Kaggle Jigsawコンペ32位でした
KaggleのJigsawコンペにチーム参加して、32位で銀メダルでした。public 58位からは上昇しましたが、金メダル圏内にはもうひと押し足らずという結果でした。
discussionにチームメイトのKazSappさんが投稿した通り、解法は6モデルの重み付き平均です。
1. bert base uncased 2. rnn 3. rnn (data augmented by translation) 4. rnn (data augmented by old toxic competition) 5. bert base cased 6. bert base multilingual cased w = [0.39193463, 0.14464678, 0.03892303, 0.06871146, 0.317778, 0.038006]
重みは、Kaggle Tokyo Meetup #5 の「Home Credit Default Risk - 2nd place solutions」で知った Scipy Nelder-Mead を用いて CV 最適化しています。
public kernel含めて多くのチームはidentity_columnsの欠損値を0で穴埋めしていたと思いますが、僕らのチームに特徴的なアプローチとしてRNNで予測した値で欠損値を補完していました。今回のデータセットにおける identity_columns の欠損値は単にアノテータ(評価者)がいなかったという意味で、必ずしも0を意味しないと考えたからです。このアイディアはKazSappさんが思いついたもので、こういった自分の手持ちにはなかった手法に辿りつけるのがチーム戦の良いところだなと改めて感じました。
同じくチームメイトのtakuokoさんも、embeddingに関する知見をdiscussion投稿しています。
金メダルを取れなかった点は悔やまれますが、Bertの強さを身に沁みて実感するなど、学びが多いコンペでした。
LightGBMでtargetをsqrt(target)に変換して予測する「reg_sqrt=True」
機械学習の教師あり学習における一つのテクニックとして、学習時の target 変換があります。昨晩に LightGBM の documentation を読んでいたところ、sqrt 限定ですが、target の変換を自動で処理してくれる parameter "reg_sqrt" を(恥ずかしながら初めて)知りました。
本記事では、学習時の target 変換の概要を述べ、LightGBM の parameter "reg_sqrt" を紹介します。
学習時の target 変換とは
target の分布が偏ったり過度に広がっている場合などに効果を発揮し得る手法です。target の各データに対して、log, sqrt を取るなどの変換を加えることで、全体の分布を整える狙いがあります。
例えば筆者が先に参加した地震コンペでは "time_to_failure" という連続値が target になっていました。この target は小さい値のデータが多く、各データに対して sqrt を取ることで、全体の分布を正規分布に近づけることが可能でした。
学習時に target を変換した場合は、当然ですが test の値を予測した後に逆変換の処理が必要になります。例えば sqrt の場合は、予測値を二乗することになります。
target を変換した場合とそうでない場合では、予測の得意・苦手が変わってくる印象があります。例えば地震コンペの場合、sqrt を取った場合は高めの予測値が出づらくなっていました。学習時の target 変換は予測の多様性も生み出すので、アンサンブルの種を作る意味でも試す価値がある認識をしています。
LightGBM の parameter "reg_sqrt"
学習時の target 変換の処理は自分で書いてもさほど難しくないですが、そのせいもあってLightGBM に parameter が用意されているのを知りませんでした。予測値を二乗する処理も自動で行ってくれるので、処理し忘れで的外れなスコアを出すミスも避けられそうです。
- reg_sqrt 🔗︎, default = false, type = bool
- used only in regression application
- used to fit sqrt(label) instead of original values and prediction result will be also automatically converted to prediction^2
- might be useful in case of large-range labels
https://github.com/microsoft/LightGBM/blob/master/docs/Parameters.rst#reg_sqrt
おわりに
本記事では、学習時の target 変換の概要を述べ、LightGBM の parameter "reg_sqrt" を紹介しました。頻繁に使っている LightGBM ですが、改めて documentation を眺めると意外と認知していない parameter や機能追加に気付けるので面白いなと感じました。
「長さの近いデータを同じbatchに入れる」の性能劣化と速度
先のKaggle Tokyo Meetup #6 でのtksさんの発表で触れられた「長さの近いデータを同じbatchに入れる」について、チームで参加した「Jigsaw Unintended Bias in Toxicity Classification | Kaggle」にて同じような取り組みをしていました。
本記事では、Jigsawコンペにおける「長さの近いデータを同じbatchに入れる」処理について、性能劣化と速度の数字を紹介します。なお、あくまで筆者の事例に過ぎない点にはご留意ください。
TL;DR
「長さの近いデータを同じbatchに入れる」処理で、性能は多少落ちるが、速度が大きく向上する
JigsawコンペでのBERT学習時 | 性能(CVスコア) | 速度(s) |
---|---|---|
処理前 | 0.9372215615637538 | 28000 |
処理後 | 0.9365093209503504 | 14000 |
「長さの近いデータを同じbatchに入れる」とは
deep learningなどの機械学習アルゴリズムでは、扱うデータの長さが均一である必要があります。テキストデータは長さがバラバラなので、最大長のデータに合わせて適当な値でデータを埋める(padding)処理が実行されます。この処理は一般に、(下図の例では角丸四角で囲まれた)batch単位で行われます。
下図の左の例は、batch単位でのデータの長さがバラバラの場合を示します。このとき、長さの大小が様々なデータが同一のbatchに含まれており、長さの小さいデータでは最大長までpaddingが実施されています。
ここで事前に各データを長さ順にsortし「長さの近いデータを同じbatchに入れる」場合を考えましょう。各batchでの長さが比較的揃うことで、必要なpaddingの処理が少なくなっています。
メリット
デメリット
- 一方で、長さの近いデータのみを同一のbatchに収めてしまうことで、データに偏りが生じて性能劣化に繋がる可能性があります
実装・解説など
次のブログに、日本語での実装・解説が記載されています。なお末尾に次の文があり、本記事は数値検証の一つの実例としてまとめた側面があります。
余力があれば、
1 ) 精度面でどれだけ悪化するのか
2 ) どれだけ早くなるのか
を比較実験した記事も書きたいなと思います。
数値検証
Jigsawコンペの場合
学習時
冒頭に記載した通り、性能は多少落ちるが、速度が大きく向上するという結果になりました。
BERT学習時 | 性能(CVスコア) | 速度(s) |
---|---|---|
処理前 | 0.9372215615637538 | 28000 |
処理後 | 0.9365093209503504 | 14000 |
なおJigsawコンペではAUCを拡張した少し複雑な評価指標が使われていました。AUCと同様に0-1の値を取り、大きいほど優れた評価指標になっています。
https://www.kaggle.com/c/jigsaw-unintended-bias-in-toxicity-classification/overview/evaluation
推論時
Jigsawコンペでは、モデルの推論をKaggle Kernel内でGPU 2時間 (7200s) に収める必要がありました。推論時にもデータのソートを実施したところ、推論時間が58min -> 25min に短縮されました。
Quoraコンペの場合
tksさんがMeetup後に数値検証した結果、性能は悪化したとのことでした。
昨日の私の発表で「長さ近いのバッチに入れるべき」と述べましたがまちがいでした。長さ近いバッチと普通バッチをsubmitしたら、前者の方が悪かったです。皆さんご指摘ありがとうございました。 pic.twitter.com/JNT1ZFtJiT
— tks0123456789 (@tks0123456789) July 14, 2019
おわりに
本記事では、Jigsawコンペにおける「長さの近いデータを同じbatchに入れる」処理について、性能劣化と速度の数字を紹介しました。あくまで筆者の事例における結果なので一概に結論を述べるのは難しいですが、一定の性能を犠牲にして高速化が実現できた結果となっています。
最近はKaggleにおいても実行時間の制限があるコンペが増えており、学習・推論の実行時間を短縮できるのは十分に価値のあることだと思います。単体モデルとしては性能劣化が生じるものの、例えば浮いた実行時間で複数モデルをアンサンブルするなど、総合的な性能向上が見込めそうです。実サービス運用においても、多少の性能を犠牲にして実行速度を改善したい場面はあり得るので、選択肢の一つに入ってくるかなと考えています。
ありがとうございます!なるほどKaggle的には得られた時間で他のことやるほうが総合的には高スコアになりそうですね〜。
— Nomi (@nyanp) July 14, 2019
Kaggle Tokyo Meetup #6 にて「PetFinder 2nd Place Solution」の題目で発表しました
「Kaggle Tokyo Meetup #6」に参加し、チーム Wodori の一員として「PetFinder 2nd Place Solution」の題目で発表もしました。
本記事では、各発表の簡単な感想などを述べます。twitterの #kaggle_tokyo や kaggler-ja slackの #event-live にも情報が転がっています。
- 「PetFinder 2nd Place Solution」(Wodori)
- 「iMet 7th Place Solution & 画像コンペのアプローチ」(phalanxさん)
- 「Quora Insincere Questions 10th Place Solution & 昔話」(tksさん)
- 「PLAsTiCC 3rd Place Solution」(nyanpさん)
- スポンサーセッション
- LT①「Neural Network のご機嫌取りがしたい」(tawatawaraさん)
- LT②「NLPチュートリアル」(tamakiさん)
- LT③「Freesound Audio Tagging 2019 4th Place Solution」(OUMed: Osciiartさん、jsatoさん)
- LT④「Google Landmark Retrieval 2019 1st Place Solution」(smlyさん)
- LT⑤「Santander Customer Transaction Prediction 2nd Place Solution」(onoderaさん)
- おわりに
「PetFinder 2nd Place Solution」(Wodori)
「iMet 7th Place Solution & 画像コンペのアプローチ」(phalanxさん)
- 後半で述べていたphalanxさんなりの汎用的なmodel pipelineが素晴らしかった
- yamlを書き換えるだけで学習・推論・ログ出力などが自動化されているらしい
- 懇親会で別の画像の強い人とも話したが同様のpipelineを持っているらしく、自分もきちんとコードを整備したいと感じた
「Quora Insincere Questions 10th Place Solution & 昔話」(tksさん)
- jigsawのsolutionとして公開されて気になっていた「exponential moving average」について話題になって、個人的にとても勉強になった
- Kaggle昔話も、知らないことが多くて面白かった
「PLAsTiCC 3rd Place Solution」(nyanpさん)
- コンペの意義から具体的な解法まで、情報量多い解説だった
- 有効だが生成に時間がかかる特徴量を大量にインスタンスを立てて作成するなど、勝負どころでの力強さを感じた
- adversarial pseudo labeling や カテゴリ変数がない場合のCatboostの利用など、将来のコンペで使ってみたいアイディアが多かった
LT①「Neural Network のご機嫌取りがしたい」(tawatawaraさん)
LT③「Freesound Audio Tagging 2019 4th Place Solution」(OUMed: Osciiartさん、jsatoさん)
LT④「Google Landmark Retrieval 2019 1st Place Solution」(smlyさん)
LT⑤「Santander Customer Transaction Prediction 2nd Place Solution」(onoderaさん)
To Be Written.
おわりに
昨年12月に開催された前回は、Kaggle Expertとして参加し、LTをしました。
その後なかなかコンペで良い成績が出せず落ち込んでいた時期もあったのですが、良いチームメイトに恵まれ金メダルを獲得してmeetupで発表できたことは、本当に嬉しいです。
日本でのKaggleの人気・実力が高まっていてmeetup参加の難易度が上がっていますが、ぜひ次回も参加できるようKaggleに精進していきたいと思います。
Kaggle、現状だとmeetup参加する資格ないな( ゚∀゚)・∵.
— u++ (@upura0) February 14, 2019
運営の皆さん、会場スポンサーのDeNAさん、ありがとうございました!
Dockerのコンテナのメモリ上限の拡張
下記ブログを参考にDockerでデータ分析環境を構築した後、Dockerのコンテナのメモリ上限の関係でエラーが発生したのでメモしておきます。
発生したエラー
The kernel appears to have died. It will restart automatically.
原因
下記記事が、そのものズバリでした。
原因は、Docker for Macのコンテナのメモリ上限が2Gになっていることです。
コンテナのメモリ上限が2Gのため、メモリ大きめのファイルを読み込もうとしたところ(Macbook Pro自体のメモリは16Gあるのに)処理落ちしてしまいました。
解決策
「Preferences > Advanced」から、メモリ上限を拡張可能です。「Apply & Restart」で変更が反映されます。
おわりに
本記事では、Dockerのコンテナのメモリ上限の関係で発生するエラーについて、原因と解決策を述べました。
同様の詰まりどころは、下記の記事で紹介されている通り、DockerでMeCabを導入しようとする場合にも発生し得ます。
「Sports Analyst Meetup #3」を開催&LTしました #spoana
はじめに
「Sports Analyst Meetup #3」を開催しました。今回は自分自身もLTで発表しました。
ロングトーク「Jリーグ導入事例から見えてきた、ダイナミックプライシングの未来」
萩元徹さん(ダイナミックプラス株式会社)
- ダイナミックプラス株式会社にて、スポーツ・エンターティメント業界などでダイナミックプライシングの導入を支援している萩元さんのご講演
- 技術的観点のみならず、ビジネス的観点からもダイナミックプライシングの具体的な課題や今後の展望を語っていただきました
- 個人的には「チケットサイトが複数存在しているため、一つのサイトで導入しても意味がない」という点が、言われてみれば当たり前ですが、導入の難しさとして確実に存在しているなと気付かされました
LT
今回は18本ものLTが実施されました。全部面白くてあっという間に時間は過ぎたのですが、流石に脳みそへの負担も若干感じたので、量の調整は検討の余地があるかなと個人的に思っています。
LTの内容については、発表資料やtogetterをご参照ください。
自分の発表
おわりに
第3回の今回もたくさんの方にご参加いただき、多くの方に面白い発表をしていただきました。またダイナミックプラス株式会社の皆さまには、会場提供・ロングトーク・LT発表と、大変お世話になりました。皆さまにお礼申し上げます。
Microsoft/interpret で Kaggle titanic
次のツイートを見かけて興味を持ったので、取りあえず使ってみました。使い方はGitHubのREADMEに記載がありますが、sklearnの機械学習モデルと同様に fit -> predict します。
Microsoftが、解釈性が高くかつ精度も高いBoostingのモデル(Explainable Boosting Machine=EBM)をOSSで公開。LIMEやSHAPといった解釈を行うための手法も搭載しており、モデルの挙動も簡単に可視化することができる。https://t.co/ghQuLwTNCj
— piqcy (@icoxfog417) June 27, 2019
Kaggle Kernel
おわりに
きちんと検証をしていないので、性能についてはあまり言及しませんが、そこそこ良さ気なスコアが出ています。解釈性のための手法を同一パッケージ内に搭載しており手軽に可視化できるのが利点なので、実務などでの選択肢の一つとして今後頭の片隅に置いておこうと思っています。