機械学習

交差検証(Cross Validation)で過学習を抑える

本日は過学習を防ぐ上で欠かせない交差検証についてまとめていきます。

交差検証(Cross Validation)は何故行うのか?

モデルの評価を行う際、基本的なやり方としては全体のデータを訓練データとテストデータに分割し、訓練データを用いてモデルを作成後、テストデータでそのモデルの性能評価を行います。

pythonの場合train_test_split関数がsklearnにあり、これを用いることで訓練データとテストデータをそれぞれ75%と25%にランダムに分割することができます(任意の値に設定できます)

しかし、この方法だと訓練データとテストデータで異なる性質のものが偏って分割された場合に当然テストデータのスコアが上がりません。

yaaku

分布が異なるデータで機械学習は難しい…

 

そこで交差検証(Cross Validation)と呼ばれるより保守的な訓練データとテストデータの分割手法があり、今回はメジャーな3つに関して簡単にまとめていきます。

・k-分割交差検証(k-fold cross-validation)

・層化k分割交差検証(stratified k-fold cross-validation)

・グループ付き交差検証(GroupKFold)

k分割交差検証(k-fold cross-validation)

k分割交差検証はよく用いられる分割方法で、データセットを任意の数k個に分割します。

分割されたデータをさらにk等分して、1/k個のデータをテストデータ、残りの(1-1/k)を訓練データとして予測を行います。

分割(splits)の個数に対してそれぞれモデルを作成してテストデータに対して予測をしていきます。

KFoldでは全てのデータが正確に1度だけテストに用いられるようになるため、訓練データ全体のスコアを算出することができ(OOF:Out Of Fold)、それをモデルの性能とみなす考え方と、各Fold毎のテストデータで評価指標を計算し平均を取ることでそのモデルの性能とする考え方があります。

分類問題でAUCを用いた場合、各Foldでの予測値は順番が正しくなるように予測値を算出するため異なるモデル(各Fold毎)の出力値を合体させてOOFを作成して計算しても正しく評価できない場合があります(各モデルの出力値が相対的ではないため)。

層化k分割検証(stratified k-fold cross-validation)

次に層化k分割検証(k-stratified)ですが、先ほど紹介したKFoldでは分割によって不均衡になった場合に精度が中々出ないことが問題となるケースがあります。

例えばクラス分類でデータが次のように偏っている場合、

これでシャッフルなしでKFoldで学習させたら上手くいかないのはイメージができます。

そこで層化k分割交差検証では各分割内でクラスの比率が同じようになるように分割を行います。

こうすることで訓練データとテストデータのラベルの分布が同等になるため、先ほどのirisのようにデータを分けた際にあるクラスが異常に偏っているという状況を避けることができます。

実装は下記のようになり、KFoldとほとんど同じになります。

グループ付き交差検証(GroupKFold)

最後にグループ付き交差検証ですが、これはデータの中に密接に関係するグループがある場合に用いられます。

例えば顔の画像から感情を予測しようとするときに、同じ人の笑ってる顔と泣いている顔がテストデータと訓練データに入っていたとすると、別々の人の感情認識より楽になってしまいます。

この場合、将来得られるデータに学習時に用いられた人と同一人物が含まれる可能性が大きい場合はテストデータと訓練データに同一の人が含まれていても問題ないケースもありますが、感情推定などは恐らく学習時に使用したデータと異なる人の推定になる場合が多いと思われるのでそのような場合はGroupKFoldを検討すべきだと考えられます。

またkaggleでは月単位でGroupKFoldを行うことで、新しい月に対する汎化性能を向上させるValidationが行われていました。

実装は下記のようにsplit_groupsにグループの変数を指定します(ex, 被験者IDなど)

まとめ

kaggleでは最初から訓練データとテストデータが分けて与えられており、交差検証を行うのは訓練データに対してとなります。

つまり最初から与えられている訓練データとテストデータの関係性を分析して、なるべくその関係性を再現できるように訓練データでValidationを設計します。

特に時系列性が強い問題などはValidationの取り方次第で勝負が決まることもあるので、色んなコンペに参加してどのような問題設計でも適切にvalidationを取れるよう力を付けていきたいですね。