はじめに
機械学習において、モデルの汎化性能を測る方法に、クロスバリデーションやホールド・アウト法、リーブワンアウト法等があることは周知の事実かと思います。
しかし、これらの方法を単に訓練データとテストデータに分ける手法と勘違いしている言説を(私も含め)非常に多く見かけます。何なら書籍の中ですら、きちんと述べられていないことが多いです。
この記事では、
・k分割交差検証ってあるけど、k個のモデルのうち結局どれを最終的に使うの?
・k分割交差検証でなんで平均を取るのかわからん
・機械学習って訓練データとテストデータさえあればいいんでしょ?
といった疑問や勘違いを解消することを目標とします。
機械学習はテストデータと訓練データだけあればいいのか?
まず、モデルの汎化性能を評価するために、手持ちのデータをテストデータと訓練データに分けなければいけません。
これは確かに間違いではありません。
しかし、十分でもありません。
いま、とりあえずホールド・アウト法で訓練データとテストデータを分けたとします。
→そして、適当なハイパーパラメータで訓練データで学習を行い、テストデータでこのモデルの性能を評価します。
→いい感じだけど、別のパラメータでも試したいな。
→違う値ぶちこんだら性能上がりました、めでたしめでたし。
というのは間違いです。
なぜなら、この実験で分かったことは、ある訓練データによる「テストデータ」への当てはまりの良さを最適化するハイパーパラメータに過ぎないからです。
手持ちのデータを適当に分割した「テストデータ」に対しての当てはまりが良かっただけで、一般のデータに対する性能は保証されていません。従って、この方法では汎化性能を測ることはできません。
じゃあk分割交差検証をすればいいんじゃね
→手持ちのデータをk個のセグメントに分けて、、
→それぞれ異なるハイパーパラメータを設定してk個の異なるモデルを作って、、
→それぞれテストを行って、、
→平均を取ったよ、これが汎化性能やで、めでたしめでたし。
も間違いです。
この場合、異なるハイパーパラメータの組み合わせで作ったモデルの性能の平均は意味を持ちません。
また、k個のモデルのどれを選べばいいのか分かりません。
仮に精度が最もいいやつを選んだとて、他のデータも使って学習し直したら違う結果になることは明白です。
では、ホールド・アウト法やk分割交差検証って、結局どう使うのが正しいのでしょうか?
手持ちのデータを訓練データ、検証データ、テストデータに分ける
実は、手持ちのデータを訓練データとテストデータ分けるのがホールド・アウト法で、
訓練データを、訓練データと検証データに分けるのがホールド・アウト法、k分割交差検証、リーブワンアウトです。
先程はハイパーパラメータの探索にテストデータを使ってはいけないと書きました。
なぜなら、テストデータに最適化されたハイパーパラメータを探索することになるからです。
ではどうやってハイパーパラメータを探索すればいいのか。その答えが訓練データと検証データです。
まず、ホールド・アウト法で手持ちのデータと訓練データを分けます。
テストデータはまず置いておいて、次に訓練データをホールド・アウトなり、k分割交差検証なりで分けます。
| 訓練データ |テストデータ|
↓↓↓↓↓↓
| 訓練データ |検証データ|テストデータ|
そして、訓練データであるハイパーパラメータを試し、その性能を検証データで測れば、テストデータでどれくらいの汎化性能となるか検討をつけることができます(テストデータと訓練データが同じ分布に従うと仮定すれば)。
テストデータはあくまで、訓練データと検証データを使って見つけた最適なパラメータが、未知のデータ(一般データ)に対し、「本当に汎化性能を持つのか」評価するためだけにあるデータです。
注意
ここまでハイパーパラメータの探索は、手持ちのデータを訓練データ、検証データ、テストデータに分けて、訓練データとテストデータでイテレーションを回して最適(と思われる)組み合わせを見つけ、最後にテストデータで汎化性能を測る、と説明しました。
しかし、私が見る限り、「テストデータ」と「検証データ」に関してはかなり言葉の意味にゆらぎがあるように感じます。つまり、テストデータと検証データが、ここで述べた意味と反対になったりすることがある、ということです。(「評価データ」などと呼ばれることもあります。)
ですので、この点に関しては注意がいるかもしれません(ここまでに説明したことを頭に入れておけば文脈から推測できるとは思いますが)。
参考文献
Aurélien Géron (著), 下田 倫大 (監修), 長尾 高弘 (翻訳)「scikit-learnとTensorFlowによる実践機械学習」