6
3

More than 1 year has passed since last update.

ホールドアウト法と交差検証法をまとめてみた

Last updated at Posted at 2022-11-07

はじめに

今回、機械学習のモデル検証方法であるホールドアウト法交差検証法を簡単にまとめた。

前提知識としてモデルやハイパーパラメータの概要があることが望ましい。

ただ、なくても概念は理解できるように努めたため、理解いただければ幸いである。

目次

1.モデル検証とは
2.ホールドアウト法
3.交差検証法
3-1.k分割交差検証
3-2.leave-one-out(1個抜き)交差検証
3-3.層化交差検証
3-4.その他の交差検証
4.まとめ

1.モデル検証とは

機械学習のなかでも教師あり学習において、未知のデータに対する予測を高い精度で行うことが求められている。
そのため、既知のデータを用いて未知のデータを予測するような仕組みを作ることとなる。
このような、入力データに対してある結果(出力)を導き出す仕組みをモデルと呼ぶ。
また、モデルの仕組みの中で性能を高めるために、自由に調節できる要素のことをハイパーパラメータと呼ぶ。

そして、モデルを作成した際にそのモデルが未知データに対しての予測性能を測ることをモデル検証と呼ぶ。

無題のスプレッドシート.jpg図1

上記のカラオケの例だと概念をつかみやすいのではないだろうか。
さらに
image.png図2

ハイパーパラメータが音量やエコー調節のつまみとすれば、概念として理解しやすいのではないかと提案する。
カラオケ機器が正確に音程を理解し元の楽曲(正解)の一致具合を点数化することをモデル検証という。

ここで、既知のデータをもとにモデルを作成するため既知データに依存してしまい、未知のデータに対する性能(汎化性能)が著しく低下する可能性がある。
この問題を解決する手法を次項以降で紹介していく。

2.ホールドアウト法

機械学習において未知なるデータを予測するモデルを作成し、そのモデルの汎化性能(予測性能)を測る方法の一つとして、ホールドアウト法がある。

image.png図3

元データをデータセットとして以下の流れでモデル検証を行う。

1.データセットを学習データとテストデータに分ける
2.学習データを学習データと検証データに分ける
3.学習データと検証データから予測モデルを作成する
4.予測モデルの評価をテストデータを用いて行う
※データ分割方法は諸説あり。学習データ:テストデータ(検証データ)=7:3or8:2等

以上のようなモデル検証法では「データの偏りに弱い」という弱点がある。
分割したデータの片方に特徴的なデータが集まることで、汎化性能が著しく下がる可能性が発生する。
その弱点を解消するために次項の交差検証法がある。

3.交差検証法

学習データを2分割してモデル検証をしたホールドアウト法に対して、交差検証法は3分割以上してモデル検証を行う。

無題のスプレッドシート.png図4

図6の方法によりホールドアウト法の弱点を克服することができ、汎化性能が向上する。
交差検証法には種類があることから、いくつか紹介していく。

3-1.k分割交差検証

交差分割検証の中でもk個に学習データを分割し、そのうちの一つを検証データ、残りのk-1個を学習データとして精度を算出し、その平均をとって評価する方法である。

無題のスプレッドシート (1).png図5

流れとしては

1.学習データをk個に分割する
2.1つのデータを検証データ、残りのk-1個を学習データしてモデル精度を算出
3.1と2をk回繰り返す
4.出てきた精度の平均をとることでモデル評価する

以上となる。

特徴として学習データのすべてが検証データになることから、データの偏りによる汎化性能の低下が回避される。

コード例


import numpy as np
from sklearn.model_selection import KFold

X = ["a", "b", "c", "d","e","f","g","h","i","j","k","l"]

kf = KFold(n_splits=4,shuffle=True)

for train, test in kf.split(X):
    print("%s %s" % (train, test))

出力結果
[ 0 1 2 3 4 7 9 10 11] [5 6 8]
[0 1 2 3 5 6 7 8 9] [ 4 10 11]
[ 0 3 4 5 6 7 8 10 11] [1 2 9]
[ 1 2 4 5 6 8 9 10 11] [0 3 7]

3-2.leave-one-out(1個抜き)交差検証

k分割交差検証の派生としてleave-one-out(1個抜き)交差検証があげられ、これはk分割交差検証では学習不足に陥ってしまう場合に使用される方法である。
データの分割をデータの個数(n)分割することによって学習不足を回避し、少ないデータ数であっても計3回数を増やすことを可能にした。

無題のスプレッドシート (2).png図6

流れとして

1.学習データをn個に分割する
2.1つのデータを検証データ、残りのn-1個を学習データしてモデル精度を算出
3.1と2をn回繰り返す
4.出てきた精度の平均をとることでモデル評価する

以上となる。

特徴として過学習の回避にはつながるものの、逆に過学習(既知のデータに過剰に適合してしまうこと)になる可能性が高くなるとともに、計算コストが増大することがあげられる。

コード例


from sklearn.model_selection import LeaveOneOut

X = [1, 2, 3, 4]
loo = LeaveOneOut()
for train, test in loo.split(X):
    print("%s %s" % (train, test))

出力結果
[1 2 3] [0]
[0 2 3] [1]
[0 1 3] [2]
[0 1 2] [3]

3-3.層化k分割交差検証

k分割交差検証の派生として層化k分割交差検証があげられ、これは分類課題において目的変数(分類クラス)のデータにおける比率が偏っている場合に使用される方法である。
データの分割方法を分類クラスの比率に合わせて分割する方法をとるため、クラス比率が偏っている場合に有効な検証方法となる。
無題のスプレッドシート (3).png図7

流れはほとんど同じであるため割愛する。

特徴としてすべてのデータ分割においてクラス比率が同じとなり、比率による精度の偏りを回避することがあげられる。データ抽出を層化抽出法を用いていることで上記の特徴を得られるため、詳しく調べたい方は上記のキーワードをもとに検索してみるとよい。

コード例


import numpy as np
from sklearn.model_selection import StratifiedKFold

X = np.ones(12)
y = [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1]

skf = StratifiedKFold(n_splits=4)

for train, test in skf.split(X, y):
    print("%s %s" % (train, test))

出力結果
[ 1 2 3 6 7 8 9 10 11] [0 4 5]
[ 0 2 3 4 5 8 9 10 11] [1 6 7]
[ 0 1 3 4 5 6 7 10 11] [2 8 9]
[0 1 2 4 5 6 7 8 9] [ 3 10 11]

3-4.その他の交差検証

他にも状況に応じた交差検証があることから紹介だけしておく。

シャッフル分割交差検証
データを分割する前にシャッフルしてからk分割交差検証を行う。

層化シャッフル分割交差検証
層化抽出法を用いてデータを抽出し、その抽出したクラス内でシャッフルを行いk分割交差検証を行う。

グループk分割交差検証
同じグループ(顧客等の特定の人物を表すもの)が同じになるように、データを分割するk分割交差検証のこと。

以上の交差検証は、これだけの紹介にとどめる。

4.まとめ

今回の学習を通じてモデル検証という、作成したモデルの検証方法の考え方や方法を学べたと思う。それを共有できればと思い寄稿した。
実際のコード例も小規模データを作成し掲載できたので、活用方法も示すことができたのではないかと思う。
今回は私自身も初学者のため、図を多く用いて抽象的になったかもしれない。
今後の反省として次回以降の記事に生かしていきたい。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3