Kaggle編・卒業回 ― 公開コードを「自分の問い」に作り替え、PRMLを開く
連載の集大成。公開ノートを実務テンプレに翻訳する手順(データの取り決め・リーク監査・CV設計・指標の意思決定接続・運用)を1枚に畳み、架空企業SOLNAの案件で一本通します。最後にPRMLの読書地図(章×連載の対応回)と、足すべき数学(線形代数・確率・最適化)の最小教材を渡します。
by Shin
公開ノートを自分の業務に移し、その先のPRMLへ進むには、何を、どの順でやればいいのか。答えは、移植を5ステップ(データの取り決め → リーク監査 → CV設計 → 指標の意思決定接続 → 運用)に畳み、章×回の地図でPRMLを開くこと、です。この回では、連載で解剖してきたものを1枚のテンプレートにまとめ、過去の受託案件をもとに設計した架空企業SOLNAのChurn予測で一本通したうえで、PRML読書地図と数学の最小補強リストを渡します。
ここまでの各回が「一つのブロックの解剖」だったのに対し、卒業回の仕事は接続です。個々の手法ではなく、公開ノートを自分の問いに作り替える手順そのものを、自分で回せる形にして持ち帰ってもらいます。
公開ノート → 実務テンプレへの翻訳手順(5ステップ)
公開Notebookは「固定された綺麗なデータ」を前提に最短で精度を出すよう書かれています。実務データは動き、汚れ、遅れて届きます。だから写経では事故ります。翻訳とは、ノートの各ブロックに「自社では何が前提か」を上書きしていく作業です。5ステップで畳みます。
1. データの取り決め(入力の前提・更新頻度・供給遅延)
最初に問うのは精度ではなく、入力が「いつ・どの粒度で・どれだけ遅れて」手に入るか、です。公開コンペは全特徴量が予測時点で揃っている前提ですが、実務では予測したい瞬間にまだ確定していない値が混ざります。たとえば「初月の累計購入額」は、初月が終わるまで確定しません。これを学習特徴量に入れると、本番では存在しない情報で訓練したことになり、オフラインだけ強いモデルが生まれます。
データの取り決め(data contract)とは、各特徴量について「予測時点で観測済みか」「更新頻度はどれくらいか」「供給が遅延しうるか」を明文化することです。ここが曖昧なまま下流に進むと、後段のリーク監査もCV設計も砂上の楼閣になります。
2. リーク監査(前処理・時間・グループ)
リークは3種類を機械的に潰します。第2回・第5回で個別に見たものを、ここでチェックリストにします。
| リークの型 | 典型的な事故 | 対処 |
|---|---|---|
| 前処理リーク | 全データで欠損補完・標準化・target encodingをしてから分割 | foldの内側で fit、外側で transform(Pipelineで閉じる) |
| 時間リーク | 未来の行で学習し過去を予測(ランダムKFold) | 時間で切る(TimeSeriesSplit/時点カット) |
| グループリーク | 同一顧客が訓練と検証の両方に出現 | GroupKFoldで顧客IDを分離 |
3. CV設計(課題構造に合わせる)
交差検証は「本番で起きる分割」を訓練の中で再現する装置です。だから課題構造で選び方が変わります。不均衡なら層化(StratifiedKFold)、顧客単位で予測するなら GroupKFold、未来を予測するなら TimeSeriesSplit。SOLNAのChurnは「ある時点までの履歴で、その先の解約を予測する」ので、時間で切るのが原則です。ランダムKFoldは数字が良く出ますが、それは未来を覗き見た数字です。
4. 指標の意思決定接続(何を動かすか)
第7回の主題を、ここでテンプレに固定します。指標は「何を最適化するか」の宣言であって、現場の意思決定を良くするとは限りません。精度が高いことと役に立つことは別です。AUC(予測の順位付けの良さを測る指標。当てずっぽうで0.5)が0.85でも、それが「誰に通知を打つか」「どの順で営業が当たるか」に翻訳されなければ、現場は1ミリも動きません。テンプレでは、モデル出力(確率)→ 較正(予測確率を実際の発生率に合わせる)→ ビジネス閾値 → 打つ/打たない、までを1セットで設計します。
5. 運用(再学習・監視)
コンペはデータが固定なので運用がありません。実務はここからが本番です。コンペで効くことと実務で効くことが別になる最大の理由が、この分布シフトです。入力分布が動けば精度は静かに劣化します。監視すべきは、特徴量分布のドリフト、予測分布の変化、そして実際の成果との乖離です。再学習トリガ(定期 or ドリフト検知)を最初に決めておきます。
写経から設計へ ― SOLNAで一本通す
5ステップを実装の最小構成に落とします。まず、公開Playgroundの典型ノートは概ね次の形です(他者のNotebookは貼らず、構造だけ自前で最小再実装します)。
# 公開ノートの典型骨格(最短で精度を出す前提・実務にはそのまま使えない)
import pandas as pd
from sklearn.model_selection import StratifiedKFold
from lightgbm import LGBMClassifier
df = pd.read_csv("train.csv")
X, y = df.drop(columns=["target"]), df["target"]
# 事故ポイント: 全データで前処理してから分割している
X = X.fillna(X.mean()) # 前処理リーク
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42) # 時間構造を無視
# 以降 fit → predict → submitこれを「データの取り決め → リーク監査 → CV設計」を通したSOLNA版に翻訳します。顧客の履歴をある基準時点 T で切り、T 以前の行動だけで特徴量を作り、T 以後の解約を予測します。
# SOLNA版: 基準時点Tで履歴を切り、前処理をfoldの内側に閉じる
import pandas as pd
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer
from sklearn.model_selection import TimeSeriesSplit
from lightgbm import LGBMClassifier
CUTOFF = pd.Timestamp("2026-03-31") # データの取り決め: この時点で観測可能な情報のみ使う
# 特徴量はCUTOFF以前のイベントだけから作る(供給遅延・未来情報を遮断)
orders_hist = orders[orders["order_at"] <= CUTOFF]
sessions_hist = sessions[sessions["session_start"] <= CUTOFF]
features = build_features(customers, orders_hist, sessions_hist) # 累計購入・直近来訪など
# ラベル: CUTOFF以後の一定期間で churned_flag が立つか
labels = make_churn_label(subscriptions, cutoff=CUTOFF, horizon_days=90)
X = features.merge(labels, on="customer_id")
y = X.pop("churned_within_horizon")
X = X.sort_values("first_order_at") # 時間順に並べる
# 前処理をPipelineに閉じ込め、foldの内側でだけfitする(前処理リークの遮断)
model = Pipeline([
("impute", SimpleImputer(strategy="median")),
("clf", LGBMClassifier(random_state=42)),
])
cv = TimeSeriesSplit(n_splits=5) # ランダムでなく時間で切る
# for tr, va in cv.split(X): model.fit(X.iloc[tr], y.iloc[tr]) ...ここで効いているのは新しい手法ではなく、順序です。同じLightGBMでも、基準時点を切らずランダムKFoldで回せばスコアは上がり、本番で崩れます。コンペの綺麗なデータでは見えない非対称が、ここに全部出ます。
最後に、出力を意思決定と運用へ接続します。較正した確率を業務閾値に翻訳し、再学習トリガまでを1つの関数に畳みます。
# 指標の意思決定接続 + 運用トリガ(最小構成)
from sklearn.calibration import CalibratedClassifierCV
# 1. 確率を較正してから閾値を当てる(未加工のスコアの大小は確率ではない)
calibrated = CalibratedClassifierCV(model, method="isotonic", cv=cv)
proba = calibrated.predict_proba(X_new)[:, 1]
# 2. 閾値は精度でなく「営業が当たれる件数」から逆算する
THRESHOLD = pick_threshold(proba, capacity=営業が週に当たれる件数)
to_contact = X_new.loc[proba >= THRESHOLD, "customer_id"]
# 3. 運用: 入力分布のドリフトを監視し、閾値超過で再学習をトリガ
if population_stability_index(X_train, X_new) > 0.2: # 分布シフトの検知
trigger_retraining()この3ブロックが、連載全回の到達点です。読み込み・前処理・CV・モデル・評価・重要度・提出という公開ノートの8ブロック(第1回)が、データの取り決め・リーク監査・CV設計・意思決定接続・運用という実務の5ステップに作り替わりました。
PRML読書地図(章 × 本連載の対応回)
ここからは数学の本丸です。PRMLは独学で挫折しやすい本ですが、各章が連載のどの回の土台にあたるかが分かれば、開く順番に意味が出ます。連載で直感とコードを作ってから対応章を開く、という使い方を推奨します。
| PRMLの章・節 | 主題 | 対応回 |
|---|---|---|
| 1.1 多項式フィットと過学習 | 過学習・モデル複雑度 | 第5回 |
| 1.2 確率論/最尤 | 尤度・MLEの発想 | 第4回 |
| 1.3 モデル選択 | 複雑度とチューニング | 第8回 |
| 1.5 決定理論 | 損失と決定の分離 | 第7回 |
| 2章 確率分布 | 分布・前処理の前提 | 第2回 |
| 3章 線形回帰モデル | 最小二乗・正則化・ベイズ線形回帰 | 第3回・第5回 |
| 4章 線形識別モデル | ロジスティック回帰 | 第4回 |
| 14章 結合モデル | アンサンブル | 第6回 |
GBDTそのものはPRML本体にはありません。けれど「損失の勾配方向に弱学習器を足す=関数空間の最適化」という第6回の見方は、最適化とアンサンブル(14章)の延長として位置づけられます。手法カタログではなく地図として読む、という連載の姿勢を、ここでも保ちます。
そのために足す数学(線形代数・確率・最適化)の最小教材
PRMLを読むのに足りない数学は、深追いせず最小構成で補います。連載の y = Xw を行列で読めた人(第3回)なら、追加で要るのは固有値まわりです。
- 線形代数: 入口は『キーポイント 線形代数』、固有値・固有ベクトル(PCAやカーネルで主役になる)は『線形代数と固有値問題』。この2冊で、PRMLの行列計算で詰まる箇所はだいたい戻れます。
- 確率: 独立した確率本は置かず、『統計学入門』(赤本)で賄います。3級の素地から、PRML 2章の前提(期待値・分散・条件付き確率)まではここで届きます。
- 最適化: 第4回の勾配降下の直感があれば当面は足ります。理論側を固めたい場合のみ任意で補強する、くらいの優先度で構いません。
ベイズ的な見方(第5回の「正則化=MAP」、第8回のベイズ最適化)をPRMLのベイズ章へ繋ぐ足場は、この連載ですでに直感として置いてあります。あとは上の章×回マップをたどって、PRMLの3章(ベイズ線形回帰)を開くのが近道です。
卒業チェックリスト
連載全体の到達確認です。すべて自分の言葉で言えれば、写経の段階は卒業です。
- 公開ノートを「データの取り決め → リーク監査 → CV設計 → 意思決定接続 → 運用」の5ステップで自社案件に移植できる
- 前処理・時間・グループの3リークを機械的に点検できる
- 課題構造(不均衡・グループ・時系列)に合わせてCVを選べる
- 確率を較正し、精度ではなく業務制約から閾値を決められる
- 分布シフトとフィードバックループを前提に運用設計できる
- PRMLを章ごとに連載の回と対応づけて開ける
- 不足する数学(線形代数・確率)の補強計画を立てた
最後に、連載を貫いた3つの誤解をもう一度置いておきます。精度が高い ≠ 役に立つ/重要度が高い ≠ 因果がある/コンペで効く ≠ 実務で効く。この3つを毎回自分のコードに問えるようになったなら、もう公開ノートは「写すもの」ではなく「読んで作り替えるもの」になっています。
PRMLへの一歩
ここで連載は地図を渡し終えます。次の一歩は、読者(と筆者自身)がPRMLを実際に開くことです。上の章×回マップを手元に置き、まず3章・4章・1.5から。詰まったら連載の対応回に戻り、直感を作り直してまた章へ戻る——この往復が、独学でPRMLを完走する現実的な道筋です。
章末チェックリスト
- 公開ノートを5ステップで自社案件に移植できる
- リーク監査を一通り回せる
- PRMLを章ごとに連載の回と対応づけて開ける
- 不足する数学の補強計画を立てた
送り出し
実装はここまでです。「自社で何が成立し、何をやらないか」という判断は記述・予測編へ。そして、Churnモデルの重要度を「施策仮説」に翻訳する場面では、重要度が高いこと(予測に効くこと)と因果があることは別です。「誰に介入すれば解約を止められるか」は予測ではなく因果の問いなので、その検証は因果編に譲ります。そしてここから先は、PRMLを開く番です。