俺人〜OREGIN〜俺、バカだから人工知能に代わりに頑張ってもらうまでのお話

俺って、おバカさんなので、とっても優秀な人工知能を作って代わりに頑張ってもらうことにしました。世界の端っこでおバカな俺が夢の達成に向けてチマチマ頑張る、そんな小さなお話です。現在はG検定、E資格に合格し、KaggleやProbSpaceのコンペに参画しながら、Pythonや機械学習、統計学、Dockerなどの勉強中です。学習したことをブログにアウトプットすることで、自分の身に着けていきたいと思います。まだまだ道半ばですが、お時間がありましたら見て行ってください。

Kaggle鳥コンペの上位者に学ぶ(鳥コンペ反省会資料を読む)

今回は、KaggleのPublicスコアで初めてコンペ終了まで銅メダル圏内に残ることができました。しかしながら、Privateスコアでは一気に下がり、268位と大きくShakeDownすることになりました。

その原因の一つとして、現在の私のアプローチは、自身の知りうるデータの前処理、及びモデルを組み合わせて精度が上がる組み合わせを見つけるという実験的アプローチが主体であることがあります。

やはり、上位を目指すためには、コンペ自体の情報や、データの情報から、論理的に考えて効果が出るデータの前処理や、モデル選択が重要であることを再確認しました。

そこで、今回は、「鳥コンペ反省会」にて公開されている資料を拝見し、今後に活かしたい知見を自身のメモとして残していきたいと思います。

【目次】

1.鳥コンペ反省会 6位解法(Hidehisa Araiさん資料)

6位入賞で金メダルを獲得され、鳥コンペを主催くださいましたHidehisa Arai | Kaggleさんの資料です。

speakerdeck.com

この資料を拝見しての気づき。

・コンペで解決すべき課題を十分に理解しておく必要がある。

  • TrainDataと、TestDataは、同じ条件下で取得、アノテーションされたデータであるとは限らない。→今回の場合、TrainDataとTestDataでは、入力の音声データが異なる性質をもつことはさることながら、ラベルの付け方に大きな差異があり、TrainDataの正解ラベルをそのまま使っても精度は上がらない
  • TrainDataのラベルが正しいとは限らない。→今回の場合、secondary_labelsというラベルがあったが、信頼性はない。(そもそも、ついていない場合もありました。)

・解決すべき課題を理解した上で、解決策は事象を分割して考える。

  • 今回の場合は以下で対処されていた。
  • TrainDataとTestDataの入力の性質の違い
    →DataAugumentationでありうるバリエーションを網羅
  • TrainDataとTestDataの正解ラベルの出現頻度の違い
    →ラベル比率を変えたデータで学習させたモデルのアンサンブル
  • TrainDataとTestDataのラベルの付け方の差異
    →TrainDataのラベルを正しい(と予測される)ラベルに修正する。

・Discussionを重点的に目を通す。

  • 参加者がやっていることを見るだけでなく、やっていないことを見つける上でも重要。
  • 投稿することでも自分に有利になることがある。→議論を進める主導権を握ることで、コンペの流れを支配できる。

この資料を拝見して、私自身がまだまだ素人だと感じたことは、TrainData,TestDataは、同じ条件下で作成されている前提で取り組んでしまったことです。

また、コンペに取り組むにあたって、Overviewや、Dataの出自などを十分に確認せず、Discussionも余り目を通さず、データやモデルしかみていなかったことも良くなかったと反省しました。

これまでのコンペで、そこまで考慮していなかったのですが、通常の業務で考えたら、集められた手元のデータ(TrainData)と、これから解決すべき課題で使用するデータ(TestData)が異なる条件下のデータであることは、当たり前のように発生することを再認識いたしました。

2.鳥コンペで惨敗した話とコンペの取り組み方(fkubotaさん資料)

タイトルでは「惨敗」と記載されていましたが、最後までLBに惑わされずに取り組まれ、最終的にメダル圏外から大きく躍進して銅メダルを獲得されたfkubota | Kaggleさんの資料です。

speakerdeck.com

この資料を拝見しての気づき。

・コンペに対する心構え。

  • 「Kaggleは長期戦」=「情報戦」
  • LBの上下に一喜一憂せず、愚直に知見を蓄積させる。

・アイデアの吐き出し場所を作る(issue boad)

  • 思いついたらなんでも記録する。
  • あとで読もうと思った論文や、DiscussionのURLを貼っておく。
  • 読み返して、実装する。
    → 実施前の記録をつける

・やったことを書き残す(Kaggle日記)

  • 作成したデータセットを記録する。
  • やったことのログをかく。
  • notebookの内容を関連するnotebookや、使ったデータセット、結果、感想などとともに記録しておく。
  • 読んだ論文やDiscussionについても、反映したnotebookなどとともに記録しておく。
    → 実施後の記録をつける
  • 記録した内容で思いついた内容は、issue boardに記録する。
  • 5日に1度見返す。

この資料を拝見して、「Kaggleは情報戦」という見解は、目からウロコの見解でした。(何を今更とご指摘を受けるかもしれませんが・・・。)

これまで、答えがあることを前提(ラベルデータがキレイであることを前提)で、取り組んできましたが、答えがあっているとは限らないという前提に立つと、答えに近づくためにはどうしたらよいかという情報をいかに蓄積していくかということが重要だと再認識いたしました。

(これは、コンペに限らず、実業務においても同じだと思います。)

また、「Kaggle日記」は、これからKaggleに取り組むにあたって、非常に有効なツールであると思いました。私も実践してみたいと思います。

Kaggle日記の詳細解説はこちらに公開いただいています。

Kaggle日記という戦い方 | Zenn

3.鳥コンペ反省会(Takamichi Todaさん資料)

こちらも500位以上大幅にShakeUpされ、鳥コンペでのモデルをWeb上にアプリも作成されていたTakamichi Toda | Kaggleさんの資料です。

docs.google.com

この資料を拝見しての気づき。

・計算リソースが確保できなくても工夫次第では取り組める。

  • スペクトログラム画像をjpgで保存。
    →情報が失われる、DataAugmentationが使えない等のデメリットを理解した上で進める。

・とにかくサブミットを実施して、検証する。

  • サブミット回数100回。
    →私は22回のみ・・・。
  • 検証している手法も、CutMix, Denoise(SoundEnvelope, noisereduce), Transformer, WaveNet 等、多岐に渡る。

この資料を拝見して、これまで自分が試しているパターンは、全くもって足りていないと感じました。

量の面では、3桁は超えないとだめだと思いました。質の面では、2〜3の手法の組み合わせや、パラメータのパターンを試すのではなく、手法自体のパターンをたくさん試す必要があると思いました。

手法自体のパターンをたくさん試せるように、手持ちの手法を充実させていきたいです。

4.鳥コンペ振り返り(Takamichi Todaさん資料)

終了1ヶ月前から手をつけ始めて、122位に入賞し銅メダルを獲得された

ymicky | Kaggleさんの資料です。

docs.google.com

この資料を拝見しての気づき。

・コンペのフェーズ毎の戦略を分けていた。

  • コンペ初期:Baselineカーネルからのパイプライン作成、信頼できるLocalCV作成の取り組み
  • コンペ中盤〜終盤:公開notebookの改良、モデルの検証、DataAugmentation実施、画像サイズの拡大、secondary_labelの使用

この資料を拝見して、他の皆さんの資料にも共通して、コンペ初期は、まずコンペ自体を理解し、検証に使うための武器を準備されている期間を用意されていることに気づきました。

私は、この資料の中盤〜終盤で実施するようなことから着手し始めていて、闇雲に取り組んでいました。今後は、まずは、コンペ、データを理解し、戦略的にすすめて行きたいと思います。

5.63rd_Kaggle鳥コンペソリューション紹介(bird_musicチーム資料)

63位に入賞し銀メダルを獲得されたjohann | Kaggleさん、nnnnio_pppira | Kaggleさん、Taro Masuda | Kaggleさん、yusuke_sato | Kaggleさんのチームでのご紹介いただいた資料です。

docs.google.com

この資料を拝見しての気づき。

・フィルタバンクをカスタマイズしていた。

  • メルスペクトログラムは、人間の聴覚の解像度を模倣しているので、鳥が鳴いている周波数帯にフィルタバンクを変更していた。

・モデル自体は公開notebookのスキームをそのまま利用していた。

・アンサンブルにおいては、F1値が0.6未満と推測した上で、アンサンブル元となる予測ラベルを全部予測値に入れていた。

・今回のコンペだけでなく、過去のコンペのソリューション(CVの切り方など)を確認していた。

この資料を拝見して、公開notebookのスキームをそのまま利用するにあたっても、特性を理解した上で、それ以外のところで勝負したほうが良いと割り切った上で利用するのと、私のように闇雲に、いろいろ試した結果、公開notebookのモデルを超えられない状況で利用するのでは、ここまで差が大きくでるのかと思い知りました。

評価指標の特性を理解し、効果的な手法を選択しているところがすごいと感じました。

6.おわりに

今回、鳥コンペ反省会資料を拝見して一番大きく感じたのは、自分が、コードばかりに目を向けて教科書と照らし合わせて、精度を良くする手法の組み合わせや、パラメータ設定に重きをおいていたのに比べ、上位の皆様は、コンペの主題や、解決すべき課題に目を向け、取り組んでらっしゃった点です。

これは、コンペに限らず、実業務でも自身の作っているシステムの不具合やバグばかりに目が行きがちですが、本来の目的や、解決すべき課題に目を向ける必要があることを、再認識いたしました。

本当に、この鳥コンペは学びの多いコンペでした。

今後も、いろいろなコンペに参加して、精進していきたいと思います。

f:id:kanriyou_h004:20200929151743p:plain

【これまでの道のり】

oregin-ai.hatenablog.com

2020年8月~9月の振り返り(ProbSpace不動産コンペからSIGNATE3連戦、そしてkaggle鳥コンペへ)

今年の8月~9月は、とても濃い2カ月だったので、自身の記録としてまとめていきたいと思います。

ProbSpaceで初のチームマージあり、8月末締め切りのSIGNATE関連の3つのコンペあり、そしてkaggleの鳥コンペでの苦い経験ありのジェットコースターのような2カ月でした。では、振り返っていきたいと思います。

【目次】

1.ProbSpace Re:不動産コンペ(2020年8月11日終了)

f:id:kanriyou_h004:20200926175908p:plain

このコンペは、6月から取り組んでいたのですが、arenzero(masay)さんにお声がけいただき、初めてチームで参加させていただきました。

8月11日の深夜の締め切りギリギリまで、一緒に取り組ませていただき、日付が変わった瞬間に、順位確認のために、ProbSpaceのサイトにアクセスしたときの興奮は今もわすれられません。

PublicLBでは、1位だっただけに、Shake downで3位になってしまったのは、非常に悔しい結果でしたが、初めてチームを組ませていただいて、順位としてもこれまでの最高順位となることができ、とても学びの多い有意義なコンペでした。

コンペでの取組内容の詳細は、以下もご参照ください。

oregin-ai.hatenablog.com

2.SIGNATE3連戦その1:AI Quest アセスメント(2020年8月30日終了)

8月に募集が開始された経済産業省が実施しているAI Quest 2020|SIGNATEに応募し、受講資格の選考にあたってアセスメントに取り組みました。

signate.jp

超短期間かつ他のコンペと同時並行作業だったので、5回しか提出できなかったのですが、何とか841人の参加者中90位に入り、受講資格を得ることができました!

AI Questは、10月より開始されるのですが、従来の講師が一方的にカリキュラムを教える形式ではなく、企業の実際の課題に基づくケーススタディを中心とした「実践的な学びの場」が設定されるとのこと。
参加者同士がお互いにアイデアを試し、学びあいながら、一人一人がそれぞれの体験として、AIを活用した企業の課題解決方法を身に着けられる形式なので、今から受講が楽しみです。

3.SIGNATE3連戦その2:【第1回_Beginner限定コンペ】銀行の顧客ターゲティング(2020年8月31日終了)

これまで、登録はしていたのですが、コンペには参加できていなかったSIGNATEより、Beginner限定で、閾値となる精度を超えれば昇格できるコンペが開催されるということで、短期決戦で挑みました。

こちらは、顧客属性データおよび、過去のキャンペーンでの接触情報に基づいて口座を開設したかを予測するモデルを構築するコンペでした。

評価関数「AUC(Area Under the Curve)」でした。

前処理としては、分布に偏りがある特徴量については、対数変換したり、年齢別の特徴量、月毎の特徴量を作成しました。

モデルとしては、ランダムフォレストとLightGBMの結果のアンサンブル(単純平均)するモデルを作成しました。

この出力で、閾値を超えることができて、1つ上の称号であるIntermidiateに昇格することができました。

f:id:kanriyou_h004:20200926200658p:plain

4.SIGNATE3連戦その3:CDLEハッカソン2020予測性能部門 「画像データに基づく気象予測」(2020年8月31日終了)

SIGNATE3連戦の最後は、CDLEハッカソン2020予測性能部門 「画像データに基づく気象予測」(SIGNATE開催)に参加しました。

f:id:kanriyou_h004:20200926175529p:plain

最後の最後まであきらめずに取り組み、評価指標の順位では2位の成績を残せました!今回は、PublicLB、PrivateLBともに2位で、Shakeなしでした。

最終的に確定した順位は、10月17日に開催される表彰式にて発表されるとのことで、今からたのしみです。

このコンペの解法は以下でも紹介していますので、ご参照ください。

oregin-ai.hatenablog.com

また、1位の解法を、@pometa0507さんが公開してくださいました。

lotti.info

5.kaggle鳥コンペ「Cornell Birdcall Identification」(2020年9月16日(日本時間)終了)

9月のイベントとしては、6月から継続的に取り組んできた「Cornell Birdcall Identification」コンペ(通称「鳥コンペ」)が終了しました。

鳥コンペは、鳴き声から鳥の種類を推定する音声処理タスクでした。

最初のころは、どのように対応したらよいかわからかったのですが、Tawaraさんが公開してくださったベースラインを参考にさせていただき、何とか最後までと組むことができました。

www.kaggle.com

なかなかベースラインを超えられず長らく停滞していたのですが、終了直前で、学習時に入力する音声データの周波数帯のバリエーションを複数用意して、アンサンブルをとることで、ベースラインのスコアを超えて銅メダル圏内に入ることができました。

最終日の朝は、これまでKaggleではPublicスコアでもメダル圏内で終了できたことがなかったので、ドキドキでした。

結果としては、PrivateスコアでShakeDownして268位となり、初のメダル獲得はならずでした。

しかしながら、Publicスコアでも銅圏内でフィニッシュできたのは初めてだったので、一歩前進できたと思います。

今回のコンペでは、入力のバリエーションだけでなく、モデルについても、いろいろなパターンを試して、取り組んだのですが、結果的にはベースラインのモデルを超えることができませんでした。

まだまだ、理論的なところの理解が十分ではなく、いろんなパターンを試してみるという実験的なアプローチでしか精度を上げてこれていないので、理論的なアプローチもしていきたいと思います。

まずは、本日開催された、鳥コンペ反省会で発表された皆さんの資料が公開されているので、拝見させていただきながら、理解を深めていきたいと思います。 

f:id:kanriyou_h004:20200926210519p:plain

6.おわりに

以上が、8月~9月の振り返りになります。

現在、ProbSpaceのスプラトゥーンコンペと、SIGNATEの海岸線コンペ、Kaggleの肺コンペに挑戦中です。

また、10月はAIQuestも始まるので、インプットもしっかり取り組んでいきたいと思います。

 

【これまでの道のり】

oregin-ai.hatenablog.com

【2位解法】SIGNATE開催CDLEハッカソン2020予測性能部門 「画像データに基づく気象予測」の振り返り。

SIGNATEで開催されたCDLEハッカソン2020予測性能部門 「画像データに基づく気象予測」(SIGNATE開催)に参加し、2位の成績を残せました!

今回は、PublicLB、PrivateLBともに2位で、Shakeなしでした。初めての時系列データコンペで、初めての衛星画像データを使ったコンペでしたが、過去のフォーラム等を参考にさせていただきながら、なんとかやり切ることができました!

この夏は、並行して複数のコンペに取り組んでいたのですが、最も力を注いでいたコンペで、結果を残すことができ、一生忘れられない夏になりました。

f:id:kanriyou_h004:20200904185232p:plain

今回のコンペは、G検定、E資格取得者が入会できるCDLEの会員のみが参加できるクローズドのコンペでした。

有資格者の方々が参戦する中で、結果を残すことができたのは、私にとても大きな自信に繋がりました。

では、振り返って参りたいと思います。

1.全体構成

今回は、初めての時系列データかつ衛星画像データからの予測画像データ作成ということで、何から手をつけて良いかわからず途方にくれていました。

そんな中、「昨年開催時のフォーラムページには、当時の参加者の解法が記載されています。これらの情報を参考にしてさらなる高性能なアルゴリズムを開発しましょう。」という案内があり、フォーラムページと、入賞者レポートを徹底的に読み込みました。

その中で、温度や湿度など気象情報も画像データの1chとして入力に取り込んだり、風の向きを正負に分けて別chの入力としたりして3位を獲得されていたashenOneさんの解法を参考にさせていただきながら取り組みました。

ashenOneさんの解法からの変更点は以下のとおりです。

f:id:kanriyou_h004:20200904194631p:plain

効果がでたのは、1−SSIMを損失関数にしたのと、アンサンブルを実施した際に、算術平均ではなく幾何平均をとったことでした。

全体構成図としては以下のとおりです。

【俺人解法構成図】

f:id:kanriyou_h004:20200905200614p:plain

スタッキングや、加重平均なども試みましたが、なかなか良い精度が出ず、最終的に上記の構成となりました。

2.前処理

前処理についてはashenOneさんの解法を参考にさせていただき、以下のような処理を行いました。

衛星画像のデータと、気象情報のデータをいかに組み合わせるかというところがポイントでした。

また、画像データについては、1/4,1/6,1/8の異なるサイズを入力することでデータのバリエーションを作りました。

【衛星画像データ】

種類 処理内容
欠測補完

衛星画像の欠測には2パターンありました。

1つは、特定の時間帯の衛星画像がないパターンで、もう1つは、衛星画像はあるけれども、画像の一部がないパターンでした。

これらの欠測補完は、単純に前後の画像の値の平均値で補完しました。

縮小

画像サイズを1/4、1/6、1/8に縮小して、24時間分を1日分のデータとして保存。

1/10、1/12、1/15の縮小サイズも作成したが、アンサンブルした際にMAEは向上したものの、SSIMが下がってしまったので、採用しませんでした。

 

【気象データ】

種類 処理内容
「気温」、「湿度」、「海面気温」

区分ごとの最大値・最小値を取得して、最小値0、最大値1となるように正規化。

気象データは、3時間ごとのデータしかなかったので、前後のデータから線形に変化した前提で、間の時間のデータを補完。

「東西風」、「南北風」、「鉛直風」

区分ごとの最大値・最小値を取得して、最小値0、最大値1となるように正規化。

気温とは異なり、正負があるので、正と負に分けて保存。

気象データは、3時間ごとのデータしかなかったので、前後のデータから線形に変化した前提で、間の時間のデータを補完。


3.モデル構築

 今回は、モデル構築には、ニューラルネットワークを採用して、損失関数のを工夫しました。損失関数を変更することで、以下の通りPublic Scoreが向上したため、1-SSIMを採用しました。

f:id:kanriyou_h004:20200905205631p:plain

4.アンサンブル

アンサンブルにあたっては、最適な【入力の縮小サイズの組み合わせ】の検証と、最適な【アンサンブル手法】の検証のために、算術平均、幾何平均、加重平均、スタッキングを検証しました。

それぞれ、以下の通りとなり、最終的に1/4、1/6、1/8の縮小サイズで学習済モデルの予測結果を、幾何平均を採用しました。

 【入力の縮小サイズの組み合わせ】

入力の縮小サイズの組み合わせとしては、各入力個数ごとに最もScoreが高かった組み合わせを比較して、さらにその中で最もScoreが高かった1/4、1/6、1/8の3種類の入力を採用しました。

f:id:kanriyou_h004:20200906161737p:plain

【アンサンブルの手法】

アンサンブルの手法の比較結果としては以下の通りです。

加重平均とスタッキングについては、訓練時に検証用につかったデータの予測値を使って最適な荷重の探索や、LGBMの学習を行いました。

スタッキングについては、CVの時点でよい結果が得られなかったので、サブミット数の消費を抑えるために提出しませんでした。。。

f:id:kanriyou_h004:20200906162700p:plain

5.感想

今年の夏は、なかなか外出することもできず、自宅で過ごす時間が多く、今回のハッカソンのような学習機会に恵まれたことは、非常に有意義でした。

特に、いままで経験してこなかった課題に取り組めたことや、新たな知識を得られたことで次回に向けた意欲・モチベーションが向上できたことは、今後の私の人生に大きな一歩となりました。

まだまだ、理論が理解できていない部分が多く、多くの課題が残りましたので、引き続き、日々の勉強を続けてまいりたいと思います。

6.謝辞

最後となってしまいましたが、ハッカソンを運営してくださいました、JDLA、SIGNATE の運営の皆様、データをご提供くださいました株式会社ウェザーニューズの皆様、一緒にハッカソンに取り組んでいらっしゃった皆様に心より感謝申し上げます。

また、ashenOneさんの解法のおかげで、難解な課題について、取り組むべき方向性が示され、2位の予測性能を出すことができました。この場を借りて御礼申し上げます。

私も、これから様々な課題に取り組む皆様に、解決の一助となるような情報を発信できるよう、精進していきたいと思います。

 

【過去記事】

G検定、E資格の取得から、これまでに取り組んできた道のりは以下にまとめております。何かのご参考にしていただければ幸いです。

oregin-ai.hatenablog.com

機械学習初心者がデータ分析コンペサイトProbSpaceで総合ランク1位に到達するまでの道のり

機械学習について全くの専門外で初心者だった私がコンペサイトProbspaceのRe:不動産取引価格予測コンペで3位入賞、YouTube動画視聴回数予測コンペで9位入賞するなど、累計で金2銀1銅1を獲得することができ、総合ランクで1位に到達することができました。

f:id:kanriyou_h004:20200812171317p:plain

これまでたどってきた道のりを振り返って、良かった点、悪かった点を見直して、今後の進め方を考えていきたいと思います。

悪戦苦闘、一進一退しながら勧めてきた内容を、思いつくまま記載しているので、お見苦しい箇所もありますが、これから機械学習を始める皆さんや、始めたばかりの皆さんの何らかのキッカケになれれば光栄です。

では、振り返ってまいりたいと思います。

【目次】

1.G検定との出会い(2019年2月〜3月)

私の人生を変えたといっても過言ではない出来事が、G検定という資格との出会いでした。

この資格は、まだ新しい資格で、実際に受験された方々の中でも様々な評価があるところなのですが、私にとってこの資格を取得するまでの過程があって、今の私があるのは間違いないです。

 

この資格を受験する前は、ただぼんやりと人工知能を利用して何かがやりたい、社会に貢献できることがしたいと考えていただけでした。

このままでは、何も前に進まないと思い、とりあえず「人工知能」「勉強」「資格」「AI」などなど、いろいろキーワードを入れて片っ端から検索してみました。

その結果、以下のサイトにたどり着き、どうやら「G検定」(JDLA Deep Learning for GENERAL)という資格があることがわかりました。

資格試験について - 一般社団法人日本ディープラーニング協会【公式】

 

この資格に取り組むことで、人工知能とはなにか、何が解決できて何が課題なのか、どのような経緯をたどってきているのか、どこに向かっているのかなど、いろいろな背景や現在の状況を知ることができました。

 

また、勉強すううちに「機械学習」というものがあることを知り、「もっと深く勉強したい!」と強く意識付けされるキッカケとなったのが、この試験でした。

 

そして、無事、G検定に合格できたことも、まだまだ自分もやれるんだという大きな自信につながりました。

実際に受験してみた感想や、勉強内容については、過去の記事にまとめていますので、興味がございましたら、そちらもご参照ください。

g-kentei.hatenablog.com

2.Pythonの勉強を始める(2019年4月)

G検定に合格して、すぐにその上位資格のE資格を受験したいと思ったのですが、受験するためには、JDLA認定プログラムを修了している必要があり、実習としてPythonというプログラミング言語を使って、実際に機械学習モデルを自ら構築できる必要がありました。

Python」の読み方すら知らなかった私は、以下の2冊の本を急いで購入し、1から勉強をはじめました。

入門Python 3 [ ビル・ルバノビック ]

ゼロから作るDeep Learning Pythonで学ぶディープラーニングの理論と実装 [ 斎藤 康毅 ]

f:id:kanriyou_h004:20190831215305j:plain

 

特に、ゼロから作るDeep Learning Pythonで学ぶディープラーニングの理論と実装 [ 斎藤 康毅 ]は、名著で、現在も、続編の自然言語処理編、フレームワーク編とともに愛読しています。

ゼロから作るDeep Learning 2 自然言語処理編 [ 斎藤 康毅 ]

ゼロから作るDeep Learning 3 フレームワーク編 [ 斎藤康毅 ]

f:id:kanriyou_h004:20190713165650j:plainf:id:kanriyou_h004:20200723205241j:image

 

Pythonについては、最初、Anacondaのインストールに四苦八苦して、環境構築に悪戦苦闘していましたが、講座が始まる頃には、以下のようなことができるようになっていました。

これまで、本格的にプログラミングをやったことがなかったのですが、プログラミングは、プログラムしたとおりに必ず動いてくれて、自分の思い通りに動く喜びをしることができました。(もちろん、プログラムしたとおりに忠実に動くので、少しのミスがあると、全く動かなかったりすることもあるのですが・・・。)

3.kaggleのデータセットを使って機械学習に挑戦する(2019年4月〜5月)

知り合いからKaggleというものの存在を教えてもらい、データ分析のコンペティションなどが行われていることを知りました。

実際にコンペに参加するのは、まだまだ厳しかったのですが、kaggleのデータセットを使って、自己流も混ざっていますが、機械学習について、本格的に勉強をはじめました。

なかなか精度が向上しなかったり、精度が向上したかと思えばリークしてしまったり、一進一退を繰り返していました。

しかしながら、今思うと、このときに、データを分析したり、前処理を行ったり、モデルのハイパーパラメータを調整したり、結果を評価したりすることで、全体の流れを実際に手を動かして取り組んでいたことが、非常に役に立っていると思います。

具体的には、以下のようなことに取り組みました。

4.E資格を受験する(2019年5月〜8月)

 Python機械学習を事前に学習した状態で、E資格の認定講座を受講いたしました。

まっさらな気持ちで受講されている方々もいらっしゃいましたが、私は受講してすぐ理解できるタイプではないので、事前に十分な予習をしてから受講できたのは、非常に良かったと思いました。

 

認定講座では、理論と平行して実装も行っていくので、知識だけでなく、技術を感覚的に身につけられていると感じました。

また、今、いろいろなコンペに参加する際に何も考えずライブラリを使っている各種学習モデルについても、中身を理解して、1から手組で作る経験が得られたことは、パラメータの調整等の意味がわかって調整できるので、非常に有意義でした。

 

その効果もあって、E資格(JDLA Deep Learning for ENGINEER 2019 #2)に合格することができました。

詳細は、以下の過去記事もご参照ください。

oregin-ai.hatenablog.com

5.Probspaceで給与推定コンペで47位入賞(銅賞)(2019年11月〜12月)

E資格取得後、1〜2ヶ月ほど、復習をしながら、準備を整えて、満を持してProbspaceというデータ分析プラットフォームで開催されていた給与推定コンペに参戦しました。

結果としては、310チーム中 47位 ということで、上位15%に入り、銅賞をいただくことができました。

 

テーブルコンペだったので、取り組みやすく、チュートリアルもわかりやすかったので、初めてのコンペながら楽しんで参戦することができました。

実際に他の皆さんと切磋琢磨しながら取り組むのは、自分一人で学習を進めるのに比べて、何倍も進歩が違うと感じました。

一方で、これまでの積み上げがあったからこそ、なんとかついていけたのだとも思いました。

 

今のところ、自分自信の理解を深める積み上げの期間と、積み上げた結果を確認するアウトプットの期間を織り交ぜていくのが自分の中ではベストです。

コンペに参加しながら、いろいろな最新情報のインプットもできる人には、本当に感服いたします。

 

給与推定コンペの振り返りは、以下もご参照ください。

oregin-ai.hatenablog.com

6.Probspaceで浮世絵作者予測コンペで10位入賞(銀賞)(2019年10月〜2020年1月)

先程の、給与推定コンペと並行して、浮世絵の作者を予測するコンペにも参戦いたしました。

こちらは、約4ヶ月の長丁場でしたが、E資格時に画像分類はさんざん実施してきていたので、知識をフル動員して頑張りました。

結果は、232チーム中 10位に入賞することができ、銀賞をいただきました。

ここまで来ると、だんだん欲がでてきて、どんどんコンペに参加したくなってきていました。

しかしながら、今回のコンペでは、E資格で学習した内容でそこそこの成績までは到達できたものの、10位まで到達するまでには、いろんなパターンを組み合わせて、いろいろ試した結果、スコアが向上したという行きあたりばったりの改善策もありました。

このため、なぜそうなるのかということも理解したい気持がわいてきました。

コンペでの取組内容は、以下をご参照ください。

oregin-ai.hatenablog.com

7.東京大学GCI Winter 2019を受講(2019年12月〜2020年3月)

浮世絵作者予測コンペを取り組む中で、もっと理解を深めたい欲求がでてきたときに、ちょうど東京大学のGCI寄附講座という無料講座を見つけ、早速申し込み、運良く参加することができました。 gci.t.u-tokyo.ac.jp

 こちらは、オンラインの講座だったのですが、単なる講義だけでなく、毎回宿題もあり、コンペもあり、コンペも開催される、かなりハードな4ヶ月間を過ごすことになりました。

しかし、その甲斐あって、確率統計などの基礎知識から、モデルの検証方法や、チューニング方法にいたるまで、基礎理論から実装、さらにはビジネスへの応用まで含めた、スキルアップをすることができました。

 

この内容を無料で受けられるのは、非常にありがたいと思いました。機会があれば、絶対受講をおすすめいたします。

詳細は以下の記事も、ご参照ください。

8.ProbspaceでYouTube動画視聴回数予測コンペで9位入賞(2020年4月〜6月)

そして、GCIでの成果を発揮すべく、YouTube動画視聴回数予測コンペに参戦しました。

このコンペは、一見、テーブルコンペのように見えましたが、コメント欄を自然言語処理したり、サムネイル画像を画像処理したりするなど、工夫次第では、どんどん領域が広がる複合的なコンペでした。

今までのなかで一番難しく、一番楽しいコンペでした。

結果としては、446チーム中 9位に入賞することができ、金賞をいただきました!

f:id:kanriyou_h004:20200724001856p:plain

このコンペで一番苦労したのは、環境構築と維持でした。

いろいろな学習モデルを使う際に、テーブルデータ用の分析するための環境、自然言語処理をするための環境、画像処理をするための環境など、いろいろな環境をつくらなくてはならず、一個の環境をつくるために、前の分析を行うための環境が崩れてしまったりして、とても苦労しました。

また、たくさんのコードを作って、いろんなバージョンができたので、どの組み合わせだったか等の管理にも非常に苦労しました。

今回のコンペでは、単に機械学習という観点だけでなく、「システム開発」としての、効率的な運用も考えて行く必要があるということに気づけたとても有意義なコンペでした。

9.ProbspaceでRe:不動産取引価格予測コンペで3位入賞(金賞)(2020年6月〜2020年8月)

Youtubeコンペ終了にあわせて、一時度開催された不動産取引価格予測コンペの評価指標を変更したコンペという一風変わった「Re:不動産取引価格予測コンペ」が開始され、9位入賞の勢いで、続けての参加をいたしました。

結果は、252チーム中、なんと3位入賞と大躍進をとげました!

f:id:kanriyou_h004:20200811104318p:plain

今回のコンペは、評価指標が変わっただけのコンペだったのですが、前回優勝のコードでも、上位のスコアには到達できないということで、評価指標によってこんなに結果が変わるものかと、驚きました。

また、今回はarenzero(masay)さんにお声がけいただき、初めてチームで参加させていただきました。

PublicLBでは、1位だっただけに、Shake downで3位になってしまったのは、非常に悔しい結果でしたが、初めてチームを組ませていただいて、順位としてもこれまでの最高順位となることができ、とても学びの多い有意義なコンペでした。

 自身の成長面でも、Youtubeコンペでの反省点を活かし、いろんなモデルをたくさん試すことよりも、徹底的にデータと向き合って、前処理に注力したことが功を奏したと感じました。

また、環境構築面では、後述の講座受講で学んだDockerを利用して、環境を構築したので、とても簡単に今回のコンペ専用の環境を作ることができ、今後に活かせることができました。

 

コンペでの取組内容の詳細は、以下の記事もご参照ください。

oregin-ai.hatenablog.com

10.現在取り組み中の内容、そして今後にむけて

現在は、ProbspaceのRe:不動産コンペや、Kaggleのコンペに参戦しつつ、YouTubeコンペの反省を込めて、環境構築や管理に必要なDockerについて、 かめ@usdatascientistさんの以下の講座を受講して勉強中です。 

 

これまで学習してきた内容は、まだ受講途中ですが、以下の記事にまとめました。

oregin-ai.hatenablog.com

また、このDocker講座が終わったら、自分のコードについて、適切にバージョン管理等ができるように、GitHubについても勉強していきたいと思います。

 

以上が、これまでの私の取り組んできた道のりになります。

G検定に出会ってから約1年半、いろいろ紆余曲折がありましたが、なんとかここまでやってくることができました。

まだまだ道半ばではございますが、世間様にお役に立てるアウトプットを出していけるよう、今後も精進してまいりますので、引き続きよろしくお願いいたします。

 

f:id:kanriyou_h004:20200812171317p:plain

ProbSpaceのRe:不動産取引価格予測コンペの振り返り(3位入賞!)

データ分析プラットフォームProbspaceRe:不動産取引価格予測コンペに参加し、3位に入賞しました!

PublicLBでは、1位だっただけに、非常に悔しい結果でしたが、初めてチームを組ませていただいて、順位としてもこれまでの最高順位となることができ、とても学びの多い有意義なコンペでした。

f:id:kanriyou_h004:20200811104318p:plain

今回のコンペは、一時度開催された不動産取引価格予測コンペの評価指標を変更したコンペという一風変わったコンペでした。

前回は、思ったように成果が残せなかったので、爪痕は残せたかなと思っています。

では、振り返ってまいりたいと思います。 

1.全体構成(俺人パート)

今回は、arenzero(masay)さんとチームで参加させていただいたので、私が担当した部分を振り返ります。

全体像としては、以下のとおり2段のスタッキングのモデルでの予測が最高精度になりました。

最終的には、この出力を、arenzeroさんの最高精度の出力と平均して提出していただいたもので、3位に入賞することができました。

一番力を入れたのが、前処理で、trainデータと、政府公示資料の地名や、駅名の表現のゆらぎなどを、うまく繋げられるように、カテゴリ変数化に注力しました。

f:id:kanriyou_h004:20200811110629p:plain

2.前処理

前処理については、前回のコンペ時に使った前処理をベース(ベースの構成)にして、更に精査しました。

具体的には、以下のようにTrainデータと、政府公示資料を見比べて、どのようにつなぎ合わせるかを検討しました。(特にカテゴリ変数)

データ間で、用語が異なっていて苦労しましたが、実際の現場では、よくある話なので、良い経験になりました。

【カテゴリ変数】

trainのカラム 変換内容
「種類」
「用途」
組み合わせることで、政府公示資料の「利用の現状」と繋げられるようにしました。(政府公示資料の「用途」はTrainデータの「用途」とは別物でした)
「地域」 政府公示資料の「用途」に紐付けられるように変換しました。
「市区町村コード」:政府公示資料の「所在地コード」に紐づけました。
「市区町村名」
「最寄り駅:名称」
政府公示資料の「市区町村名」、「駅名」と紐付けられるようにコード化しました。このとき、名前にゆらぎがあったので、駅名等が異なっても同じ駅であれば、同じコードになるように工夫しました。
「間取り」 前回のコンペでの変換ツールを流用して、各部屋種別のOne-hotベクトルと、部屋数に変換しました。
「土地の形状」 政府公示資料の「形状区分」と紐付けられるように「ほぼ」などの曖昧な表現をなくして、コード化しました。
「建物の構造」 政府公示資料の「建物構造」に紐付けられるようにコード変換を実施しました。
「前面道路:種類」
「前面道路:方位」
それぞれ、政府公示資料の「前面道路の方位区分」、「前面道路区分」と紐付けられるようにコード変換しました。
「都市計画」 政府公示資料の「用途区分」と紐付けられるようにコード変換しました。
残りのカテゴリ変数 政府公示資料と紐付けずに、Trainデータ内でTarget encodingを実施しました。

【数値変数】

以下の処理と、文字列を数値に変換。

trainのカラム 変換内容
「建築年」 全部西暦に直して、nanは−1に。
「取引時点」 年を数値にするとともに、四半期分を「0」「0.25」「0.5」「0.75」に変換。
「最寄り駅:距離(分)」 文字列で時間の表記になっている箇所を全て分に変換(例:「1H30?2H」→「105」)。また、政府公示資料では、時間ではなく「駅距離」だったので、徒歩の速度80m/分で割って、「距離(分)」を計算。
「間口」 "以上"、"未満"などの文字列の処理を実施。あわせて、政府公示資料では、「間口」自体の記載はなく、間口と奥行きの比率で記載されていたため、「面積」と「間口(比率)」、「奥行き(比率)」から、算出。
「面積」
「延べ床面積」
「建ぺい率」
容積率
"以上"、"未満"などの文字列の処理を実施。

【追加した変数】

  •  政府公示資料と紐づけを実施した変数について、政府公示資料での各変数毎にグルーピングして平均した価格を追加。
  • 「最寄り駅:名称」、「市区町村コード」、「市区町村名」毎にグルーピングして平均した価格と「面積」を掛けた値を追加。
  • 同じく「最寄り駅:名称」、「市区町村コード」、「市区町村名」毎にグルーピングして平均した価格と(「面積」+「延べ床面積」)を掛けた値を追加。
  • 「取引時点」から「建築年」を引いた「築年数」を追加。

3.モデル構築

 今回は、モデル構築には、それほど時間がかけられず、1段目は、LightGBMとXGboostのハイパーパラメータをOptunaで探索して、CVがよくなるモデルを採用しました。

KFoldでFold数を11のモデルとしています。

また、チーム参加後、気合をいれてスタッキングにも挑戦しました、しかも、2段目は、NNを採用しました。

計算に時間がかかるので、あまりパターンが試せませんでしたが、なんとか7層のNNで最高精度がだせるモデルを作ることができました。

チームに参加していなければ、このモデルを試すこともなかったと思うので、チームを組んでくださって本当に感謝です。

4.チームでの参加について

今回、初めてチームで参加させていただいたのですが、最後の最後まで、とても有意義で、エキサイティングな経験をさせていただきました。

特に、締切間際の数分で、提出回数が復活して、提出した最後のSubmissionが、過去最高LBスコアを叩き出して、PublicLB1位をキープできたときは、しびれました。

残念ながら、PrivateLBでは3位となってしまいましたが、いろいろな意見が交換できたり、自分一人なら実施していなかったであろう取り組みができたり、本当によい経験でした。

5.謝辞

コンペを運営してくださいました、ProbSpaceの運営の皆様、コンペに参加してくださった皆様に心より感謝申し上げます。

チーム参加のお声がけをくださいました、arenzero(masay)さんのおかげで、単独で参加するコンペよりも何倍も素敵なコンペにすることができました。この場を借りて、厚く御礼を申し上げます。

またの機会がございましたら、もっと貢献できるよう更に腕を磨いていきたいと思います。

 

【過去記事】

これまでの道のりは以下の記事をご参照ください。

oregin-ai.hatenablog.com

Docker学習記録のまとめ(米国AI開発者がゼロから教えるDocker講座)

アメリカでデータサイエンティストを実施されているかめ@usdatascientistさんの「米国AI開発者がゼロから教えるDocker講座」をUdemyで受講した学習記録のまとめです。

私は、Dockerという言葉自体を最近知ったぐらいの知識レベルだったのですが、この講座は、ひとつひとつ丁寧に解説いただけますし、ハンズオン形式で講座が進むので、まさに「手で覚える」ことができました。

では、振り返っていきたいと思います。

事前準備編(講座受講前の準備・申込み)

事前の準備として、Dockerをインストール手順と、受講を決心した理由などの記事です。

基礎編

基礎編として、Dockerについて、順に手を動かしながら学んでいきました。

講座だけでなく、kaggleやProbspace、SIGNAGEなど、複数のコンペティションに並行して参加しながら取り組んでいたので、コンペごとに環境を作成して、覚えたことをすぐに実践につなげることができました。

応用編(受講中:完了次第掲載予定)

基礎編で学んだことを使って、実際の利用シーンを想定した環境を構築していきます。

【ただいま受講中、受講次第掲載いたします。】

 

 

f:id:kanriyou_h004:20200808084943p:plain

Dockerのホストとコンテナの関係を理解する(米国AI開発者がゼロから教えるDocker講座)

これまでは、コンテナを起動する際にホストからファイルをコピーしたり、設定等をおこなったりしていましたが、コンテナを起動してからもファイルのやり取りをしたり、コンテナが利用するリソースを制御したりする方法を理解しました。

今回もかめ@usdatascientistさんの「米国AI開発者がゼロから教えるDocker講座」をUdemyで受講しながら進めています。

とても分かりやすく解説いただけますし、ハンズオン形式で講座が進むので、まさに「手で覚える」ことができるので、おすすめです!

www.udemy.com

では、振り返っていきたいと思います。

Dockerのホストとコンテナの関係を理解する

1.ホストとコンテナ間でファイルを共有する(-v オプション)

これまで、ホストからコンテナにファイルを渡すときは、Docker image作成時にファイルをコピーしていました、しかしながら、コンテナ起動後、ファイルをやりとりしたくなることもあります。また、コンテナに大きなファイルをおきたくないこともあります。

このようなときには、「-v」オプションを使うことで、ホストのファイルシステムをコンテナにマウントすることができます。

では、早速やってみます。

今回は、ホスト側に「mounted_folder」を作成しマウントされたことの確認用に、この中に「file_at_host」というファイルを作っておきます。

そして、このディレクトリを、コンテナ側に「new_dir」を作成した「new_dir」というディレクトリにマウントさせます。

まずは、以下のDockerfileを作成します。

FROM ubuntu:latest
RUN mkdir new_dir

作成したDockerfileが保存されたディレクトリに移動して、Dockerをbuildします。

docker build .

f:id:kanriyou_h004:20200725154105p:plain

図1.docker buildの実行

作成されたDocker imageから、コンテナを立ち上げます。

立ち上げる時に「-v」オプションを指定します。引数には、ホスト側のマウントするホスト側のディレクトリと、コンテナ側のディレクトリを「:」で区切って記載します。

docker run -it -v ~/tmp/docker/mounted_folder:/new_dir 616979cf0014

f:id:kanriyou_h004:20200725155702p:plain

図2.ホスト側のディレクトリをマウントしてコンテナを立ち上げる

コンテナが起動したら、「new_dir」が作成され、「mounted_folder」にマウントされている(「file_at_host」が中にある)ことを確認します。

cd /new_dir

ls

f:id:kanriyou_h004:20200725155840p:plain

図3.「mounted_folder」内のファイルが表示されることを確認する

無事、「new_dir」に「mounted_folder」がマウントされ、ホスト側の「mounted_folder」内に作成した「file_at_host」が表示されることが確認できました。

2.ホストとコンテナ間でアクセス権限を共有する(-u オプション)

 先ほどの「-v」オプションを使ってマウントした場合は、コンテナからホストにアクセスするときに、ルート権限を持ってアクセスできてしまいます。

このため、「-u」オプションを指定することで、適切なアクセス権でマウントさせることができます。

まず、以下のDockerfileを作成します。

FROM ubuntu:latest
RUN mkdir created_in_Dockerfile

作成したDockerfileが保存されたディレクトリに移動して、Dockerをbuildします。

docker build .

f:id:kanriyou_h004:20200725163145p:plain

図5.docker buildを実行する

次にコンテナを立ち上げる際にアクセス権を指定してみます。

「-u」オプションでは、引数にユーザーID,グループIDを「:」で区切って記載します。

この時、各IDの数字を入力するのではなく、コマンドの実行結果を渡すために$(コマンド)の記載を使って、実行結果を直接、引数として渡します。

docker run -it -u $(id -u):$(id -g) -v ~/docker/mounted_folder:/created_in_run 0f9142f9b4ad bash

f:id:kanriyou_h004:20200725164433p:plain

図6.アクセス権を指定してマウントする

マウントされたディレクトリのアクセス権を確認します。

ls -la

f:id:kanriyou_h004:20200725170307p:plain

図7.アクセス権を確認する

Dockerfileで作成した「created_in_Dockerfile」ディレクトリは、ユーザもグループも「root」権限になっています。

コンテナ起動時にアクセス権限を指定した「created_in_run」ディレクトリは、ユーザは「1000」、グループは「staff」となっていることが確認できました。

3.ホストのポートをコンテナのポートにつなげる(-p オプション)

 コンテナ上にWebサービスを立ち上げた際に、IPアドレスはホストのアドレスと同じとなるため、コンテナ上のサービスにアクセスするために、「-p」オプションを指定することで、ホストのポートとコンテナのポートにつなげることができ舞う。

今回は、jupyter notebookのDocker imageをpull(run)して、ポート番号8888同士をつなげます。

docker run -it -p 8888:8888 --rm jupyter/datascience-notebook bash

f:id:kanriyou_h004:20200725175113p:plain

<中略>

f:id:kanriyou_h004:20200725181432p:plain

図8.つなげるポートを指定してコンテナを起動

コンテナが起動できたら、jupyter notebook を立ち上げます。

jupyter notebook

f:id:kanriyou_h004:20200725181730p:plain

図9.jupyter notebookを立ち上げる

コンテナ上でjupyter notebookが立ち上がったら、ホストのブラウザから「http://localhost:8888/」にアクセスします。

f:id:kanriyou_h004:20200725182728p:plain

図10.コンテナ上のjupyter notebookにホストからアクセスする

無事、ホストからコンテナ上のjupyter notebookにアクセスすることができました。

4.コンテナの利用できるリソースを制限する(--cpus,--memory オプション)

 コンテナがホストのリソースを使い切ってしまわないように、それぞれのコンテナに利用できるリソースを制限できます。

CPUについては「--cpus」オプションで引数に利用するコア数を指定します。メモリについては「--memory」オプションで、メモリのバイト数を指定します。

例えば、以下は、CPUを1コア、メモリを2GBに制限したコンテナを立ち上げます。

docker run -it --rm --cpus 1 --memory 2g ubuntu bash

f:id:kanriyou_h004:20200725183848p:plain

図11.リソースを制限してコンテナを立ち上げる

ホストのターミナルから、コンテナのCPU、メモリの利用状況を確認します。

まずは、CPUを確認します。docker inspect コマンドで、コンテナの情報を得ることができます。ただ、情報がたくさん出すぎてしまうので、grepコマンドで、cpuという文字列を含む行だけ出力します。

docker inspect b80dcb84513d | grep -i cpu

f:id:kanriyou_h004:20200725184447p:plain

図12.コンテナで利用できるCPUの利用量を確認する

少し読みづらいのですが「NanoCpus」を確認すると1000000000NanoCPUであることが確認できます。これは、単位がNanoなので、1CPUということになります。

 

同様にメモリについても確認します。

docker inspect b80dcb84513d | grep -i memory

f:id:kanriyou_h004:20200725185047p:plain

図13.コンテナで利用できるメモリの利用量を確認する

またもや、少し読みづらいのですが「Memory」を確認すると2147483648バイトであることが確認できます。これは、1024バイトで1Kバイト、1024Kバイトで1Mバイト、1024Mバイトで1Gバイトなので、計算すると2Gバイトになります。

これで、無事、リソースを制限することができました。

 

今回の振り返りは以上になります。

今回、Dockerのホストとコンテナの関係を理解し、ディレクトリのマウントや、アクセス権限の管理、ポートの接続、リソースの制限ができるようになりました。

これで、Docker講座の基礎編が終わり、一通りDockerが使えるようになりました。

 

今回受講している「米国AI開発者がゼロから教えるDocker講座」では、もっと詳しくわかりやすくご説明いただけているので、ほんとうに良い勉強になります。

次回からは、応用編に進み、Dockerを使いこなせるようになりたいと思います! 

www.udemy.com

 

 【過去記事】

2019年8月31日(土)にE資格を受験して、合格しました!

E資格対策として勉強の進め方や、参考書などをまとめました。

これから受験される方がいらっしゃいましたらご参考まで。

oregin-ai.hatenablog.com 

 

 2019年3月9日(土)にG検定を受験し、見事合格できました!

受験の体験記や勉強法などを別のブログにまとめました。

これから受験される方がいらっしゃいましたらご参考まで。

g-kentei.hatenablog.com

 【E資格対策に使った参考書】

 

f:id:kanriyou_h004:20200725150502p:plain