kaggle本で参考になった点のなぐり書き - ML_BearのKaggleな日常

ML_BearのKaggleな日常

元WEBマーケターのMLエンジニアがKaggleに挑戦する日々を綴ります

kaggle本で参考になった点のなぐり書き

これはなに?

  • kaggle本を読んで血肉になった/したい点をなぐり書きにしたただの個人用メモです。ちゃんとした書評を書こうと思い続けてはや半月以上経過したので一旦書きました。
  • この箇条書きの記事だけ読んでも多分内容わからないと思うので、気になった点があればぜひ購入しましょう!読後すぐに書いた推薦ツイートは以下のとおりです。

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的な発想とか身近に合ってわかりやすいし、なるほどなーと。
  • ユーザーIDごとの集約統計量など
    • P153-170あたりはカンペとして壁に貼っておきたいレベル
    • 個人用メモには全部転記したけど、ブログに全部書くのは気がひけるので見出しだけ
      • 単純統計量
        • 単純カウント
        • ユニーク数のカウント
        • 存在するかどうか
        • 合計・平均・割合
        • MAX・MIN・STD・MEDIAN・PERCENTILE・Kurtosis・Skewnness
      • 時間的な統計量
        • 直近や最初のレコードの情報
        • 間隔・頻度
        • 重要イベントからの間隔・次のレコードの情報
        • 順序・推移・共起・連続
      • 条件を絞る
        • 特定の種類のログに絞る
        • 集計対象の時間、期間を絞る
      • ラグ特徴量
  • testの期間に合わせて使うデータ期間も調整
    • テストデータが1ヶ月分
      • 前後半(orそれ以上)に分けてモデルを作るというアイディアがある
        • Corporacion Faborita Grocery / Recruit Restaurant Visitor など
      • テストデータ後半は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本の超縮小版みたいな記事を書いてたので、よかったら参考にしてください。

naotaka1128.hatenadiary.jp