kaggle本で参考になった点のなぐり書き
これはなに?
- kaggle本を読んで血肉になった/したい点をなぐり書きにしたただの個人用メモです。ちゃんとした書評を書こうと思い続けてはや半月以上経過したので一旦書きました。
- この箇条書きの記事だけ読んでも多分内容わからないと思うので、気になった点があればぜひ購入しましょう!読後すぐに書いた推薦ツイートは以下のとおりです。
kaggle本読み終わりました。初心者にも良い本だと思いますが、ExpertやMasterなりたての人が最も恩恵を得られそうだなと感じました。自分の今までのコンペ経験を思い返しつつ、その中では経験できなかった内容を学ぶことができ「賢者は歴史に学ぶ」が可能になった感があります。著者の方々に感謝です!
— ML_Bear (@MLBear2) October 23, 2019
Chap. 2 - タスクと評価指標
- 「しきい値の最適化」という概念
- 正例か負例のラベルを提出する評価指標では必要
- このような評価指標のコンペに出たことがないので目からうろこ。
- tips
- scipy.optimize モジュールとか使えるよ (基本はNelder-Mead)
- oofで実施するという手もある
- mean-F1: 行ごとに最適化すると上がるかも (Instacart)
- 活用事例: q-weighted kappa (P100)
- 自分の参加してないコンペでたまに聞いてた指標だ
- 回帰問題の四捨五入や分類タスクで解くモデルでは対処不能
- クラス分けをする区切りを最適化する必要あり
- 予測確率の歪みに注意
- RFとかは歪む
- 補正方法
- 予測値をn乗する
- 極端に0/1に近い値のclipping
- stacking: 2段目で予測値が歪まないモデル使う
- CalibratedClassifierCV
- 目的関数を多少変更することも検討しようとのこと
- eloで回帰問題を(0-1に変換して)分類として解いてたの見たけど、(広義で捉えると)そういうたぐいの話はぼちぼちあるらしい。
- MAE: 直接目的関数にできないため、近似関数を目的関数にする。 (Fair関数 / Psuedo-Huberなど)
- MCC: Boschコンペの評価指標は不安定だった → PR-AUCに変更した
Chap. 3 - 特徴量生成のテクニック
- 「決定木の気持ちになって考える」
- 欠損値補完: GBDTはあまり補完しなくて良いが、更に強くなるには知識として持っておこう
- Bayesian Avg.
- 他の変数から予測するモデルを作る
- 各種非線形変換
- GBDT以外のモデルを使うとき用に覚えておいたほうが良さそう
- 対数、log(x+1)、絶対値の対数
- Box-Cox変換、Yeo-Johnson変換
- RankGauss
- 数値変数を順位に変換したあとに順位を保ったまま半ば無理やり正規分布に近づける
- ニューラルネットでモデルを作るときの変換として有用
- Porto Seguro の1st place solution
- Target Encodingの正しい方法: P146
- このあたり全然真面目にやってなかったので、次回のテーブルコンペでのTODOに積む。
- 学習データ: foldのtrain利用し、TE用のfoldを切って計算
- Validation: foldのtrainデータ全体から計算
- 変数の組み合わせ
- GBDTは加減よりも乗除の関係が苦手
- 分岐の組み合わせで差分はなんとか表現できる
- 乗除は厳しいので助けてあげたほうが良い
- 複数の変数を組み合わせた指数に倣おう (P198)
- BMI, 不快指数, ウィルスが活動しやすい気温・湿度
- BMI的な発想とか身近に合ってわかりやすいし、なるほどなーと。
- GBDTは加減よりも乗除の関係が苦手
- ユーザーIDごとの集約統計量など
- P153-170あたりはカンペとして壁に貼っておきたいレベル
- 個人用メモには全部転記したけど、ブログに全部書くのは気がひけるので見出しだけ
- 単純統計量
- 単純カウント
- ユニーク数のカウント
- 存在するかどうか
- 合計・平均・割合
- MAX・MIN・STD・MEDIAN・PERCENTILE・Kurtosis・Skewnness
- 時間的な統計量
- 直近や最初のレコードの情報
- 間隔・頻度
- 重要イベントからの間隔・次のレコードの情報
- 順序・推移・共起・連続
- 条件を絞る
- 特定の種類のログに絞る
- 集計対象の時間、期間を絞る
- ラグ特徴量
- 単純統計量
- testの期間に合わせて使うデータ期間も調整
- テストデータが1ヶ月分
- 前後半(orそれ以上)に分けてモデルを作るというアイディアがある
- Corporacion Faborita Grocery / Recruit Restaurant Visitor など
- テストデータ後半は1週間前のデータを使った特徴量生成ができなかったりするから
- かなり前のデータを見る前提でモデルを組む
- 前後半(orそれ以上)に分けてモデルを作るというアイディアがある
- テストデータが1ヶ月分
- 背景のメカニズムを理解しよう (P198)
- サービス提供側の視点にもたとう
- 商品の販売数0は在庫なかったのかも?
- お店の昼休みとかもあるよ?
- Webサイト構造
- 検索で上位表示するものは?
- リストボックスの選択肢などに考慮
- オンライン講座サイトにおける脱落予測
- ユーザーの真面目さや学習進捗を表現する特徴量が有用
- 自然現象のメカニズムも考えよう
- 日の出、日の入り、降雨量
- サービス提供側の視点にもたとう
- レコード間の関係性に注目する
- グラフ理論: Quora (「似ている文章に似ている文章」は元の文章に似ている)
- Bosch
- 直前に通過した他の製品情報を特徴量にする
- バッチ生産するから、前に通過した商品は似ているはず
- 相対値に注目する
- カテゴリの商品の平均値からの乖離
- 同じ職業の人が借りている金額からの乖離
次元削減
- PCA
- 正規分布を想定するので、歪んだ分布を持つ変数は注意
- このあたり、理論的な認識が弱い。
- TruncatedSVDのほうがよく使われているらしい (疎行列も扱えるから?)
- 正規分布を想定するので、歪んだ分布を持つ変数は注意
- tSNE
- Ottoで大活躍
- UMAPなら実行速度が数分の一 (umap-learn で入れる)
- クラスタリング
- クラスタ中心からの距離も有効な特徴量になりうる
- malwareでも使ってた
- クラスタ中心からの距離も有効な特徴量になりうる
面白いテクニック
- decision tree feature transformation
- レコードが分岐によってどの葉に落ちるかをカテゴリ変数の特徴量とみなす
- データのリバースエンジニアリング
- バーコード情報の復元
- データを圧縮してその圧縮率を特徴にする
- カーブフィッティングとの差分
Data Augumentation
本ではChap5だが個人的な分類はここにしておく
- instacart
- trainよりも前の情報として与えられているものをtrainとして扱った
- recruit restaurant
- 各店舗の最初のレコードはHOT PEPPERへの登録日と予想
- 登録日を適当にずらして、新しい学習データを作り出した
- HOT PEPPERへの登録日が多少ずれたところで、予測する日の来客数には大して影響がないだろう、と仮定するもの
Chap. 5 - Validations
時系列データ
- hold-outのときは傾向の近いデータをきちんとバリデーションデータにしよう
- 例: 1年毎の周期性が強いデータ → テストデータの1年前の期間をバリデーションデータにした方が良いこともある
- sklearnの
TimeSeriesSplit
: 並び順しか考慮してくれないから使い勝手悪い… - リークに注意すれば
- 本来バリデーションデータとして利用するテストデータに最も近いデータで学習し
- その前月とかでバリデーションする、という手段も使える
評価指標
- 安定しない評価指標の場合、安定する評価指標を使って勝手にモデル改善しても良い。
- 例: 2値分類ならコンペの指標に関わらずloglossやAUCを参考にする
test/train split を真似るときの注意
- 抽出がランダムかどうか?
- テストが地域で分けられてるならgroup k-fold の検討も必要
Chap. 6 - Tuning
全体
- 特徴量エンジニアリングの時とFoldのseedを変えるという方法も有用
- バリデーションデータへの過剰な適合を防ぐことができる
- CVが安定していれば1foldだけで精度確認しても良い
GDBT手動チューニング
- P318-320: Jackさんはじめ、様々な人のチューニング方法が非常に詳しく列挙されていてとても良い
ニューラルネット (MLP)
- P321: まず学習率を調整して、ある程度学習がうまく進むようになるところから始めるらしい。へぇ〜。
特徴量選択
- 相関係数 / カイ二乗検定 / 相互情報量
- null importance
- 目的変数をシャッフルしてベースを出す → 普通にやったものとの差分を取る
- 全然勘違いしてた
その他
- TPE: カーネル密度推定を利用している
Chap. 7 - Ensemble
Tips
- 様々なAveraging: 全然発想すらなかった
- 幾何平均: n個の予測をかけ合わせて1/n乗する
- 調和平均: 逆数の算術平均の逆数を取る
- n乗しての平均: n乗して平均を取り、1/n乗する。
- アンサンブルするなら過学習気味のものを使う?
- アンサンブルはバリアンスを下げる効果がある
- なら、シングルモデルはバイアスを極端に下げて、多少バリアンスあってもいいんじゃないか?
Stacking
- なんとなく効くときと効かないときがあるのは感じていたが、その根拠付けみたいなのが1mmぐらいは分かった。
- 学習データの内容を使い尽くすイメージ
- 学習データとテストデータの分布が違っているとあまり良い結果になりづらい
- accuracyよりもloglossのほうが効きやすい
- 細かく予測値をチューニングするから
- 2層目に加える特徴量
- 教師なし学習による特徴量を加えることもある
- foldの切り方
- early stopping は validation データをほんの少しカンニングすることになる
- Stackingで悪さをする可能性があるので、early stopping で止まる round 数を 別のfoldの切り方で見つけておく、という方法もあるっちゃある。
- 1層目で吐き出す目的変数
- 必ずしもTargetじゃなくてもよい
- 重要変数の欠損値補完とか、二値分類とか、役に立てば何でも良い
- 王道の組み合わせ
- GBDT 2-3 (決定木の深さが浅/中/深)
- RF 1-2(決定木の深さが浅/深)
- NN 1-2 (層が多/少)
- 線形モデル 1
ちなみに
- 前に自分でもkaggle本の超縮小版みたいな記事を書いてたので、よかったら参考にしてください。
JupyterNotebookで簡易ダッシュボードを作ってSlackに投げる方法
ざっくりいうと
JupyterNotebookで広告効果を見るための簡易的なダッシュボードを作って、Slackに毎日投げるようにして簡単に見れるようにした話です。
こんな感じです
もちろんnotebookの中身は仮のものですw
課題
広告運用実績は(GoogleAdsの)出稿データとアプリ内行動データをBigQuery上で結合し、グラフやテーブルを生成して見える化する必要がありました。
しかし、キャンペーンがXX個(たくさん)あるのでBIツールでいくつもグラフを作るのが面倒でした。。
解決策
そこで、グラフを JupyterNotebook 上のPythonでループを回して作り、その結果をSlackに飛ばしてケータイでも気軽に見れるようにしました。
流れ
- JupyterNotebook でデータ取得→データ加工→可視化
- JupyterNotebookをバッチ実行してHTMLを生成
- HTMLをSlackに飛ばす
- ↑の流れをCronタスク化して毎日自動実行する
JupyterNotebook でデータ加工とか可視化する
- データ加工とか可視化はご自由に…。
- ダッシュボードとして使う際はスクリプト部分が邪魔なので、以下のような
スクリプトを非表示にする
ボタンを作っておくと便利です。
from IPython.display import HTML HTML(""" <button id="code-show-switch-btn">スクリプトを非表示にする</button> <script> var code_show = true; function switch_display_setting() { var switch_btn = $("#code-show-switch-btn"); if (code_show) { $("div.input").hide(); code_show = false; switch_btn.text("スクリプトを表示する"); }else { $("div.input").show(); code_show = true; switch_btn.text("スクリプトを非表示にする"); } } $("#code-show-switch-btn").click(switch_display_setting); </script> """)
- 参考記事: Jupyter 知っておくと少し便利なTIPS集
JupyterNotebookをバッチ実行してHTMLを生成する
- ここからが本番
runipy
を使えば JupyterNotebook をバッチ実行できます- インストール
pip install runipy
- ipynbをバッチ実行して、
# usage: runipy 実行するnotebook 実行結果notebook runipy notebook.ipynb output.ipynb
- その後、Jupyterの
nbconvert
機能で ipynb ファイルから HTMLファイルを生成します
jupyter nbconvert output.ipynb --to html
HTMLをSlackに飛ばす
- 作ったHTMLファイルをSlackに飛ばします
- 以下のような感じで Slack の BotUser としてHTMLを投稿します
# slack_html_upload.py import requests TOKEN = 'xoxb-XXXXXXXXXXXXXXXXXXXXXXXXXX' CHANNEL = 'ZZZZZZZZZZ' files = {'file': open("output.html", 'rb')} param = { 'token': TOKEN, 'channels': CHANNEL, 'initial_comment': "【テスト運用中】今日のGoogle Adsのパフォーマンスだよ!" } requests.post( url="https://slack.com/api/files.upload", params=param, files=files)
- BotUserのToken取得は参考記事を見ていただければわかるはず
- ファイルサイズが1MBに満たないとCodeSnippetになってブラウザが立ち上がってくれないかも…?(なんかいい回避方法あるのかな…?)
- 参考記事
cronで定期実行するように設定する
最後に上記の流れをシェルコマンドにまとめてCronで定期実行するなり何なりすれば簡易ダッシュボードシステムの完成です。
runipy notebook.ipynb output.ipynb && jupyter nbconvert output.ipynb --to html && python slack_html_upload.py
備考
- Slackに直接グラフとか投げるんじゃだめだったの?
- グラフだけなら全然それでよかったですが、テーブルがうまく投げられませんでした。
- 文字数オーバーしちゃったり、
- 画像として投げたらサムネイルが小さすぎて見づらかったり…。 という感じでした。
- グラフだけなら全然それでよかったですが、テーブルがうまく投げられませんでした。
【随時更新】Kaggleテーブルデータコンペできっと役立つTipsまとめ
これはなに?
- Kaggleのテーブルデータコンペに参加するときに役立つ(と思う)Tipsを Kaggle Coursera の授業メモに色々追記する形でまとめたものです
- 自分で理解できている内容を中心にまとめました。各種資料の内容はまだまだ理解できていない内容が多く、今後も随時更新していきます(随時更新できるように勉強します)。
- この記事に書いてあるTipsをどのように活かしたかはKaggle参戦記に書いたので、併せてどうぞ。
参考文献
主として以下の資料の内容をピックアップさせていただきました。引用を明記していない部分は(ほぼ100%) Kaggle Coursera の内容です。
- Kaggle Coursera
- kaggle_memo by nejumiさん
- Kaggleで世界11位になったデータ解析手法〜Sansan高際睦起の模範コードに学ぶ
- Kaggle TalkingData Fraud Detection コンペの解法まとめ(応用編)
- Kaggle Memo by amaotoneさん
- 最近のKaggleに学ぶテーブルデータの特徴量エンジニアリング
- Santander Product RecommendationのアプローチとXGBoostの小ネタ
- Tips for data science competitions
- Feature Engineering
('20/02/09追記) テーブルコンペできっと役立つ本
- このブログ記事を書いた後に、テーブルコンペで役立つ技術が満載の本が出版されました。
- この記事ではkaggle-couseraを大いに参考にしていますが、2020年2月現在ではまずはこの本を読むのが良い、というか日本語話者のkagglerなら読まないと大いに不利になると思いますので、紹介しておきます。
EDA
全般
- データはちゃんと見よう、たまに間違ってるよ。(だからカラムの意味は理解しよう)
- EDAのとっかかりがなかったらXGBoostやLightGBMのfeature_importanceをまず見るのでも良い(2)
- 間違ってる列は消すんじゃなくて、間違ってるデータ列だとアルゴリズムに教えよう。(あなたよりアルゴリズムのほうが賢いこともよくあるよ)
- 可視化は大切だよ
- 一軸が役に立たないなら二軸に散布図かこう
- 散布図はTrain/Testが同質なデータか否かもわかるし便利だよ
- 以下のコードで一発
- 一軸が役に立たないなら二軸に散布図かこう
pd.scatter_matrix(df)
- スパイク見つけるためにヒストグラム書こう (これは絶対)
- Excelなどで色つけて眺めてみよう
- anonymous featureはリバースエンジニアリングしたらたまに良いことあるよ
- 誕生日の年とか出てきて役立った例とかあるよ
- 以下の使える表現は覚えよう
df.dtypes, df.info, x.value_counts, x.isnull
- 時系列などの場合は特に意味のある順序にソートして眺めよう(5)
データクリーニングの話
- 情報量ゼロのカラムを消そう
- 1種類の値しか入ってないカラム
- 完全にダブってるカラム
- 相関係数が1のカラム
- 参考Kernel
- Testでしか新しい値が出てこないカラム消そう
- ラベル変えたら同じになるカラム消そう
pd.factorize
使えば楽だよ
- Train/Testでデータ被ってることあるので、念のため理由を推測してみよう。
- 移動平均取ってみたらデータが正常にシャッフルされてないこと気付けるかも?
- プロットしてみるとデータがシャッフルされてるとかもわかるよ
- 線が出現したらその値が頻出とかもよくわかるよ
- カテゴリ変数の列を抜き出す表現は覚えよう
df.select_dtypes(include=['object']).columns
Numerical Data
概要
- 採用するモデルによって前処理の方法は変えよう
- 線形モデルと決定木モデルでは必要なデータが違うよ
- 異なる前処理を行ったモデルを混ぜると効くことがあるよ
Scaling
- 決定木はスケーリングは基本的に関係ないよ
- MinMaxScaler ⇔ StandardScaler
- 線形モデルではどっちでも変わらないよ
- kNNは結構影響あるかも
異常値排除 / 各種変換
clipping
- 99%タイルにクリッピングするとか効くよ
upperbound, lowerbound = np.percentile(x, [1, 99]) y = np.clip(x, upperbound, lowerbound)
rank transformation
- outliersをしこしこ処理できないときはrankに変換してしまおう
- kNNやNNはこの変換が効くよ
scipy.stats.rankdata
log transformation
- NNに激しく効くよ
np.log(1+x) np.sqrt(x+2/3)
Numericalデータの特徴量作成
- とにかく沢山の特徴量を作ってみよう
count
,sum
,max
,min
,rolling
is_null
,is_zero
,is_not_zero
,over_0.5
- 行ごとの統計情報をまとめてみよう(9)
Nanの数
,0の数
,負の数
とか
- 要素の掛け算、割り算とかしよう
- ◯◯と△△との差
- カテゴリ内の平均XX
- 変数間の相互作用は
PolynomialFeatures
で計算できる
- 小数点以下だけ取り出した要素とか作ろう
- 4980円の
980
円的なやつ- 4ドルと3.98ドルは人間心理的にぜんぜん違うよ
- もちろん切り捨て/切り上げとかも作る価値はあるよ
- それをカテゴリカル変数として扱っても良いかもね(9)
- 4980円の
- 木モデルでは以下のデータ処理が必要
- 積み上げの値を普通の値に戻す (線形モデルでは不要)
- 和、差、積など取るのは重要だから頑張ろう
- 木モデルはカラム間の処理を頑張ると良いよ
- 差や比率を直接表現できないため
- Owen曰く(8)
GBM only APPROXIMATE interactions and non-linear transformations.
Strong interactions benefit from being explicitly defined.
- 木モデルはカラム間の処理を頑張ると良いよ
- データによってはNumerical→Categorical変換するのもあり
- 例: 年齢層(30代前半)とか
- 網羅的にやるよりもビジネス的に意味がある演算をすると効率いい
- HomeCreditでの例
- 借入額と毎月の返済額の比
- 利用限度額と月々の利用額の比
- 支払い予定日と実際の支払日の日数差
- 借入額と頭金の比率 など
- Avitoでの例
- 同一カテゴリ内の平均価格と自分の価格との差/比
- 例: iPhoneの中では安い
商品名の中の名詞
でグループ化した価格平均を使った特徴量
- 同一カテゴリ内の平均価格と自分の価格との差/比
- Kaggle Days Paris by CPMP
- 2Sigma Appt Rental: apartmentの説明文から相場を予測 → その相場予測と家賃との差を特徴量にした
- TalkingData: アプリDLしたらもう広告踏まないよね? → 同じ端末から同じADへの次のクリックへの時間を予測し、実際の時間との差を (ry
- Avito 9th
- HomeCreditでの例
- ビン詰めすると効くこともある(9)
- Testの数値範囲がTrainと外れているときとか
Categorical / Ordinal Data
Encodings
LabelEncoding
- 木モデルに有効
- 線形モデルの場合は
OnHotEncoding
が追加で必要 - 木モデルは
OnHotEncoding
は不要なことが多い- 遅くなるのでむしろ不利かもしれない
- 線形モデルの場合は
- S席、A席、みたいなやつは数字にしてあげると効くこともある
- 木モデルに有効
FrequencyEncoding
- 出現比率でエンコーディングする
- 線形モデルだけではなく、木モデルにも有効
- 異常値に弱い(9)
- logを取ると効くこともある(9)
TargetEncoding
- 強力だけどdata leakageには注意しよう
- leakageを防ぐ工夫はH2O.aiの人のスライドが詳しい
- Smoothing: 日本語記事もある
- leave-one-out
- Weight of Evidence
- その他の工夫
- out-of-fold (Kaggle Meetup #4 LT by Jackさん)
- random noise を加える (Port Seguro Kernel)
- 時系列など過学習が気になる際はTargetそのものではなく、重要特徴量にたいして行うと選択肢もアリ(HomeCredit 2nd)
- 基本的にLeakが気になるケースでは初心者は用いないほうが良い(2)
- 時系列の場合
- CatBoost で過去全体のtargetの平均を用いるという方法もある(kaggler-ja mamasさん)
- Column descriptionsで
Timestamp
を指定し、 - さらにtraining parametersの
has_time
を指定する。
- Column descriptionsで
- 過去N月のtarget平均を使うのも良い
- CatBoost で過去全体のtargetの平均を用いるという方法もある(kaggler-ja mamasさん)
Tips
- 複数のカテゴリカル変数をくっつけて使うこともある
- 性別☓客室等数とか
- 線形モデルで有効
- 多くの掛け合わせをすることを恐れるな
- OwenはAmazonCompetitionで7掛け合わせ変数を使った(8)
- アホみたいな掛け合わせが効くことあるから
weird interaction
も試してみろ(9)
Datetime / Coordinates Data
Date and time
- 日付は重要なこと多いから徹底して特徴量作成しよう
- 通常のDatetimeに加えて、◯◯から△分、とかも使える
- 同様に、◯した日と△した日の差、とかも
- 午前/午後/深夜とか、平日/休日/祝日/祝前日、とか
- 国民の祝日、大きなスポーツイベント、第一土曜日とか(9)
- 重要な日付から近いものの重みを大きくしてみよう
- 逆に遠いものは減衰させて重みを小さくしてみよう
- 曜日・時刻・(月の)日付などの周期性のある特徴量を円周上に配置し、cos・sinに分解して、循環連続性を表現するのも効果的(2)(9)
Coordinates(座標/地理) Data
- 重要なランドマークや都市からの距離とか
- 周辺地価とかの有効なデータの追加とかも効く
- 都市はgeographic feature作ったりいろいろやってみよう
- 近くに何個家があるか、学校があるか、など近くの情報も使おう
- GPS座標、郵便番号の住所への付与とかもやってみたら良いかもね(9)
- ニセの空間情報に気づけ(9)
- 不可能な速度での移動
- 今いる場所と違う場所での出費
その他 特徴量作成 Tips
次元削減系
- PCAよりNMFのほうが木モデルに使いやすい次元縮約をしてくれる
- PCAが効く理由
- XGBoostなどの決定木系アルゴリズムが軸に斜めの表現を不得手(表現できないわけではないが、PCAで回転した方が効率的)としていることに起因するとのこと(2)
- トピックモデル(LDA等)の活用を検討しよう(4)
時系列データ
- 基本的には直近のもので学習させたほうが良いが、1年前などに特徴的な周期性がないかは確認すべき(5)
- 時系列で重み付けしたカウントなどは有効な特徴量になり得る(5)
- 「費用」は先週の費用、先月の費用、昨年の費用などに分解してみよう(9)
- 全てのデータが一度に与えられるコンペではユーザーの未来の行動の情報の特徴量を作ると強い (TalkingData 1st)
- 過去の行動よりも未来の行動に基づく特徴のほうがたいてい強い
- 直前のクリックからの経過時間
- 今後1時間以内でのそのカテゴリ変数の値の出現回数
- 過去の行動よりも未来の行動に基づく特徴のほうがたいてい強い
- 過去のフラグ推移を連結した文字列をカテゴリ変数として扱う(7)
- 水準数が100を超えるような場合に有効なことが多い
- DeepLearningではなぜか効かないことが多い
- 文字列ヒストグラムはbosch 15thでも使われている
- 時系列じゃなくても文字列連結してカテゴリ変数にするのは他のコンペでも使われている模様(kaggle: Porto Seguro's Safe Driver Prediction まとめ)
巨大データを扱う
- データが大きいときは複数あるfoldのうち1つだけで検証するのもあり(Kaggle boschコンペ振り返り)
テクニック系
うまくカテゴライズできなかったテクニック集
- DenoisingAutoEncoder
- kNNによって観測された近傍点の数を特徴量として追加する(2: Facebook Predict check-insの1st place Winner’s solution)
- KMeans等のクラスタリングして、クラスタIDを使う or/and クラスタ中心までの距離を特徴量として加える(Malware '19 kernel)
- 予測値を特徴量に入れてもう一度学習する(Home Credit)
- (Targetではなく)重要特徴量を予測するモデルを作って活用する (HomeCredit 2nd)
- 予測した数値と実際の数値の差なども活用できる (Elo 18th: 予測した日付と実際の日付の差)
- 活用事例は(6)に詳しい
- メインデータとサブデータが1:多のような場合 (Home Credit や Elo の場合)
- サブに時系列性があればカテゴリ変数は最後の値を取る、などが使える
- サブデータにメインデータをマージしてサブだけで学習しすると効くことがある (Home Credit 17th / Elo 1st)
- 先頭/末尾のN行のみでAggregationなども使える
- Nの値をいろいろ変えるとなお良し
- 代表的な特徴量だけで計算したkNNで近傍500点のtargetの平均を特徴量として加える (Home Credit 1st)
- Adversarial Validation できないように特徴量を加工してTrainへの過学習を避ける (Malware '19 6th)
- K近傍を用いた特徴量抽出
- FMを活用した特徴量作成
- Kaggle Past Solutions
- ちゃんと漁れば宝の山のはず
特徴量選択
- Ridgeなどにかけて1変数ずつ有効かどうか確認するstepwiseが早い(5)
- LightGBMなどでできたらそちらのほうが良いが、計算時間との兼ね合いで決めても良い。
- boruta, eli5, NullImportances
- (今の所使って成功したことない…orz)
欠損値処理
見つけ方 & Fillana Approaches
- 見つけ方: ヒストグラムをかこう
- Fill NA Approaches
- カテゴリ変数か数値変数かによって欠損値の扱い方を変えよう
- 適当なoutlierに書き換える
- 木モデルの場合に有効
-99999
や、MAX値+1
とかmin値-1
とか
- 平均や中央値で書き換える
- 線形モデルで有効
- 木モデルにはネガティブ
- カテゴリ変数の場合
- 欠損値を「新たなカテゴリ」として扱うのも良い(3)
- K個のカテゴリがあったら、欠損値もカテゴリとみなしたK+1個の
One Hot Encoding
を行う
- K個のカテゴリがあったら、欠損値もカテゴリとみなしたK+1個の
- 欠損値を「新たなカテゴリ」として扱うのも良い(3)
- 推測する
- 注意
-99999
とかで置き換えたときにCategorycalEncoding
などに影響しないように注意- feature generationの前にfillnaしないほうが良い
Tips
category_x_isnull
の2値カテゴリーも有効- Trainデータに出てこないカテゴリーがTestに出てきたら?
- TrainとTestでの出現回数をカウントしてそれをカテゴリーにする
- XGBoost/LightGBMはNaNを直接扱える
- 値が0である説明変数の数を数えて追加の説明変数として加えてみる(2)
不均衡データの扱い
- Over-/Under-sampling
- SMOTEは効かないことが多い
- Under-samplingでもきちんとバギングすれば精度出るから問題ない(TalkingData 1st)
- imbalanced-learnの実装も使ってみよう
- 利用例: Porto Seguro Kernel
- 重みの変更
- LightGBM:
class_weight
の調整とか
- LightGBM:
Validation
Good Validation is MORE IMPORTANT than Good Model.
(8)- validationのsplitはオーガナイザーのそれを模倣しよう
- 模倣して良いValidationが出来たら
TRUST LOCAL CV
- 正しいValidationなしで進めるのは羅針盤無しで航海するのと同じ(進まないよ)
- 「模倣しろ」の具体例: Malware '19 6th
- ついでに、時系列的の場合のValidationの切り方の注意の勘所もわかって良い
- 模倣して良いValidationが出来たら
Normal-KFold
かStratified-Kfold
か?- 多クラス分類なら
Stratified-Kfold
必須(5) - 回帰でも1変数
k-means
してStratified
にすることも(5)
- 多クラス分類なら
- Adversarial Validation
- Testに近いTrainデータでValidationを行うのもあり
- LBを信じるべきか否か(8)
Ensemble / Stacking
- KAGGLE ENSEMBLING GUIDEが参考になる
- 序盤はEnsemble/Stackingによる安易なスコアアップは控えよう(2)
- 時間と余裕があるうちに、他の多くの人はやらないような独創的な手法を模索しよう
- 人と同じアプローチは後から取り入れれば良い
- パラメータ変えたモデルを配合するだけでもスコア伸びるよ
- random seed average はもはや常識(4)
- Averagingは単純だが強力な手法(2)
- N乗平均、対数平均など試してみると良いかもしれない(2)
- 小さなデータだったら平均アンサンブルで十分
- SingleModelの精度にこだわりすぎないように
- Ensembleすることは大前提として多様な(相関の低い)モデル群、特徴量を作成しよう
- 弱いモデルでもEnsembleで化けることがあるから念の為に取っておこう
- Ottoの例: P57あたりから
- Owen(8):
The strongest individual model does not necessarily make the best blend.
- とはいえ最近は
A great model is better than ensemble of weak models
という考え方も復活してきてはいる- CPMPさんがKaggle Days Parisで「bestfittingさんも言ってた」と紹介
- CPMPさんはTalkingDataで48個の特徴量のLightGBMシングルモデルで大多数のチームのEnsembleモデルに勝ったとのこと
- GBMと相性が良いモデル
- RandomForest(2)
- Neural Network(理由: Tree Baseアルゴリズムは決定境界が特徴軸に平行な矩形になるが、NNなどは曲線(曲面)となるため(2))
- Glmnet(RidgeやLASSO)(8)
- 浅いモデルと深いモデルを混ぜると効果あることがある
- Adversarial Validationが誤分類したデータを重視してEnsemble Weightをきめる(6)
- LightGBMとXGBoostをアンサンブルしてもあまり精度をあげられた例はない(7)
- Stakingの実装例: Porto Seguro Kernel
- AUCが評価指標のときはアンサンブルする前にrank化しよう(KAGGLE ENSEMBLING GUIDE)
様々なモデル
- Regularized Greedy Forest: くそ遅いけど試してみる価値あるよ
- (相対的に)早い実装もある: FastRGF
- CatBoost: デフォパラメータが良いからめっちゃ時間の節約になるよ
- tSNE
- 強力だけどパーフレシティのチューニングが大変難しい
- TSNEのsklearnくそ遅いからtsneパッケージ推奨
学習のTips
- 評価指標にとらわれなくても良い
- (時系列データなどの場合) 特徴的な傾向があれば学習データ期間をずらしてしまうのもあり(7)
- XGBoostにおけるネタ(7)
- 同じデータセットに対しては最適な学習回数はサンプル数に対しておよそ線形なので推測ができる(切片が0じゃないのでそこだけは注意)
- 単一モデルでは学習回数が不足でも過剰でも精度が落ちるが、random seed averagingは学習回数過剰気味でもあまり精度が落ちない
max_depth
が多いほどaveragingの効果が大きくなるので、単一モデル検証で精度が拮抗していたらより深い方を選ぶのがベター学習率
は小さくすれば精度が良くなるが、averagingではその効果が大きく減少するので、必要以上に小さくしないほうが学習時間的に有利。colsample_by*
は小さくすると学習時間が線形に減少する。精度向上にも寄与することが多いので小さめの値を試してみよう。
Tuning
- パラメータの意味は この記事 がとてもわかり易いです
- XGBoost
max_depth=7
あたりから始めるのがよい- Lightgbmは
深さ
に加えて木全体の葉の数
を制御できるので融通が利いて良い bagging_fraction
: 1つの木を育てるのにどれくらいのデータを使って良いかを決める グリーン (オーバーフィッティングしたら下げればよい)feature_fraction
: 1つの木を育てるのにどれくらいの特徴量を使って良いかを決める グリーンmin_data_in_leaf
: 汎化に最も重要なパラメータ レッド (オーバーフィッティングしたら上げる)lambda_l1
,lambda_l2
: これも重要、0,5,15,300 あたりを見てみる。num_round
: =何本の木を作るか。最初の方の木で十分に説明できてしまうこともある。learning_rate
: 高すぎると全く収束しない可能性ある、適切な小ささの学習率は汎化に有効。- trick: 以下を行うと大概精度が上がる (学習時間は長くなるが )
step * alpha
eta / alpha
boosting_type
: dropoutを模したdart
っていうのも有効- Owen流(8)
- CPMP流 (Kaggle Days Paris)
- subsample=0.7 & 他はデフォから始めろ
- min_child_weight: train/val gap 大きければ増やせ
- それから max_Depth or number_of_leaves を調整しろ
- LBがCVより低ければ正則化を強めろ
- LightGBM
- なにはともあれ 公式 Parameters Tuning ガイド
num_leaves
多め、feature_fraction
かなり小さめ、とかもあり(5)feature_fraction = sqrt(n_features)/n_features
程度だと特徴量数の影響を受けづらく、良い(5)- dartだとearly_stoppingしたときに挙動が変だから気をつけて
- Random Forest
- gbmより深い木でも大丈夫なのでトライしてみよう
- giniが大概良いが、たまにエントロピーが勝つ
- コンペの序盤と中〜終盤の2回やるという方法もある(Malware '19 Discussion)
- Optunaが学習中断/再開とかもできて何かと便利
その他Tips
- Testデータに対する
semi-supervised learning
は現状で主要な差別化ポイントのひとつ(2) - 終了直前で激強kernelが出現することがあるので対応が必要(5)
- 特に銅メダル圏内ぐらいのとき
- 最終日は2サブ残しておき自分のsolutionとアンサンブルできるようにしておけば安心
- 1サブ残しだと精神的にきついので、2サブ推奨らしい
黒魔術系
まだ使ってないけど役に立ちそうなもの
- Linear Quiz Blending
- 遺伝的プログラミングによる特徴量作成
未整理: 使えるライブラリとか
あとでまとめる(かも)
- pandas-profiling
- コピペで使える。Kaggleでの実験を効率化する小技まとめ
- あなたの生産性を向上させるJupyter notebook Tips
- Jupyter Notebook Viewer
- kaggle-apiというKaggle公式のapiの使い方をまとめます
- JupyterLabのおすすめ拡張機能7選
- Vaex入門 / 可視化もXGBoostも
- Preemptive Instance のシャットダウン時に使えるScript
- pandas.DataFrame のforループをゆるふわ△改良して300倍高速化する
最後に
冒頭にも書きましたが、個人的に理解できている(と思っている)内容のみ書いています。まだまだ理解できていない内容が多いので、今後も随時更新していきます。
あと、実験に飽きてきたらトーマス・エジソン名言集を読むとたまに元気づけられます。よろしければ参考にしてください笑。
私は失敗したことがない。 ただ、1万通りの、うまく行かない方法を見つけただけだ。
私たちの最大の弱点は諦めることにある。 成功するのに最も確実な方法は、常にもう一回だけ試してみることだ。
ほとんどすべての人間は、もうこれ以上アイデアを考えるのは不可能だ、 というところまで行きつき、そこでやる気をなくしてしまう。 勝負はそこからだというのに。
Kaggle参戦記 〜入門からExpert獲得までの半年間の記録 & お役立ち資料まとめ〜
これはなに?
- デジタルマーケター 兼 プロダクトマネージャー 兼 データアナリスト (肩書長い…) の私が Kaggle に挑戦した約半年間の記録です。現時点で2つのコンペに真面目に取り組んで2つの銀メダル(入賞)を獲得出来ています。
- Kaggle挑戦期間を通して、有識者の素晴らしい資料に助けられたのでとても感謝しています。同じような志を持つ方に自分の記録が少しでも役に立てばと思い、有用な資料のリンク集に私のKaggle参戦記ポエムをつけてまとめてみました。
- 自分の得意領域で勝負しようと思ってテーブルデータのコンペばかり選んでいるのでDeepLearning系の話は全然ないです、すみません。
目次
プロローグ
初ガチコンペデビュー
スランプ → 一転して銀メダル獲得
2回目のコンペ挑戦
2個目の銀メダル獲得とその先
おまけ
('20/03/20追記) 入門に役立つ本
- このブログ記事を書いた後に、入門に役立つ本が出版されました。この入門記事ではkaggle-couseraをやる、と書いていますが、今から入門される方はまずはこの本で入門するのが良いかと思います。
- 上記の本で入門した後は、以下の本で実力を伸ばすのが良さそうです。
プロローグ
Kaggleへの興味の芽生え (2018年7月ごろ)
- 私はデジタルマーケティング畑の出身です。デジタルマーケは大量のデータを扱うことが要求されるので、データ分析やプログラミングのスキルは自然と身につきました。そのスキルを活かして一時期データアナリストもやってました。
- Kaggleのことは元々なんとなく知っていましたが、なんか凄いアンサンブル世界大戦が繰り広げられているだけの場所だと思っていました。そんなある日、「kaggle初心者の私が3ヶ月でソロゴールドを獲得した方法」というブログ記事を見つけました。
- このブログにはどのような流れでKaggleを勉強していったか、どんな資料が役に立ったか分かりやすく書かれていました。
- その後、このブログで知った「tkmさんのYoutube動画」を見て、なんとなくとっつきにくかったKaggleに一気に興味を持ち、ちょっとやってみっかーと思いたったのが2018年8月頃でした。
※ 自分はこの時点ですでにPythonや機械学習の基礎知識がありましたが、無い方はこの記事の末尾につけたような初心者本を一度読んでからやるのが良いかと思います。
初参戦 → 即撤退 (2018年8月)
- 2018年8月頃はHomeCreditというコンペがとても盛り上がっていました。
- データもなんとなく面白そうだったので、とりあえずKernel(参加者が自分のモデルを公開して議論する場所)からモデルをパクってきて参加してみました。
- ただ、モデルを改善するにあたり何から手をつけたらいいのかよくわからなかったので、全然手が進みませんでした。
- そのまま手探りで進めてみても良かったのですが、これでは良い結果は絶対に出ないだろうなと思い、まずはきちんと勉強することにしてすぐ撤退しました。
ガチ参戦に向けた修行 (2018年8〜10月)
- 自分自身の転職と被ってバタバタしていたので、以下の資料を使って3ヶ月ぐらいゆっくり勉強を進めました。
- How to Win a Data Science Competition: Learn from Top Kagglers
- Coursera の Kaggle 講座で、おすすめ資料として各所で常に話題に上がります。実際にKaggleで優勝している方々が講師をされており、非常に実践的な内容を知ることが出来ました。(これ無しで銀メダルを取れたイメージは全く湧きません)
- Validationに対する考え方や、過学習の避け方、木モデルと線形モデルに対する特徴量エンジニアリングの違いなどはこのコースを見ないと気づくことすらなかったと思います。
- いつかまとめたいと思っているのですが、自分の雑記メモはこの後も何度も見返しました。
- kaggle初心者ガイド
- Kaggler-jaというSlackグループの有志による初心者ガイドです。ここに載っている記事は一通り読みました。
- また、Kaggler-jaのSlackで話されている内容も示唆に富むものが多いのでぜひこちらから参加されることをおすすめします。
- Kaggle Meetup Tokyo #4 動画
初ガチコンペデビュー
初ガチコンペ…、のはずが。(2018年10月)
- 3ヶ月ぐらい勉強したところで、ちょうど良いコンペを見つけました。
- 「Google Analytics Customer Revenue Prediction」です
- 仮想のGAのデータが与えられて、売上予測せよというものでした。
- 私の出自はマーケターでGAチョットワカル( ̄ー ̄)ニヤリなのでこれは好都合だと思って喜び勇んで始めることにしました。
- しかし、データ眺めてさぁ始めようとおもったら
GAコンペ、TESTとTRAINのデータの質が違うとは聞いてたけど、なるほどなーという感想が芽生えつつあるよ!TRAINではdisplay ad全然つかってなかったのにTESTでは結構 (流入の5%強 )使ってるんだね!GDNのリマケ広告、最近強くなったもんね笑。
— ML_Bear (@MLBear2) 2018年10月8日
- その2日後にリーク(コンペ設計のミス)が発覚して
お、Discussion読んでたらすごい内容が出てきたよ。これ、GAのテストアカウントのデータ使ってるんだね。ということは…??!
— ML_Bear (@MLBear2) 2018年10月10日
- わずか10日後にコンペが大幅に変わってしまいました
Rコンペは完全な未来予測になったね!10/15までの来訪者の12月〜来年1月の再来訪による収益を当てろって!これはなかなか設計が変わって難しいね…。クリスマスもあるしなかなか大変だよ!でも、条件はみんな一緒なのでこれはこれでいいんじゃないかな。
— ML_Bear (@MLBear2) 2018年10月16日
- そのまま続けても良かったのですが、Leader Board (コンペ期間中のランキング表) が全く機能しないので、面白くなさそうだなと思って回避しました。
- Twitter界隈では年末ジャンボ宝くじと言われていましたが、真面目にやればそこそこ良い感じの結果が出たそうです。しかし、いま考えてもはじめてのガチコンペとしては回避して良かったと思います。
初ガチコンペ参戦 (2018年11月下旬)
- どうしたもんかねぇと思っていると、ほどなくして「Elo Merchant Category Recommendation」というコンペが始まりました。
- クレジットカードの購買データを用いて顧客ロイヤリティ的な数値を当てるコンペでした。
- マーケで使うLTVの概念とか流用できるかなー、と思ってよく考えずに参戦しました。
- 最後まで何を予測してるのかよく分からないコンペでしたが笑、結果としては以下の観点から初心者としては良いコンペでした。
- データサイズが大きくない
- Validationが難しくない
- 特別なドメイン知識を必要としない
ベースモデル作成(12月初旬)
- コンペ序盤はデータを眺めつつ、ベースとなるモデルを組んでいきました。
- データを眺めるのはpandas-profilingが圧倒的に便利でした
- ざーっとデータを見たあとはほぼマーケの実務と同じ感じでデータ分析しました
- データはすべてBigQueryに投入→粛々とSQL書いてデータ抽出
- 気になったところがあればExcelでコネコネ
- ベースモデル作成はKernelの写経から始めました。
- このKernelを改変したものをずっと使っていました
- はじめてコンペに参加する際は、KernelにめっちゃUpvoteがついているものを選べば大怪我はしないと思います。
- EloはValidationを気にせず↑のモデルのままで何も問題がなかったので、ある意味初心者に良いコンペだったと思います。
- 次のMalwareコンペに参戦したときに Validation すら作れず大変苦戦しました…。
- このKernelを改変したものをずっと使っていました
- 後々のことを考えてGCEにJupyter notebookを立てて作業していました
- 最初は8コアから始めて、最後の追い込みのときはは64コアとか使っていました。
- 64コアとはいえpreemptiveインスタンスだと非常に安く、GCPの無料体験枠で十分に収まりました。
- 参考になった記事: jupyter notebook on GCE
特徴量エンジニアリング(12月初旬〜中旬)
- ベースとなるモデルができたあとはひたすら基本的な特徴量を作りまくりました
- 各ユーザーの過去1ヶ月、3ヶ月、6ヶ月…の取引状況など、実務で使うような集計をたくさんしました
- Courseraで習ったような変換を行ったり、異常値の処理を作ったり有効な要素同士の割り算掛け算とかしました。(平均利用金額とか)
- 2〜10個ぐらいをモデルに追加 → スコア改善したらモデルに組み込みというのをひたすら続けました
- 良い特徴量を作っただけスコアが改善してとても楽しかったです
- このあたりでKaggleにハマり始めたと思います
- すこし応用的なもの
- 基礎的な特徴量を作った後は凝った特徴量を作って遊びました
- LDA / PCA / tSNE といった技術を活用してコネコネしてました
- この時期によく読んでた資料
- 特徴量エンジニアリングについて
- 実験の効率化について
特徴量選択(12月下旬)
- 特徴量作成も一段落ついてきたある日、Less is more というスレで高度な特徴量選択の有用性を知りました。
- その頃、簡単に思いつく特徴量はだいたい作って特徴量が300-400個ぐらいになっていました
- 減らしたほうが良いのかなと思って手を付けてみました
- 結果的にはうまく行きませんでした
- boruta / eli5 を使ってみましたが、CVにoverfittingしてしまうイメージでした
- 特徴量が300個ぐらいだと不要だったのかもしれません
- 次のMalwareも特徴量が200個ぐらいだったので使わなかった
- 参考になった記事
- borutaの解説記事
- 自分がborutaをやったあとに出た記事でした。先に読みたかった笑。
- eli5 permutation importanceの解説記事
- borutaの解説記事
ブレンディング(12月末)
- 特徴量選択に一通り失敗したあと、3つのモデルを混ぜ合わせて
スコアを上げるKernelを参考にしつつ、特徴量エンジニアリングだけじゃないスコア改善にトライしました。
- 各コンペの内容に合わせていろいろなモデルの混ぜ方を出来るようになると上位安定しそうです。
- Eloの場合も上位解法見てるとそれぞれ工夫されていました。
- 自分は↑のKernelと同じようなやり方しかしてなかったので金に届かなかったのかなとも思います。
- 後で見返してみたらこの時点で既に銀メダルを取れるスコアを出せていました
スランプ → 一転して銀メダル獲得
スランプ(2019年1月)
- 年が変わった頃から長いスランプに入りました。
- 基本的な特徴量をだいたい作りきったからか、全然スコアが上がりませんでした。
- この時期は何したかあんまり覚えていません笑
- 飽きてる
ELOコンペわからんぞ…!
— ML_Bear (@MLBear2) 2019年1月13日
outlier検出の精度を上げるべきか、それ以外のものか予測制度上げるべきか…。outlierによる誤差が大きいからそこ頑張ってみたくなるけど、そもそも予測が難しい。まぁよく出来てるっちゃよく出来てるんか…?
飽きてきたから他のコンペ見てみたい…。
- TargetEncoding失敗して凹んでる (今思えば避けられるだろ、っていう)
target を使った特徴量エンジニアリングをやってみてるんだけど「スコア下がるけどリークなだけ」なことが多くてぬか喜び感がハンパない…w 避けては通れないんだろうけどw
— ML_Bear (@MLBear2) 2019年1月14日
- いろいろ読んで試行錯誤はしました
- 【Kaggle】HomeCreditコンペ上位入賞者の手法まとめ(メモ)
- Kaggle Meetupの各回のスライド
アンサンブル(1月末)
- 特徴量エンジニアリングに飽きてきて気持ちが切れたので「後で使うもの先に作っておくか」と開き直ってアンサンブル(Stacking)のコードを書き始めました。
- 通常はコンペ1週間ぐらい前からやる作業だそうです
- EloではシンプルなAveragingはあまり効かなかった印象なので(異常値が丸め込まれちゃう?)、初コンペ参加者としてはこの時点でコードを書いておいたのは良い判断だったと思っています。
- 停滞していたスコアが如実に伸びてビックリしました
- 「コンペ序盤にアンサンブルで小手先のスコア向上しないほうが良いよ」(≒アンサンブルとかどうせみんなやるから、時間あるならオリジナリティがあることやれよ。)というセオリーの本質が少し理解できました。
- 勉強にはKAGGLE ENSEMBLING GUIDEを使いました。
- アンサンブルの基礎から応用まで丁寧に説明してくれている記事で、バイブルと言われているとのことです。
- 実際に学ぶべき点が非常に多く、次のコンペの時も合わせて何度も読み返しましたが、まだ2割程度しか理解できてない気がします笑
- その他に使った資料
- Stacked Generalizationで分類器のスコアをひねり出す
- ↑のGuideと併せて読むと理解が捗ると思います
- Simple Stacker LB 0.284
- Stacking実装は過去コンペのKernelを大いに参考にしました
- Owen Slide
- Stackingの勉強で見つけましたがその他の部分もとても参考になりました
- 実践多クラス分類
- アンサンブルでどんどんスコア上がる事例が載っていて面白かった
- Stacked Generalizationで分類器のスコアをひねり出す
Malwareコンペに浮気(2月初旬)
- Eloに完全に飽きたので他のコンペ(Malware)を覗き始めました
今のコンペ(Elo)が進まないことの気晴らしとして次のコンペ(マルウェア)のデータを眺めて滑らかに次のコンペに移行するライフハックを実践中…、ってこれやってたらいつまでも結果出ぇへんぞ…(´・ω・`)
— ML_Bear (@MLBear2) 2019年2月8日
- この後すぐEloコンペ再始動するのですが、その後も毎日少しづつMalwareコンペのKernel/Discussionに目を通し続けてました。
- その中でMalwareで使うベースモデルやアンサンブルモデルのKernelを見つけられました。
- そしてMalwareの銀メダルにつながってたので結果オーライでした
- 浮気用に使った資料
- 特徴量エンジニアリングの神スライド
- Malwareはほぼカテゴリ変数だったのでこの資料で色々な対処法を学びました
- lightgbm カテゴリカル変数と欠損値の扱いについて+α
- LightGBMでのカテゴリ変数の扱い方について学べました
- 特徴量エンジニアリングの神スライド
神Kernel現る(2月7日)
- 浮気した矢先にGrandMasterのraddarさんによる衝撃的な Kernel が現れました
https://t.co/n5zuHYDAg1
— ML_Bear (@MLBear2) 2019年2月8日
すげぇKernelきたw こういうリバースエンジニアリングみたいなのできるまじすごいw 世界は広い…!
Eloのtargetの数値の意味を Grandmaster が解き明かしてるKernel。サブスクリプション支払いになってる人を何人か見つけてきて、de-anonymized targetと突き合わせて証明してる。すごいという小並感しか出てこないwhttps://t.co/SOCxSpzuaj
— ML_Bear (@MLBear2) 2019年2月11日
- Eloコンペではいくつかの特徴量が謎の数値になっていました
- raddarさんはそれをリバースエンジニアリングしてキレイな数値にしてみせました
- 当時の感動を伝えられる語彙力が無いのが歯がゆいですが、世界トップクラスのデータ分析力を目の当たりにしてクラクラしました。
Eloコンペ再開 (2月中旬)
- raddar-Kernelにより今まで失敗していた特徴量(購入金額系など)の特徴量エンジニアリングに目処がつき、やる気が復活しました。
朝書き出したTODOタスクをポモドーロ・タイマーに従って淡々と消化するマンになる!
— ML_Bear (@MLBear2) 2019年2月9日
- SQLで特徴量をごりごり作りました
そしてその内容を元に特徴量候補をSQLでひたすら作るわたし…。
— ML_Bear (@MLBear2) 2019年2月11日
ギャップがすごいw
- raddarイベント以降、とてもはかどりました。
気分転換にMalwareのデータ見たりKernel読んだりしはじめたら、なぜかEloのスコアがぐいっと伸びたので、人間いかに気分転換が重要なのかがよく分かる…!(半分ぐらいはraddarさんの情報のおかげですが…)
— ML_Bear (@MLBear2) 2019年2月15日
初の銀メダル獲得(2/26)
- その後、(個人的には)滞りなくコンペは進み銀メダルゲットできました。(しかもTOP2%圏内でビックリ)
Eloコンペ、銀メダル取れました!(43 / 4221位)
— ML_Bear (@MLBear2) 2019年2月27日
初めて真面目に参加したコンペで銀狙って銀取れたの嬉しい! pic.twitter.com/iWUNYTlAQ1
- 最後の10日間ぐらいはほとんど何もできず、ただ下がっていく順位を眺めていました。
- みんなpublic LBにoverfittingしてるに違いないと自分に言い聞かせる日々でした
- 最終的には暫定130位まで落ちたが→43位(その後42位に)でフィニッシュでした
- 金圏にはかなり遠いかなと思っていたのですが、あと0.004で金でした
- 結果発表直後は「金圏、意外と近いな」と少し慢心してました(爆)
- が、その後上位解法を読んで「近くて遠いとはこのことか」と無事、謙虚に戻れました笑。
2回目のコンペ挑戦
2回目のコンペ参戦
- Eloはソロ銀取れたのですが最終の順位変動が結構大きいコンペで、Kaggleの実績がほとんどない自分はフロックっぽくて嫌でした。
- なので、フロック疑惑を晴らすのも兼ねて、Elo終了後の2週間で(それまで浮気していた)Microsoft Malware Predictionにチャレンジすることにしました。
- 結果としてはMalwareでもTOP2%で銀メダルを獲得できたものの、Elo以上に激しい順位変動があるコンペだったのでフロック疑惑は晴らせませんでしたw
- が、EloよりKernel/Discussionが充実しており大変勉強になったコンペでした。
- 細かい内容は振り返りにまとめた & 新しい資料少なめなので以下はサラッとです。
序盤から大苦戦 (2月下旬)
- Eloが終わる10日前ぐらいからEDA→初歩的なFEを実施していました
- Eloが終わったときからベースモデルを作成してテストしました
- Eloとの違いに大苦戦しました
Validation: CVとLBが合わない…
- EloのときはValidationが素直でした
- なので、Malwareに参戦して初めて、Courseraの先生が「羅針盤となるValidationを早期に作れ」と言っていた意味を理解できました。
- 以下のKernelや記事でAdversarial Validationの概念を初めて学んで試行錯誤しました (上手く行ったとは言ってない)
データ量: 計算全然終わらない…
- 特徴量エンジニアリングなどはTrainデータの一部で行ってました
- Trainデータ全量での計算はコンペ終了1週間前ぐらいから始めてました
- ↓全然楽じゃないことをまだ知らない少年だった頃の私のツイート
ELOで使ったコードリソースの大半がマルウェアでも使えるから楽だ…!MasterとかGrandMasterの人はこういうのの積み重ねがすごいんだろな〜!
— ML_Bear (@MLBear2) 2019年2月26日
ベースモデル作成と特徴量エンジニアリング(2月下旬〜3月初旬)
- 振り返りの内容と被るので割愛します。
- あまり時間もなかったので特に新しい資料などは探さず、ここまでに書いたものやコンペのDiscussionを読んでました。
Parameter Tunings
- MalwareコンペではLightGBMのパラメータチューニングが効きました
- Eloでも行っていたがあまり意味がなかった(なんかのKernelで凄く良いパラメータを引いていたようです)
- 使った資料
- 公式Docs
- LightGBMの公式資料は実践的でわかりやすかったです
- はじめてのKaggle体験記
- LightGBM関連の資料がたくさん載っていたので一通り「読み」ました (全て理解できたとは到底言い難い…)
- Kaggle Coursera の Week4
- 参考にはしましたが、後述するoptunaで自動化したのであんまり参考にはなってません…。
- CPMPさんのDiscussion
- 公式Docs
CPMPさんはパラメータチューニングをコンペの序盤と中盤の2回行うらしい。マルウェアは結構適当なパラメータでやってたけど、昨晩optuna回したら今までのパラメータと全然違うものが出てきて焦った (LBも上がった)。Validation概ね出来た時にやっておくべきだったかも…?https://t.co/HPyQk8PU9t
— ML_Bear (@MLBear2) 2019年3月5日
- ライブラリ
- optuna が非常に使いやすく、他のライブラリは検討もしませんでした
- 公式サンプル を多少変えただけで使えました
- 私は基本的にpreemptiveインスタンスなので(強制シャットダウンされたときも)最適化を途中から再開できるのも助かりました
- チューニング前後は以下の感じです
- optuna が非常に使いやすく、他のライブラリは検討もしませんでした
チューニング前
'num_leaves': 300, 'min_data_in_leaf': 75, 'boosting': 'gbdt', 'feature_fraction': 0.2, 'bagging_freq': 3, 'bagging_fraction': 0.8, 'lambda_l1': 0.1, 'lambda_l2': 0.1, 'min_child_weight': 50
チューニング後
'num_leaves': 1638, 'min_data_in_leaf': 1819, 'boosting': 'gbdt', 'feature_fraction': 0.202, 'lambda_l1': 50.300, 'lambda_l2': 41.923, 'min_child_weight': 8.56,
データ全量でのテスト(3/7〜)
- Malwareコンペのデータは重かったのでコンペ初〜中盤まではtrainデータを1/4ぐらいに絞っていろいろテスト
- trainデータ全てを使い始めたのはコンペ終了のわずか1週間前
- 自分は終了日を1日勘違いしてたので体感的には6日前
- 全量で回すとすぐにBest公開Kernel超えられたのでホッとしました
MalwareようやくアンサンブルKernel抜いたぞ…!って言ってもSingleModelで抜いたから後は突き放すだけなんだけど。それにしてもデータ重いいw#kaggle - because this RAM isn't going to use itself. https://t.co/8uH1H3BjpA
— ML_Bear (@MLBear2) 2019年3月8日
アンサンブル (3/8〜)
- 評価指標に合わせてアンサンブルの方法を変える必要があることをDiscussionで知りました
- KAGGLE ENSEMBLING GUIDEにも同じことが書いてあることに気づき、読み返しました。
Gibaさん曰く、AUCが評価指標のときはアンサンブルする前にrank化するのが良い…?まだ(個人的には)アンサンブル考えるタイミングじゃないので後でporto seguroのコンペのKernelとか読んでみよう。https://t.co/RwLBoQa7d4
— ML_Bear (@MLBear2) 2019年2月26日
- アンサンブル詳細は振り返りに書いたので以下サマリーです
- はじめはパラメータを変えたLightGBM3つでStacking: LB 0.698
- Kernelのdeep系FMをそのままStacking: LB 0.700
- DeepFactorizationMachine
- 喜びのTweet
- 危うさ: Kernelでは何も特徴量の前処理をしていなかったため、publicLBにoverfittingする可能性があると思っていた (実際していた)
マルウェア0.700到達!ただ、若干の危うさを残すモデルだからちょと怖い。FinalSub選択には注意しなきゃ。
— ML_Bear (@MLBear2) 2019年3月8日
- Kernelのdeep系FMの特徴量を自分のものに置き換えてさらにStacking: LB 0.701
- Kernelそのままのdeep系FMは消してRankAveraging: LB 0.700
- ファイナルsubmitには後ろ2つを選択
2個目の銀メダル獲得、そして…。
2個めの銀メダルでExpertに (3/14)
Malwareコンペ、Shakeすごすぎてワロタけど自分は無事2個めのソロ銀メダルをゲットできました!(Public34位→Priivate43位)
— ML_Bear (@MLBear2) 2019年3月14日
メダル確定したら Kaggle Expert だ!今回、Shakeがあってもなくても銀取れただろうし、銀はそこそこ安定して取れるようになったと思うので次は金とってMasterになりたい! pic.twitter.com/DNa0rV3UkM
マルウェアの銀メダル確定して、Expertになれました!(Expert牧場に入牧すると言うらしい笑)
— ML_Bear (@MLBear2) 2019年3月14日
次は金メダル獲ってMasterになりたい! pic.twitter.com/HhyuUwdN0z
今後は: 目指せKaggleMaster
- デジタルマーケやPMの業務に使えると思って機械学習の勉強がてらKaggleやり始めましたが、2つのコンペを経てKaggleそのものがとても楽しくなってきてしまいました。
- Kaggleについてはカレーちゃんさんのこのツイートが秀逸でした
kaggleは
— カレー🍛専業kaggler (@currypurin) 2019年2月26日
・チームプレイは楽しいしスコアが上がる
・ソロでもプレイ可能で優勝も狙える
・世界中の人が参加
・課金すると強くなるけど、課金だけでは強くなれない
・良い成績をとると、リアルにも良い影響
・kaggle勢とtwitter・リアルで交流すると更に楽しい
と奇跡的なバランスのネットゲームだな
- 幸いにもあと金メダル1個とれれば Kaggle Masterの称号が貰えるので、Master目指してやっていこうかと思います!
- って書いたけど金メダル簡単に取れたら苦労しませんw
- ということでこれからも自分のペースで頑張っていきます!
おまけ
まだ使ってないけど役に立ちそうなもの
- 遺伝的プログラミングによる特徴量生成
- K近傍を用いた特徴量抽出
- Linear Quiz Blending
- Linear Quiz Blending以外にも役立ちそうな高度なテクニックが満載
- FMを活用した特徴量作成
- Kaggle Past Solutions
- ちゃんと漁れば宝の山のはず
- FastRGF
- Courseraのセンセイ方も試してみる価値あるよ、と言ってたRGFの速い実装。
- Eloで試したけど上手くスコア出ず断念しましたが効くコンペもあるのかも
- Light LDA
機械学習の基礎を勉強する時に使ってたもの
Kaggle初参戦する以前に勉強していた時に役立った本リスト
Python機械学習プログラミング
- 機械学習の基礎の基礎から勉強できるテキストです。
- 実際にscikit-learnを用いたサンプルコードもほぼすべて載っているので、こちらで基礎固めを行いました。
- この本の内容が概ね理解できない、コード書けない、だと厳しいと思います。
PythonとKerasによるディープラーニング
- ディープラーニングに勉強のためにこの本を買いましたが、機械学習全般の話がとても平易な文章で書かれており、ディープラーニングよりも機械学習の全体の流れの勉強になりました。
- 高度な機械学習が行えるディープラーニングだからこそ、まずは簡単な手法でベースラインを作ってみる、などは、ディープラーニングに限らず様々な場面で基礎として有用だなと。
scikit-learnとtensorflowによる実践機械学習
- こちらもtensorflowを触ってみようと思って買ったのですが、前半の、scikit-learnを用いた機械学習の話のほうが役に立ちました
- アンサンブルの基礎的な考え方もこの本で学びました。
おわりに
- 超長文読んでいただきありがとうございました。(はたしてこの箇所まで読む人いるのだろうか…)
- 冒頭にも書きましたがKaggle界隈には有用な資料がたくさん転がっており、独力であっても勉強して結果を残すことが出来ると思います。
- 一度ハマれば勉強にもなるし楽しいし一石二鳥の趣味になると思います。
- この記事を読んでKaggleに興味を持ってくれる人が一人でもいて、どこかのコンペでお会いできたりすればこれ以上幸せなことはありません笑。
Kaggle Microsoft Malware コンペ振り返り
これはなに?
- MalwareコンペはKernelやDiscussionから学ぶべき点が非常に多いコンペで、個人的にとてもコミュニティに感謝していました。(おかげさまでソロ銀メダルも取れました)
- なので、終わったらコミュニティに恩返ししようと思ってKaggleのDiscussionに投下するべく Malware コンペの解法や工夫していた点をサラッと箇条書きにしていました。
- が、コンペの最終結果がKaggleの歴史的に見ても大荒れの結果(参考)になってしまって、真面目に英訳するのが面倒になったのでブログにサクッと起こしたものです。
- これから肉付けしたり加筆しようと思ってたものをほぼそのまま出したのでヌケモレ多数あります笑
Malwareコンペのきっかけ
- Malwareの前はEloコンペをやっていましたが、1月下旬ごろからコンペに飽きていました。(その後raddar神が降臨して面白くなるのですが笑)
- 気分転換がてらMalwareのデータ見たりして遊んでいましたが、上述の通りKernelやDiscussionが面白く勉強になっていました。
- Eloはソロ銀取れたのですが結構Shake Up/Downが大きいコンペで、Kaggleの実績がほとんどない自分はフロックっぽくて嫌でした。
- なので、フロック疑惑を晴らすのも兼ねて、Elo終了後の2週間でチャレンジすることにしました。
- フロック疑惑を晴らすために出場したのに、Elo以上のShake Up/Downだったのでフロック疑惑は晴らせなかったのが残念です。
- が、2個めの(ソロ)銀メダル取れたので、次に金メダル取ったらMasterになれます。そのステップアップが出来たのは嬉しかったです。
注意
- 以下の内容は全てCV/PubLBでの話です (PriLBの後追い検証はしてません)
- 雑記なのでCPMPさんのSolutionを読まれる方が勉強になると思います笑
特徴量エンジニアリング
ベース
- 良さそうなKernelがあったので、基本的な特徴量はここから頂戴しました。
https://t.co/mcmgLZCZKF
— ML_Bear (@MLBear2) 2019年2月10日
マルウェアのベースはこれが良さそうかな。シンプルだけど今んとこベストスコアでかっこいい。OuterJoin使ってTrain⇔Testの出現割合が偏ってたり、出現数少ない値を排除してる部分とかとても綺麗で参考になる。全カラムをカテゴリ扱い(FreqEncoding)してるので伸び代も多そう
- 今回、Train/Testで時系列でデータが分けられていました。さらに、このLBが完全時系列分断されている可能性があることを指摘しているKernelがあったため、特にバージョン系の特徴量の取扱に気をつけました。Trainデータ内の新し目のバージョンはまだマルウェアに感染していなくて、これから感染する、などの可能性もあるかなと思ったためです。
マルウェアコンペのLBが完全に時系列でPublic⇔Private分割されているという問題を指摘したKernel。ある日付(正確には推測の日付)以降のsubmissionを全部0にしてもPublic LBは全く影響を受けなかったとのこと…。これは難しそう…。https://t.co/RRSZrcN5rV
— ML_Bear (@MLBear2) 2019年2月13日
- 具体的にはVersion系の扱いを以下の感じで処理しました
- バージョン番号そのもの及び分割したものでTargetEncodingはしなかった
- 古いバージョンだけ行ったり、丸めたバージョンで行ったりはしました。(が、あんまり効いてなかった気がします)
- AvSigVersionは日付に変換して日付として処理を行った
- 例: Train(or Test)の最新の日付までの差分(Latest AvSigVersion Date of TrainData - AvSigVersion Date)
- CPMPさんのSolutionみてるとこの当たりにMagicFeatureあったみたいなのでたどり着けなくて悔しい
- バージョンを古い順に並べ替えて、一番古いものから数えて出現頻度が何パーセンタイルに位置するか、なども効きました
- バージョン番号そのもの及び分割したものでTargetEncodingはしなかった
Target Encoding
- バージョン番号系以外はTargetEncodingを利用しました
- Fearure Importance高めの特徴量では2個の掛け合わせでも行いました。
- 個人的には効いていたと思っていましたが、CPMP Solutionでは効いてないと書いていたので、なにか間違っているかもしれません。
Cluster Distance Features
- このKernel で出てきたクラスタ中心までの距離の特徴量もそこそこ使えました
https://t.co/X1NvYFnsiA
— ML_Bear (@MLBear2) February 10, 2019
KMeansでクラスタ中心を求め、中心までの距離を特徴量として加えるというどっかで見た特徴量を作ってるカーネル、なんだけど、マルウェア下調べの身としては強い特徴量の活かし方の方が参考になった。同じ特徴量からエンコーディングだけ変えて何度も追加したりするんだね。
- 具体的には以下のようにして作って選別しました。20回ぐらい回して2-3個使えたかなぐらいでした。
- LightGBMでFearure Importance高めの変数を20個ぐらいピックアップ
- そのうち7個をランダムで選んでKMeans→クラスタ中心までの距離計測&特徴量化
- LightGBMに投入して精度が下がらなかったら採用
KNN Features
- Home Credit 1st Place Solutionで使われていた
neighbors_target_mean_500
も作りました - 計算時間の都合で多くは作れなかったがいくつか採用した
LDA Features
- 以下のような感じでLDAした特徴量はそこそこ効いていました
- TrainデータとTestデータを結合
- Fearure Importance高めの特徴量を2個づつ取ってきて以下のように処理
- AVProductStatesIdentifierとCountryIdentifierの例
- 各 AVProductStatesIdentifier で CountryIdentifier が何回現れるかカウント
- LDAで AVProductStatesIdentifier のCountryIdentifier文脈でのトピックを算出
- AVProductStatesIdentifierとCountryIdentifierの例
Validation
以下のKernelを参考に似た感じでやりましたが最後まで苦戦していました。うまく行った人のやり方聞きたいです。
Models
Base Models
概要
- LightGBMはKernel Fork後自分でかなり書き換えましたが、FMは特徴量の入れ替えとコードの可読性改善以外ほとんどいじっていません。
- 時間的制約…、と言いたいところですがDeepFMとかほぼ知識なくいじれなかった…。
詳細
- LightGBM
- base: Kernel
- CV 0.7344 / pubLB: 0.697 / priLB: 0.645
- 特徴量: 180個ぐらい
- 120個ぐらい自分で足しました
- 20-30個ぐらい削ったと思います
- XDeepFM / NFFM
その他のModel
- Stacking用にRandomForest、LogisticRegression、XGBoost、CatBoostなど作りましたが結局使っていません。
Parameter Tuning
LightGBM
- パラメータチューニングのノウハウがあまりないので、Optunaを使いました。
- パラメータの意味は分かるが、どれくらい動かしたら良いかとかKaggleCoursera以上の知識がない
- 経験ある人なら簡単にたどり着けたなのかもしれませんが、自分では絶対に設定しないようなパラメータにたどり着けてとても有用でした。 (LB +0.003)
- 具体的なパラメータは以下のような感じでした
チューニング前
'num_leaves': 300, 'min_data_in_leaf': 75, 'boosting': 'gbdt', 'feature_fraction': 0.2, 'bagging_freq': 3, 'bagging_fraction': 0.8, 'lambda_l1': 0.1, 'lambda_l2': 0.1, 'min_child_weight': 50
チューニング後
'num_leaves': 1638, 'min_data_in_leaf': 1819, 'boosting': 'gbdt', 'feature_fraction': 0.202, 'lambda_l1': 50.300, 'lambda_l2': 41.923, 'min_child_weight': 8.56,
Stacking/Blending
- 最終的にFinal Best Scoreとなったものは以下3モデルのRankAveragingでした (CV: 0.73616 / pubLB: 0.700 / priLB: 0.649)
- LightGBM
- XDeepFM
- NFFM
- これ不要なんだけど気づきようがありませんでした…
- 抜いてたら金だった…
- PublicLB最良モデルは↑に加えて以下をStackingしたものでした (CV: -- / pubLB: 0.701 / priLB: 0.647)
- LightGBM*2
- XDeepFM (Kernel そのまま)
- NFFM (Kernel そのまま)
- RandomForest / LogisticRegression
- 最終Submitには上の2つを使いました
- PubLB最良のものはKernelのデータを使っているが、Kernelの特徴量は保守的な補正が入っていない
- なので、pubへのoverfitが怖かった。
- そのため、自分が作った保守的な特徴量だけのモデルのシンプルなRankAveragingをもう一つのサブとして選んだ
余談: その他工夫した点
- データが重かったのでモデルを組んだり特徴量のテストをする時はデータを1/4程度にサンプリングして使ってました
- Trainデータ全量でモデルを走らせたのはわずか1週間前でした
- この計算結果がコケたら諦める、というものが無事 pubLB 0.697 を出してアンサンブルKernelを抜いたときにはホッとしました
MalwareようやくアンサンブルKernel抜いたぞ…!って言ってもSingleModelで抜いたから後は突き放すだけなんだけど。それにしてもデータ重いいw#kaggle - because this RAM isn't going to use itself. https://t.co/8uH1H3BjpA
— ML_Bear (@MLBear2) March 8, 2019
- とにかくデータが重かったので特徴量作成はBigQueryを主としていました。
- 僕の本職がデジタルマーケティング / PM なのでpandasよりもSQLのほうが慣れてるというのもありますが…笑
- 以下の処理を自動化して寝ている間に特徴量テストが終わるように工夫した
- 寝る前までにクエリ書いて保存しておく
- テスターが以下の処理を勝手に行う
- BigQueryに並列でクエリ投げる
- pickleに保存する
- pickle読み出してLightGBMに投入して採否判断
- どうせLightGBMでコア数必要になる & とにかく時間がなかったので、データ処理は綺麗に書く方法を考えるより多コアで殴れるように工夫して書きました。
- read_gbq的なコマンドのBigQueryからのデータ転送が遅いので下記のように並列化していました
import os import glob import joblib import pandas as pd from google.cloud import bigquery from reduce_mem_usage import reduce_mem_usage def bq_load(query, feature_name, exec_date): file_path = './features/{}/df_{}.pickle'.format(exec_date, feature_name) bq_client = bigquery.Client.from_service_account_json('/path/to/xx.json') df = bq_client.query(query).to_dataframe() df = reduce_mem_usage(df) df.to_pickle(file_path) exec_date = '20190301' queries = {} for sql_file_path in sorted(glob.glob("./sql/{}/*".format(exec_date))): with open(sql_file_path) as f: query = f.read() feature_name = get_feature_name_from(query) queries[feature_name] = query r = joblib.Parallel(n_jobs=32)( joblib.delayed(bq_load)(query, feature_name, exec_date) for feature_name, query in queries.items() )
- 以下のような並列処理のメソッドも多用しました
import numpy as np import pandas as pd from functools import partial from sklearn.preprocessing import StandardScaler from multiprocessing import Pool, cpu_count def parallelize_dataframe(df, func, columnwise=False): num_partitions = cpu_count() num_cores = cpu_count() pool = Pool(num_cores) if columnwise: # 列分割の並列化 df_split = [df[col_name] for col_name in df.columns] df = pd.concat(pool.map(func, df_split), axis=1) else: # 行分割の並列化 df_split = np.array_split(df, num_partitions) df = pd.concat(pool.map(func, df_split)) pool.close() pool.join() return df def standard_scaling(sc, series): """ 列毎の正規化処理 """ 〜〜〜〜 return scaled_series sc = StandardScaler() numerical_cols = [hoge, fuga, ...] f = partial(standard_scaling, sc) df_scaled = parallelize_dataframe(df, f, columnwise=True)
CPMP Solutionからの学び
(あとで追記するかも)
- adversarial validation がしずらくなるようにデータを前処理した
- CPMPさんの曰く
- 当初のデータはAUC0.98でadversarial validation出来てしまう
- データを前処理して0.7以下に抑えた
- 例: EngineVersion を Freq Encodingする等
- 「どれくらい前処理(すれば|しなくても)良いんだろう?」って思ってた解だ。なるほど…!
- CPMPさんの曰く
- magic feature
- 同じEngineVersionにおけるMax AvSigVersion と AvSigVersionとの差
- LB: +0.020 らしい。すげぇ…。
- 言われてみれば意味合いはなんとなく分かる(がたどり着けない)ので、分析のセンスとTry&Errorの手数の重要さがわかる。
- 同じEngineVersionにおけるMax AvSigVersion と AvSigVersionとの差
- Models
- Single
- LightGBM: pubLB 0.698
- Keras: pubLB 0.696
- Blend
- Keras (w/ LightGBM preds): pubLB 0.698 (priLB 0.683!)
- Single
- TargetEncodingは効かなかった
- 外部データも効かなかった
総括
- 大荒れのコンペでしたが、自分的には色々勉強になったし銀メダルゲット出来たので総じて良いコンペでした。
- Malwareするまでは `adversarial validation' の概念すらしらなかったので隔世の感です…!
- また、文頭にも書きましたがKernelやDiscussionでのコミュニティの暖かさにも感激したコンペでした。
- 1st Placeの人も書いてるように @cdeotte @ogrellier @cpmpml あたりの投稿が非常に参考になりました。
- 一旦一区切りだけど次は金メダル取れるように頑張りたいです。
プロダクトマネージャーを志す人におすすめの50冊 〜基礎体力養成編〜
この記事は Product Manager Advent Calendar 2018 の10日目の記事として書かれました。
まえがき
プロダクトマネージャの職責は比較的曖昧で、そのため「プロダクトマネージャーとは何か」という議論は混迷を極めます (その曖昧さがPMの本質だ、という話もあります)
と参考記事にもあるように、会社によってプロダクトマネージャーに求める職責に若干の差はあるものの、プロダクトマネジメントの業務は基本的には多岐に及びます。
その実務においては広範な知識が必要ですが、知的生産の基礎体力がない状態ではせっかく身につけた知識もフル活用できないでしょう。野球に例えると、良いバットを持っていても、それを使いこなすカラダが出来ていないとホームランが打てないようなものかと。
そこで今回は、プロダクトマネージャーを志す人におすすめしたい、知的生産の基礎体力を養成するための本をまとめてみました。
私自身、デジタルマーケティングの出自で、データアナリストの経験もあるので、そういった職種の方にも共通しておすすめできると思います。
個人的に必読だと思っているものに★をつけた以外は、あえておすすめ度は書いていません。
読書には時期がある。ほんとジャストミートするためには、時をまたねばならないことがしばしばある。
という大江健三郎氏の言葉がありますが、この本あわないかも、と思ったらその本は一旦捨てていただいて、気が向いたらそのうちまた読む、といったカジュアルな感じで読んでいっていただければと思います。
もくじ
- まえがき
- もくじ
- 基本的な心構えを知る
- ユーザーの気持ちを知る大切さを知る
- イノベーションを生み出す技術を知る
- プロダクトマネジメント
- がむしゃらにやる大切さを知る
- マーケティングや説得の技術を知る
- アイデアを作る技術
- デザインの基礎を学ぶ
- スライド作成の技術
- 経営の基礎を学ぶ
- 会計基礎知識
- マネジメント・チームビルディング
- 生き抜くコツを知る
- 自分の強みを見つける
- プログラミング・機械学習の基礎
- 色々な教養
- 人生で大切なものがなにか迷ったときに読む
基本的な心構えを知る
★イシューからはじめよ
- 仕事の効率を劇的に向上させる本
- 個人的に自己啓発本の頂点
★外資系コンサルの知的生産術
論理的思考力ばかり喧伝される現代で真に必要な知的生産技術とは何か
ザ・ゴール
「ボトルネック」の概念とその重要性を学ぼう
トヨタ生産方式
出版されて40年経った今でもAmazonランキングの上位に登場するお化けみたいな本
ユーザーの気持ちを知る大切さを知る
★創刊男の仕事術
リクルートで数々の新規事業立上を行った男の、ユーザーニーズを徹底的に知る技術を知ろう。
★ジョブ理論
あらゆるサービスや事業はユーザーの「ジョブ」を解決するために設計される
★リクルートのすごい構創力
数々の新規事業立上げを成功させるため、リクルートが行っている数々のしくみを知ろう。
江副浩正
- リクルート創業者の伝記
- 「かもめが翔んだ日」でも可
スープで行きます
SoupStockTokyo立上時の企画書が非常に秀逸
イノベーションを生み出す技術を知る
★ゼロ・トゥ・ワン
- 至言がたくさん
- 価値を創造する企業をどう立ち上げるか
★世界は落下している
Indeed 出木場さんの名言を紹介したKAIZEN sudokenさんのブログ記事
逆説のスタートアップ思考
- このスライドの増補改訂版みたいな本
- スライドみて合わなければ読まなくても良い
イノベーションのジレンマ
- 巨大企業が新興企業の台頭を許す理由を知る
- 新たなイノベーションを起こすヒントを得る
プロダクトマネジメント
★Inspired
最近、プロダクトマネジメント本は色々出てるけど取りあえずこれを読もう
Product Management Triangle
- 本じゃないが2本の記事で概念理解しよう
Hooked ハマるしかけ
熱心なファンがつくサービスの仕掛けを知ろう
フェイスブック 不屈の未来戦略
フェイスブックがどうやって世界No.1のSNSサービスに成長したか。
Startup Playbook
これまた本じゃないけど
がむしゃらにやる大切さを知る
★嫌われる勇気
- タイトルはミスリード気味。食わず嫌いせずに読んでみて。
- 原因論から脱却し、今まさに目の前にある現実に必死で向き合う大切さを知る。
- ホリエモンの「ゼロ」でも代用可かも
渋谷ではたらく社長の告白
不格好経営
マーケティングや説得の技術を知る
USJのジェットコースターはなぜ逆に走ったのか
元USJ森岡さんがUSJを復活させた話
ドリルを売るには穴を売れ
タイトルの概念だけ理解できたらOK
経営戦略全史
辞書的に使うのが良いかと
影響力の武器 漫画版
- 人が動かす6つの原則を知ろう
- 個人的には漫画版で良いんじゃないかと
僕は愛を証明しようと思う
「非モテコミット」の概念を知りユーザーへの非モテコミットを回避しよう
アイデアを作る技術
★アイディアの作り方
30分で読めて一生使える
SPRINT
SPRINTそのものを行うことはあまりないしれないが、そこで使われているテクニックは使えるものが多い。
デザインの基礎を学ぶ
★ノンデザイナーズ・デザインブック
- 必読
- 美のセンスは体系化出来る。
スライド作成の技術
外資系コンサルのスライド作成術
スライド作成のところもよいが、「心がまえ」のセクションも良い
プレゼンテーションZEN
スライドは情報を詰め込むもの、という常識からの脱却。
経営の基礎を学ぶ
三枝さん3シリーズ
- V字回復の経営
- 戦略プロフェッショナル
- 経営パワーの危機
V字回復の経営読んで合わなかったら他の2冊は読まなくて良い
経営学
クロネコヤマト創業者の伝記
会計基礎知識
決算書がスラスラわかる 財務3表一体理解法
- 最低限のお金の勘定はできるように
- この本の内容くらい理解できないと苦しい
マネジメント・チームビルディング
★Team Geek
こんな良いまとめもあるよ
学習する組織
- 読むのに1ヶ月ぐらいかかる
- 「迷ったときに読む」でも良いかも
ワーク・ルールズ!
Googleの人事制度や職場環境がどう設計されてきたのか知ろう
あなたのチームは機能してますか
チームビルディング状況のピラミッドが◎
論語と算盤と私
岡田監督インタビューの章だけでも是非
生き抜くコツを知る
★人生は、運よりも実力よりも「勘違いさせる力」で決まっている
- 実力をつけるのと、実力を理解してもらう、のは違うこと。
- 自分のマーケティングも頑張ろう
自分の強みを見つける
さあ、才能に目覚めよう
ストレングスファインダーやるだけでも可
プログラミング・機械学習の基礎
たのしいRuby
- プログラミングしたことないなら
- 単純作業はプログラムにやらせよう
Python機械学習プログラミング
- コードはすべて飛ばして良い
- どんな問題をどう解けるかを知ろう
ゼロから作るDeepLearning
プログラミングも数学も知らなくてもディープラーニングを理解できる本
仕事ではじめる機械学習
これ、AIでなんとかなりませんか、って言っちゃうPMにならないように。
色々な教養
お金2.0
「価値」あるものが徐々に変わってきていることを知ろう
暗号解読
- 暗号技術の基礎知識
- 小説としても面白い
アルゴリズムが世界を支配する
銃・病原菌・鉄
「構造が結果を支配する」
人生で大切なものがなにか迷ったときに読む
★イノベーション・オブ・ライフ
人生に本当の幸福をもたらしてくれるものはなにか。また、それを大事にすることの大切さを知ろう。
仕事は楽しいかね
迷ったときに読む
【イベントレポート】プロダクトマネージャー・カンファレンス2018
これは何
2018/11/06-07にベルサール秋葉原で開催された "プロダクトマネージャー・カンファレンス2018"(通称: pmconf / hashtag: #pmconfjp)のイベントレポです。
今回、pmconfに初めて参加したのですが、非常に学びが多かったのでまとめてみました。
丸二日間で29人の登壇者という規模感だったので全部は取り上げられず、自分の印象に残った部分のみの抜粋となります。詳細が気になる方は、イベントページに掲載されている全セッションのtogetterをご覧になると良いと思います。
今回のレポートは「講演をどう自分が受け取ったか」の "感想文" なので、講演者の意図と異なる点もあるかもしれません。その際はご容赦いただけると幸いです。(もしくは @naotaka1128 までご指摘下さい!)
あと、長くなりすぎたので明確に2日目後半の感想が雑な感じになってます…。(気が向いたら後日ちゃんと書き直します。)
1日目(11/06)
丹野さん基調講演
講演資料
ざっくりまとめ
今回のpmconfのテーマは「愛されるプロダクトを創ろう」。pmconf実行委員を代表し、メルペイ丹野さんがテーマの選定理由を講演されました。
「AARRRモデル/LTV/CAC」の概念を使い、愛されるプロダクトを創る必要性をシンプルに解説。初心者向けと題されていましたが、PM経験者の僕でも「なぜ愛されるプロダクトを創る必要があるのか」ってこんなに上手く説明できるんだー、と十分勉強になった講演でした。
なぜ愛されるプロダクトを創るのか
(SNSの発達などで情報取得コストが著しく下がったためか) 近年、AIDMAモデルよりもAARRRモデルが消費者行動により当てはまるようになってきている。
AARRRモデルではユーザーに愛されると以下の効用があり「LTV>CAC」を実現できれば加速的な成長が可能になる。
- 継続利用が増え顧客生涯価値(LTV)が上がる
- 紹介などで顧客獲得コスト(CAC)が下がる
逆に、ユーザーに愛されないと「LTV<CAC」となり、収益化にたどり着くことすらできなくなる可能性がある。
- 継続利用が減り顧客生涯価値(LTV)が下がる
- ネガキャンで顧客獲得コスト(CAC)が上がる
LTVを伸ばした好例は最近のAdobe。売り切りモデル(一括96000円)→サブスクリプションモデル(月960円)への転換を行うことでLTVを伸ばした。ただし、サブスクリプションモデルは一度売上が下がる(ので思い切った決断は必要)。
愛されるプロダクトを創ろう
愛されるプロダクトを創ることは
- 顧客にとっての利用価値
- 自社にとっての事業的価値
の両方を伸ばすことが出来る。ぜひ、愛されるプロダクトを作って、顧客価値と事業価値の両方を最大化していきましょう。
ノンピ 荒井さん & 及川さん
講演資料
ざっくりまとめ
nonpi荒井さんと及川さんのランチタイムセッション。nonpi荒井さんが携わられたGoogleの社食設計の話を伺って「社食設計もユーザー体験設計なんだな〜」ととても関心したので、抜粋してメモ。
「荒井さんはプロダクトマネージャーという肩書じゃないけど、実質的にプロダクトマネジメントやってるから連れてきた」と言って、こういうセッション組める及川さん素敵だ!
Googleの社員食堂は福利厚生?
Googleの社員食堂は単なる福利厚生ではなく、一緒に食事をすることでコミュニケーションを活性化してイノベーション創出も狙っている。Gmailはエンジニアが社食でくだらない話をしているときに思いついたらしい。
「コミュニケーションの促進」を目指して
Googleは渋谷にオフィスがあったときは社食がなく、六本木ヒルズに移転するときに社食を作ることになった。他のGoogleの社食の例に漏れず、六本木ヒルズの社食も「コミュニケーションの促進」を目的として設計された。
ご存知の通り、六本木ヒルズは眺めが良い。いい景色を眺めながら食事出来るようにするため、カウンター席を設けたくなるものだが、目的が「コミュニティの促進」なのでカウンター席とかは作らなかった。
食堂設計 = ユーザー体験設計
ユーザーの使いやすさという点でも色々工夫した。
- 味噌汁の味: 人は活動すると水分を消化して塩分を求めるようになる。なので、「朝さっぱり⇔夜濃いめ」のように朝昼晩で味噌汁の味噌の配合を変えたりしていた。(すごい!)
- 食べ残しを減らす: 自分で食べ残しを捨てさせて可視化した。50%ぐらい減った。(すごい!)
- 健康の増進: フルーツなど健康に良いものは目に付きやすいところに置き、逆に、コーラなどは目のつきにくいところになど工夫した。
- 設計の正しさの確認: サーベイやアンケート(手書き)で判断して随時改善した。
エウレカ 金田さん
講演資料
ざっくりまとめ
pairsの立ち上げから今までを振り返りながら、
- 求められる価値が時代によって変化することを前提として
- ユーザー価値を粘り強く考え続ける
ということの大切さをストーリー調で講演されたセッション。 表現は違うものの、後のpixiv清水さんのセッションとも重なるところが多く、愛されるプロダクトを作り続ける大切さを再確認できたセッションでした。
「海外ではやってるらしいよ」はバカにならない
pairsは「海外でオンラインデーティングアプリ流行ってるらしいよ」的なノリで話が持ち上がってスタートした。
- ここで、ビジネス・サービスモデルに超革新的なものなんてない
- → だから「海外ではやってるらしいよ」はバカにならない
- → だから、真似する&きっちり横展開することは大事
- → なので「きっちりパクる&マーケティングで競り勝つ」というスタイルを徹底し、成長し続けた。
ユーザーの求める価値の変化
pairsリリース前と今と比べると、自社の状況も、市場の環境も変わっている。それに応じてユーザーの求める価値も変化しているので、それに合わせてpairsは進化していく。
- pairsリリース前
- 出会いアプリが当たり前じゃない&先行サービス多数だった
- なので、「選べる・高くない・気軽・安心」を主要な提供価値に据え、他社を模倣しつつ成長してきた。
- 今のpairs: 出会いアプリが当たり前になってきた&日本でNo.1アプリになった
- No.1なのでデータをたくさん持っている
- なので、強みを活かし、(競合を見るのではなく)ユーザーの価値観の変化を吸収しながら今後成長していく。
- 具体的には、選択肢が多すぎて選べない悩みをレコメンドで解決するなど
pixiv清水さん
講演資料
ざっくりまとめ
女子高生VTuberが男性の声で喋ってて最初はぎょっとしたけど、発表聞いてるうちに慣れてきて、人間の適応能力ってすごいね、っていうことを再認識したセッション(違)。
最初はなんじゃこりゃと思ったけど笑、ドメインにコミットする大切さと、清水さんご自身のドメインへの愛情が伝わってくるいい話でした。
「未来にあって当たり前のものを作る」
プロダクトを作るとは「未来にあって当たり前のものを作る」こと。「あって当たり前だけど今はまだない=穴がぽっかり空いているところ」を埋めていく。
穴の形は多種多様なので正確に把握していないとうまく埋められない。でも、穴は星の数ほどたくさんある。なので、近づいて範囲を絞ってどんな穴なのかを把握しないといけない。なので、ドメインを絞り込めば詳細を見よう。
そのためには、特定領域のプロフェッショナルになることが重要。誰よりもその領域について理解できていると、誰よりも一歩先を歩み続けることが出来る。
ただし、ドメインを絞り込むことと視野を狭めることは違う。特定の領域のみ見続けているだけでは埋めるべき穴を見誤る。埋めるべき穴は時代の変化とともに変わっていくのでそれを見落とさないようにしよう。(例: スマホの普及前と普及後)
愛を持って特定領域にコミットすること
ドメインにコミットし続けると愛着が湧いてくるし、その愛着はユーザーにも伝わる。その結果、ユーザーとのエンゲージメントも高まる。ぜひ、愛を持って特定領域にコミットしよう。
余談
シンプルすぎる感想で笑ってしまったw
#pmconfjp Pixivさんの穴のメタファーはわかりやすいのだけど、終わった後に「美少女が穴について話していた」という記憶しか残らない不安がある(いや、大丈夫
— 及川卓也 / Takuya Oikawa (@takoratta) 2018年11月6日
ZOZO金山さん
講演資料
ざっくりまとめ
Vasilyがスタートトゥデイ(現: ZOZO)にMAされ、金山さんがスタートトゥデイテクノロジーズ(現: ZOZO Technologies)を急速に立ち上げされたときの組織づくりの話。オンボーディングを大変重視し、全力でコミットして行っているというのが素晴らしいと感銘を受けたセッションでした。
ちなみに登場が特徴的だった金山さん。Twitterや本しか拝見したことなかったので、こんなお茶目な方とは思っていなくて、その意味でも感銘を受けました笑。
ZOZO金山さん、発表冒頭壇上にいなくて「VTuberに対抗する」って宣言して登場されたので、まさかZOZOスーツで来るのか?!かと思ったけど普通の登場だった笑。 #pmconfjp
— ıɥɔɔn (@naotaka1128) 2018年11月6日
オンボーディングこそ全て
人材、特にPMにおいては入社3-6ヶ月のオンボーディングのプロセスが最も大事。(誰をバスに乗せるかが重要なのは前提)
「活躍して初めて入社」ぐらいのマインドで部門のマネージャーが成果にコミットして並走する必要がある。PMは以下の要因で「愛され」なくなることも往々にしてあるので、「愛され」はじめることがとにかく重要。
- PMのしごとは成果でしか見えることが出来ない
- 意思決定や部門間調整が多く仕事を指定内容に見えちゃう
- 上流の業務にいたり頻繁な意思決定の変更が多いので警戒されやすい
「花を持たす」
具体的にZOZOテクノロジーズでのオンボーディングは、以下の3STEPを経て「花を持たす」ことを徹底して行っている。
- 入社前にトップ-PM間で入社3ヶ月以内に達成する成果を明確にする
- トップがその成果にコミットし達成する
- 成果を社内に大きくアナウンスする
これをやるかやらないかで全然愛され方が違うはず。だから、今も昔もとにかくオンボーディングを重視している。
2日目(11/07)
folio 甲斐さん
講演資料
(資料公開なさそう?)
ざっくりまとめ
金融業界のPMは攻めと守りの天秤を取る必要があるのでとにかく大変、というのが自分の現職の体験にも通じることがあり、とても刺さったセッションでした。
folioの今と昔
folio開発は3ヶ月ぐらいでiPhoneアプリを出すつもりが、気がつくと2年かかって新しいiPhoneを製造していたイメージとのこと。(言い得て妙だ…。)
folioの単一プロダクト時代はそんなに論点はなかったが、ロボアドとLINEスマート投資という2つの新しいプロダクトをだしたら一気に複雑性が増した。今は、理想と現実のバランスを取りながら組織体制を考えている。
- 理想
- 現実
- 単一バックログ/フロント&バックエンド密結合/兼務によるリソース取り合い
- ビジネスKPI以外も重視する必要あり→複雑な優先順位になる
- 複雑性によるオーナーシップの不明瞭さ
MoneyFoward 今井さん
講演資料
(資料公開なさそう?)
愛をお金に変えよう
マネフォ今井さん
— ıɥɔɔn (@naotaka1128) 2018年11月7日
・愛をお金に変えよう: 元Apple社員だから知ってるんだけど iPhone(iPad)のアクセサリーは死ぬほど儲かるよ。だから僕純正アクセサリー買いません笑。あ、これはiPhoneが愛されてるからこそアクセサリーも売れるっていう例だから怒らないでね笑。#pmconfjp
SaaSをやるなら日本はいい環境だよ
マネフォ今井さん(続き)
— ıɥɔɔn (@naotaka1128) 2018年11月7日
・SaaSをやるなら日本はいい環境だよ: 競合が少ない(USの1/10程度)し、単一民族のわりに人口多いから。でも、まぁ楽勝ってわけでもなくて、日本も広いので努力は必要だよ。鹿児島にとっておきの話を持っていったが全然刺さらなかったこともある。#pmconfjp
今半弁当
2日目のご飯は僕が大好きな今半のお弁当だった!
2日目は今半弁当だー! #pmconfjp pic.twitter.com/eomZJVVvKQ
— ıɥɔɔn (@naotaka1128) 2018年11月7日
SmartNews 宮田さん
講演資料
海外のPM系カンファレンスが勉強になった話
スマニュー宮田さん: 「会社の海外渡航制度を使って海外のPM系のカンファレンスやコースに行ってみた」とのこと。北米「PM Bootcamp by General Assembly」、アジア「PM Festival」、欧州「Turning Fest」など全然知らないカンファレンスばかりで勉強になった。#pmconfjp
— ıɥɔɔn (@naotaka1128) 2018年11月7日
北米: PM Bootcamp by General Assembly
— ıɥɔɔn (@naotaka1128) 2018年11月7日
・参加者: 北米では「ロジカルシンキング ≒ プロダクトマネジメント」ぐらいの普及度があるためか、未経験の人もガンガン来てて驚いた。
・内容: ベーシックなPM論が多いそう。General AssemblyはPM以外にData Scienceなど様々なコースをやってる#pmconfjp
アジア: PM Festival
— ıɥɔɔn (@naotaka1128) 2018年11月7日
・参加者: GAFA系とベンチャーが半々ぐらいで、すでに経験されてる方が多い。
・内容: 「PMの責任と役割」的な話が多い
欧州: Turning Fest
・参加者: 2000人ぐらい / ほぼEuro / 40歳前後
・内容: PMを中心にしつつ開発、マーケ、グロース、文化組織なども絡めて解説#pmconfjp
おまけ
2日とも、夜ごはんは「カラシビ」(辛さと痺れ)を食べることが出来て幸せでした。 秋葉原周辺最高!
1日めの夜ごはん
pmconfjp1日目の晩ごはん pic.twitter.com/Jv1OYAIBqQ
— ıɥɔɔn (@naotaka1128) 2018年11月7日
2日めの夜ごはん
そしてこれがpmconfjp2日目の晩ごはん pic.twitter.com/FFtOSt87b8
— ıɥɔɔn (@naotaka1128) 2018年11月7日