03.1.1 高校生向け
交差検証(高校生向け)
こんな場面を想像してみよう #
定期テストの対策に過去問 100 問を解いて覚え、そのあと同じ 100 問でテストをしたら 100 点でした。これは実力でしょうか。答えを覚えただけかもしれません。実力は、まだ見たことのない問題(残りの 20 問など)で測る必要があります。
そこで 100 問のうち 80 問だけで勉強し、残り 20 問を初見のテストにします。これが機械学習の「訓練データと検証データに分ける」(ホールドアウト)です。ただしどの 20 問を残すかで点数は変わります。得意な分野の 20 問が残れば高く、苦手な分野が残れば低く出ます。1 回の分け方に頼らず、分け直して平均をとろう、というのが交差検証です。
仕組み:検証用のブロックを順番にずらす #
5 分割交差検証の流れを表にします。
| 回 | ブロック 1 | ブロック 2 | ブロック 3 | ブロック 4 | ブロック 5 | 成績 |
|---|---|---|---|---|---|---|
| 1 | 検証 | 学習 | 学習 | 学習 | 学習 | 0.82 |
| 2 | 学習 | 検証 | 学習 | 学習 | 学習 | 0.86 |
| 3 | 学習 | 学習 | 検証 | 学習 | 学習 | 0.79 |
| 4 | 学習 | 学習 | 学習 | 検証 | 学習 | 0.88 |
| 5 | 学習 | 学習 | 学習 | 学習 | 検証 | 0.85 |
まず、データの順番をよく混ぜてから、同じ大きさの \(k\) 個のブロックに切ります。次に、ブロック 1 を検証用にしまい、ブロック 2〜5 でモデルを作ります。表の 1 行目です。そのモデルにブロック 1 のデータを初見の問題として解かせ、正解率や誤差を記録します。続いて表の「検証」のマスを 1 つ右へ移動し、そのたびにモデルをゼロから作り直して測ります。これを \(k\) 回くり返すと、どのデータもちょうど 1 回だけ検証用になります。最後に \(k\) 個の成績の平均とばらつきを見ます。上の例なら平均は 0.84、最低と最高の差は 0.09 で、1 回だけのホールドアウトなら 0.79 と出ることも 0.88 と出ることもあった、と分かります。
\(k\) を変えると何が変わるか:\(k = 5\) なら毎回 80% で学習し 20% で検証、\(k = 10\) なら 90% で学習し 10% で検証です。\(k\) を大きくするほど学習に使えるデータは増えますが、1 回あたりの検証データが減って成績がばらつき、モデルを作る回数も \(k\) 倍になります。
動かして見てみよう #
下の図で「再生」を押すと、説明した手順が 1 つずつ進みます。手順ごとの説明は図の下に出ます。
気をつけたいこと #
最初の注意は、検証データで何度も調整すると、検証データにも「慣れて」しまうことです。成績を見ながら設定を何十回も変えると、検証データに合わせ込んだことになるので、最終確認用のデータは別に取り分けておきます。二つ目は、偏ったクラスはブロックごとの比率をそろえることです。陽性が 5% しかないデータを適当に分けると、陽性が 1 件も入らないブロックができることがあるので、各ブロックの比率を元データと同じにする分け方(層化)を使います。三つ目は、時間の順番があるデータは混ぜてはいけないことです。混ぜると未来で学習して過去を当てる不正が起きるので、過去のデータで学習し未来のデータで検証する分け方(TimeSeriesSplit)にします。
やってみよう #
最初の課題は、1〜20 の番号を書いたカードをよく混ぜ、4 枚ずつ 5 つの山に分けて、「山 1 を検証用」から「山 5 を検証用」まで表に書き出し、どのカードもちょうど 1 回だけ検証用になることを確かめることです。二つ目は、「全部覚えたのに本番で解けなかった」経験を思い出し、それが過学習とどう似ているか、交差検証に当たる勉強法は何かを考えることです。三つ目は、上の表の成績が 0.60, 0.95, 0.70, 0.98, 0.65 だったとき、平均は同じ 0.78 くらいでも何が心配か(標準偏差で言うと何が大きいか)を説明することです。
つぎに読む #
scikit-learn の cross_validate を使った実装、ホールドアウトとの数値比較、分割の設計は 標準版の交差検証 で扱っています。各ブロックのクラス比率をそろえる分け方は 層化 k 分割交差検証 へ。交差検証で測る「成績」の中身は 分類の評価指標 と 回帰の評価指標、モデル選択の話題全体は モデル選択 にまとめています。