初心者データサイエンティストの備忘録

調べたことは全部ここに書いて自分の辞書を作る

【読書記録】インプット大全

 コンサルの仕事においては、お客様のサービスに対するドメイン情報が重要である。私の場合は、このドメイン情報をなかなかキャッチアップできないことが、課題である。その課題に対する答えを求めて、インプット大全を読んだ。本記事は、インプット大全の書評だ。

 インプット大全を読んで、情報のキャッチアップが次の3ステップで行われていると理解した。

  1. 情報を認識する
  2. 情報を理解・記憶する
  3. 情報を発信する

 私の場合、「1. 情報を認識する」と「3. 情報を発信する」の2ステップに課題があると考えている。1をより詳細に言語化すると、私のアンテナが低く、必要な情報にアクセスできていないことが課題である。また、3については、一度覚えたはずの情報が業務で活かすべきときに活かせないことが課題である。

 インプット大全から得た知識を基に、各ステップにおける課題解決策や重要な考え方をまとめた。(図1)

図1:情報のキャッチアップの3ステップ

 図1から私は今後のTODOとして、下記3点に取り組む。

  1. マンダラチャートを書く
  2. Googleアラートを設定する
  3. 毎日何かを観察し、それを会社の分報に記載する(分報は社内ツイッターみたいなもの。私が働いている会社では割と何を投稿してもOK)

3月末に上記TODOを再度振り返り、インプットが進んでいるか確認したい。

【釣行記】カマスは釣れた

「【釣行記】カサゴは釣れない」に引き続き今回は「カマスが釣れた」に関する釣行記を書く。 aisinkakura-datascientist.hatenablog.com

 実は、前の記事でカサゴを釣りに行った日とカマスが釣れた日は同じである。この日は根魚狙いで釣行したため、カマス用の仕掛けは何も用意していなかった。しかし、その場しのぎの仕掛けでなんとか釣ることができた。

このとき使った釣り具がこちら。

たまたま根魚用の仕掛けに紛れ込んでいたのだが、カマスがベイトを追いかけているのを見て、なんとかこれで釣れないか勝負してみたのだ。 たが、肝心のワームがない。そこで、ジョイントノッカーにつけていたイカの塩辛を細く切ってワームのようにして釣ってみた。そんな簡単な仕掛けで釣れたのだ。

この釣りをして得られた知見が3点ある。
 まず一つは、ベイトを追いかけているカマスはサビキでは釣れないことだ。私たちが釣りをしているすぐそばで、地元民と思われる老夫婦がサビキでカマスを狙っていたのだが、全く釣れていなかった。サビキは魚がいればなんでも釣れるイメージだが、ベイトを追っているカマスには無効なようだ。
 二つ目は、カマスが泳ぐ層よりも上の層でヒットが続いたことだ。この日の海は非常に穏やかで澄んでいたため、サイトフィッシングであった。そのため、当初はカマスの泳ぐ層まで目視でルアーを沈め、そこからルアーを引いてきた。しかし、バイトはあるもののイマイチ乗らない。そこで、カマスが追っているベイトと同じ層、つまり表層を引いてみたら食いも深くしっかりヒットした。恐らくカマスは餌となる小魚が泳いでいる上の層に意識を向けていたのだろうと思われる。
 三つ目は、一定のペースでタダ巻きをしなければ釣れないということだ。ベイトが結構跳ねていたので、アクションをつけてみたが、それでは釣れなかった。きれいにタダ巻きできたときだけ食らいついた。

 今回のカマス釣りを経て、次回持っていく道具が決まった。次回は2号のナイロン糸を巻いたトラウトロッドを持っていこうと思う。トラウトロッドであれば、2gという軽いルアーを飛ばしやすく、かつロッドが軽いからタダ巻きもしやすい。また、塩辛で釣れたということはガルプも可能性があるのではないかと思う。普通のメバル用ワームと比較してみたい。  カマスはこれから秋にかけての半年間シーズンなので、もっともっと研究していきたい。

【釣行記】カサゴが釣れない

 先日、大学のときの友人と真鶴に釣りに行った。狙いは根魚である。しかし、本命のカサゴがあまり釣れなかったので、悔しい思いをした。そこで、今回の釣行で得られた仮説をここに記し、次回の釣行に活かそうと思う。

カサゴが釣れる条件は何か?」ということを考えていたときに、過去の釣行の実績から導き出された仮説がある。

仮説:カサゴは人がいないところでしか釣れない

 実際にデータを取得しているわけではないのだが、カサゴが良く釣れるポイントは釣りをしにくい場所であったり、メジャーな磯から歩く必要があったりと不便な場所が多い気がする。このことを念頭にカサゴの生態を調べていると以下のようなサイトに出会った。

www.scc.u-tokai.ac.jp

このサイトには以下のような記述がある。

カサゴ成魚の移動範囲は大体1km以内であると報告されている。定着性の強いカサゴにとって生活範囲の狭さが原因となり、他地域の集団との隔離が生じると考えられる。

 これを見るに、人が多く出入りする釣り場では、カサゴは釣り切られている可能性がある。このことから、仮説1はある程度支持されるのではないかと思う。 逆に言えば、同じ根魚でもアカハタのような季節ごとに移動する魚は、人が出入りしている釣り場でも常に供給があり、釣り切られていない可能性が高い。

 この仮説を基に考えると、次回の釣行で取り組むべきアクションは次の4点である。優先順位が高い順に並べてある。

  1. 駐車場からたくさん歩かなければならないような不便な場所で釣る。
  2. 遠投する。
  3. 釣りがしにくい場所を選んで釣りをする。(足場が高く釣りをしにくい場所など)
  4. 有名でない磯をGoogleマップから探す。

実行可能性としては、1が一番簡単である。頑張って歩けば済む話である。 2番目についてもそれほど難しくない。これを実行するためには、PEラインを細くし、かつ重りを重くすればよい。今回はジョイントノッカーの18gで戦っていたが、ガン玉をつけて少し重くしてみよう。 3番目については、場所によりけりではあるが、最悪命を落とすことになるので、実行可能性はあまり高くない。高いが安定した足場の磯があったらやってみるくらいな感覚。 4番目については、東京在住の私にとってはかなり難しい気がする。東京は人口が多い分釣り人も多く、開拓され切っていると思う。少なくとも人がアプローチできるような磯は全部ネットに載っているのではないだろうか?

ということで、次回のアクションまで決めることができた。次回の釣行が楽しみである。

追記
今回写真を撮り忘れました。1枚も写真がない釣行記はなんと貧弱なことか...! 仕方ないからジョイントノッカーのアフィリエイトを貼っておくので、買ってください(笑)

pandas.DataFrameの特定条件の行から値だけ取得する方法

 pandas.DataFrameで特定条件の行から単独の値だけ取得する際にハマったことのメモ。 まずは問題設定。以下のようなスクリプトでDataFrameから一つだけ値を取り出して色々操作したい。

import pandas as pd

df = pd.DataFrame(
    {
        'key': ['K0', 'K1', 'K2', 'K3', 'K4', 'K5'],
        'A': [1, 2, 3, 4, 5, 6]
    }
)

# "key"が"K0"の行の'A'の値を取り出す
a = df[df["key"] == "K0"]["A"]

このとき、print(a)をすると図1のように表示される。

f:id:aisinkakura_datascientist:20220317003409j:plain:w300
図1:print(a)の結果

つまり、aはnumpy.int64などの値ではなく、型情報なども含まれているSeries型であることがわかる。なお、このことはtype(a)することでもわかる。
 このように特定条件の行から値だけ取り出したつもりが、Series型であることによって引き起こされる問題はいくつかある。 例えば、下記のようなスクリプトは動かない。

df2 = pd.DataFrame(
    {
        'key2': ['K0', 'K1', 'K2', 'K3', 'K4', 'K5'],
        'B': [1, 2, 3, 4, 5, 6]
    }
)

# df2から"B"がaである行を取り出す
df2.query("B == {a}".format(a=a))

'''
下記のようなValueErrorを吐く
ValueError: multi-line expressions are only valid in the context of data, use DataFrame.eval
'''

 上記の問題をクリアする方法として、Series型から値だけを取り出す方法がある。具体的にはilocを使う。

import pandas as pd

df = pd.DataFrame(
    {
        'key': ['K0', 'K1', 'K2', 'K3', 'K4', 'K5'],
        'A': [1, 2, 3, 4, 5, 6]
    }
)

# # "key"が"K0"の行の'A'の値を取り出す
# a = df[df["key"] == "K0"]["A"] ← ダメだったスクリプト
b = df[df["key"] == "K0"]["A"].iloc[-1]  #←使えるスクリプト

これで下記を実行するとちゃんと動く。

# df2から"B"がbである行を取り出す
df2.query("B == {b}".format(b=b))

ということで、pandas.DataFrameの特定条件の行から単独の値を取り出すときは、iloc[-1]をしましょう!

E資格合格体験談

 2022年第1回のE資格に合格しましたので、合格のポイントを書いておきます。この記事はE資格の認定講座に申し込む前に読んだほうが良いです。

本記事の要約

合格のポイントは下記2点です。

  1. 友達と受けるべし
  2. 認定用講座と黒本を併用すべし

この2つのポイントについて説明していきます。

友達と受けるべし

 E資格の特徴として、受験資格を得るために、認定講座を受ける必要があります。私はとにかく安かったStudy-AI株式会社のラビット・チャレンジを受講しました。 ai999.careers

 恐らく他の認定講座も同じだと思うのですが、ラビット・チャレンジにはテストとレポート提出の課題があります。これらの課題を期日までにクリアしないと認定がもらえません。 ラビット・チャレンジのテストの難しいところは合格点が高め(90%)に設定されていることと、間違った問題を教えてくれないことです。 講座内のテストは最大10回までしか受験できません。10回落ちてしまった人は課金すればさらに10回受けることができるのですが、とても時間がかかります。 なので、友達と一緒にテストを受けてお互いに確信のある問題を持ち寄り、協力して合格を目指すことが大事です。

認定用講座と黒本を併用すべし

 ラビット・チャレンジに申し込むと講師による映像授業を受けることができます。これによって、試験範囲の技術についてなんとなく知ることができます。しかし、授業をただ眺めているだけでは、E資格合格の力はつきません。本番の試験では、実装に関する問題が多数出るためです。また、講座の中で出てくる数式にまあまあな量の誤字があるので、勉強しにくいです。 なので、通称黒本も併用しましょう。

黒本は多くの問題が載っており、難易度も適切です。そのため、「黒本で問題を解く→わからないことは認定講座の授業を振り返る or ググって解決」のサイクルを繰り返すと良いです。 逆に言えば、黒本と認定講座以外は勉強しなくて良いと思います。  なお、黒本も誤字がたくさんあります。下記サイトの「お詫びと訂正」に正誤表あるので、これを見ながら勉強したほうが良いです。 book.impress.co.jp

落穂ひろい

 上で書ききれなかった事柄を書いていきます。

結果発表の日程

 E資格の公式サイトには結果発表の日程が載っていません。しかし、Twitterとかを調べてみると、おおむね受験から3週間程度で発表されるようです。ちなみに私の場合は、2022年2月18日に受験し、2022年3月10日に結果がメールで通知されました。

認定の締め切り

 E資格の受験申し込みは、受験前日までできます。しかし、認定講座の修了締め切り日は1か月以上前です。この修了締め切り日に間に合わないと、E資格の受験資格が得られないため注意してください。私はのんびり講座を進めていたら、後半時間がなくなり、徹夜で仕上げざるを得ませんでした。

レポート

 私が受講した際は、認定講座のレポートの合格レベルがよくわからなかったので、偉大な先人が書いたレポートを参照していました。私はQiitaでレポートを書いて提出しましたが、ラビット・チャレンジの場合は、下記のレベルで書けていれば認定をもらうことができました。

qiita.com

qiita.com

qiita.com

qiita.com

qiita.com

qiita.com

みなさんの合格を願っています!

Excelで縦持ちデータから横持ちデータに変換する方法

 Excelで縦持ちデータを、横持ちデータに変換する方法についてのメモ。ピボットを使うと簡単だが、ピボットが使えない状態で関数を使って実現する方法を記載する。

 まず、問題設定をする。図1の縦持ちデータを図2の横持ちデータに変換する。つまり、商品名と日付が列になっている状態から、商品名と日付のクロスで販売個数が分かるようにしたい。

f:id:aisinkakura_datascientist:20220315013315j:plain:w300
図1:縦持ちデータ

f:id:aisinkakura_datascientist:20220315233021j:plain:w300
図2:横持ちデータ

 このとき、まず初手としてはVLOOKUPを使う。VLOOKUPの使い方については、このサイトが分かりやすかった。 dekiru.net

 ただし、今回の場合は、商品名と日付の2つの条件をVLOOKUPの検索値(1個目の引数)にしなければいけない。 そこで、まず最初に商品名と日付を結合させた列を作成する(図3)。

f:id:aisinkakura_datascientist:20220315014705j:plain:w300
図3:検索値を1つにまとめる

 この列を作ることで、VLOOKUP関数の検索値に入れる2つの条件を1つにまとめることができる。 このような前準備を経て、図2:横持ちデータのB2セルにVLOOKUP関数を入れる。 B2セルは、A2セルとB1セルの2条件をがキーとなっている。そこで、B2セルには絶対参照に注意しながら次の関数を入れる。セルの番号は図2、図3を見ていただきたい。

=VLOOKUP($A2&B$1, $A$21:$D$28, 4, False)

上記関数をB2セルに入れて、B2:D4セルまでコピペしてできた表が図4である。

f:id:aisinkakura_datascientist:20220315233914j:plain:w300
図4:VLOOKUPを入れた表

 図4を見るとVLOOKUPを入れただけで横持ちデータはほぼほぼ完成しているが、C2セルでエラーを吐いてしまっている。 エラーを吐いた原因は、元の縦持ちデータに2022/3/16の「よなよなエール」が存在しないからである。今回は販売ログ(購入があったらその履歴を記録したようなデータ)を想定しているので、このような縦持ちデータに存在しない行がある場合、その日付のその商品の販売個数0とする。 これをExcel上で反映させるためにIFERROR関数を使う。IFERROR関数の説明はこのサイトが分かりやすかった。 office-hack.com

先ほどのB2セルの関数を次のように置き換える。

=IFERROR(VLOOKUP($A2&B$1, $A$21:$D$28, 4, False), 0)

これを先ほどと同様に、B2:D4セルまでコピペしてできた表が図5である。

f:id:aisinkakura_datascientist:20220315235008j:plain:w300
図5:IFERRORも入れた表

これで欲しかった表ができた。

pandas.DataFrame.joinの右側DataFrameのキーは、indexしか指定できない

 pandas.DataFrameのjoin関数で少しはまったのでメモ。 2個のpandas.DataFrameを結合しようとして下記のコードを書いた。このとき、dfとotherに共通のカラムkeyで結合しようとしたのだが、エラーを吐いてしまった。

gisted6a13740d3bf16c8608f60e28a2a316

原因を調べるためネットでググると下記とのこと。

呼び出し元のpandas.DataFrameのキーとする列を引数onで指定できる。引数に指定する側のpandas.DataFrameは常にインデックスがキーとなる。

ちなみに参考にしたサイトはこちら。 note.nkmk.me

 したがって、joinする2つのDataFrameに共通のカラムがあっても結合することができない。

 対処法は簡単。右側のDataFrameの結合したいカラムをindexにするだけ。つまり、下記で結合できるようになる。

df.join(other.set_index("key"), on="key")