深さ学習-データセットをトレーニングセットとテストセットに分割する方法

4726 ワード

質問:mm個のサンプルのみを含むデータセットD={(x 1,y 1),(x 2,y 2),⋯,(xm,ym)D={(x 1,y 1),(x 2,y 2),⋯,(xm,ym)について、DDからトレーニングセットSSとテストセットTTをどのように適切に処理し、DDから生成するか.
一般的な3つの方法を紹介します.
  • 残法
  • クロス検証法
  • セルフサービス法
  • 残留法(hold-out)


    残法は、データセットDDを直接2つの反発の集合に分割し、そのうちの1つの集合をトレーニングセットSSとし、残りの集合をテストセットTT、すなわちD=S∪T,S∩T=∅D=S∪T,S∩T=∅とする.モデルをSS上で訓練した後,その試験誤差をTTで評価し,汎化誤差の推定とした.二分類タスクを例として,DDが1000個のサンプルを含むと仮定し,7/3のサンプリングを行い,これをSSに分割して700個のサンプルを含み,TTは300個のサンプルを含む.
    S/TS/Tの区分はできるだけデータ分布の一致性(S/TS/Tのデータ分布はDDと同じ)を維持してこそ、データ区分過程に追加の偏差が導入され、最終結果に影響を及ぼすことを避けることができる.たとえば、分類タスクでは、少なくともサンプルのカテゴリスケールを類似させます.カテゴリスケールを保持するサンプリング方法、すなわち階層サンプリング(stratified sampling).例えば、DDには500個の正例、500個の反例が含まれており、階層サンプリングを用いて70%のサンプルのトレーニングセットSSと30%の偽物のテストセットTTを取得すると、SSは350個の正例と350個の反例、TTは150個の正例と150個の反例を含む.
    サンプルの割合が与えられ、DDを分割する様々な分割方式がある.上記の例では、DDのサンプルを並べ替えて、前350個の正例をSSに入れてもいいし、後350個の正例をSSに入れてもいいし...このような異なる区分は、異なるトレーニング/テストセットをもたらし、対応するモデル評価にも差がある.従って,残留法を用いる場合,通常は数回ランダムに区分し,実験評価を繰り返した後,平均値を残留法の評価結果としてとる.例えば100回のランダム分割を行い,1回のS/TS/Tを生成するごとに実験評価を行い,100個の結果を得たが,留法で返されたのはこの100個の結果の平均である.
    一般的なやり方では約2/3~4/5のサンプルをSSとし,残りはTTとする.sklearn.model_selection.train_test_splitを呼び出して、トレーニングセットとテストセットを比例的に区分します.
    import numpy as np
    from sklearn.model_selection import train_test_split
    
    X, Y = np.arange(10).reshape((5, 2)), range(5)
    print("X=", X)
    print("Y=", Y)
    X_train, X_test, Y_train, Y_test = train_test_split(
        X, Y, test_size=0.30, random_state=42)
    print("X_train=", X_train)
    print("X_test=", X_test)
    print("Y_train=", Y_train)
    print("Y_test=", Y_test)

    このうちtest_size=0.30はTTが30%を占め、SSが70%を占めていることを示している.実行結果:
    X= [[0 1]
     [2 3]
     [4 5]
     [6 7]
     [8 9]]
    Y= range(0, 5)
    X_train= [[4 5]
     [0 1]
     [6 7]]
    X_test= [[2 3]
     [8 9]]
    Y_train= [2, 0, 3]
    Y_test= [1, 4]

    クロス検証法


    クロス検証法はDDをkk個の大きさの類似した反発サブセットに分割し,すなわちD=D 1≒D 2≒Dk,Di∩Dj=∅(i≠j)D=D 1≒D 2≒Dk,Di∩Dj=∅(i≠j)である.各サブセットDiDiは、可能な限りデータ分布の一貫性を維持し、すなわち、DDから階層サンプリングによって得られる.そして,k−1 k−1個のサブセットを毎回SSとし,残りのサブセットをTTとすることでkk群S/TS/Tを得ることができ,kk回の訓練とテストを行い,最終的にこのkk個のテスト結果の平均を返すことができる.
    クロス検証法の評価結果の安定性と保真性はkkの値に大きく依存し、これを強調するために、クロス検証法を通常「kk折り返しクロス検証」(kk-fold cross validation)と呼ぶ.kkで最もよく使われる値は10で、5や20などを取ることもあります.sklearn.model_selection.KFoldを呼び出してkk折り返し交差でトレーニングセットとテストセットを分割します.
    import numpy as np
    from sklearn.model_selection import KFold
    
    X= np.arange(10).reshape((5, 2))
    print("X=", X)
    kf = KFold(n_splits=2)
    for train_index, test_index in kf.split(X):
        print('X_train:%s ' % X[train_index])
        print('X_test: %s ' % X[test_index])

    このうちn_splits=2はk=2 k=2を表す.実行結果:
    X= [[0 1]
     [2 3]
     [4 5]
     [6 7]
     [8 9]]
    X_train:[[6 7]
     [8 9]] 
    X_test: [[0 1]
     [2 3]
     [4 5]] 
    X_train:[[0 1]
     [2 3]
     [4 5]] 
    X_test: [[6 7]
     [8 9]]  

    DDがmm個のサンプルを含み、k=mk=mとすると、クロス検証法の特例である留一法(Leave-One-Out、略称LOO)が得られる.留一法で使用したSSはDDより1サンプル少ないため,ほとんどの場合,実際の評価結果はDDで訓練したモデルと類似している.そのため、留一法は比較的正確とされている.しかし、大きなデータセットに対して、計算のオーバーヘッドが大きすぎる方法を残します.他の方法よりも永遠に正確ではない.sklearn.model_selection.LeaveOneOutを呼び出して、トレーニングセットとテストセットを留一法で区分します.
    import numpy as np
    from sklearn.model_selection import LeaveOneOut
    
    X= np.arange(10).reshape((5, 2))
    print("X=", X)
    loo = LeaveOneOut()
    for train_index, test_index in loo.split(X):
        print('X_train:%s ' % X[train_index])
        print('X_test: %s ' % X[test_index])

    実行結果:
    X= [[0 1]
     [2 3]
     [4 5]
     [6 7]
     [8 9]]
    X_train:[[2 3]
     [4 5]
     [6 7]
     [8 9]] 
    X_test: [[0 1]] 
    X_train:[[0 1]
     [4 5]
     [6 7]
     [8 9]] 
    X_test: [[2 3]] 
    X_train:[[0 1]
     [2 3]
     [6 7]
     [8 9]] 
    X_test: [[4 5]] 
    X_train:[[0 1]
     [2 3]
     [4 5]
     [8 9]] 
    X_test: [[6 7]] 
    X_train:[[0 1]
     [2 3]
     [4 5]
     [6 7]] 
    X_test: [[8 9]] 

    セルフサービス法(bootstrapping)


    試験のためにTTとしてサンプルの一部を保持する前の2つの方法では、実際の評価モデルで使用されるトレーニングセットTTは、所望の評価モデルで使用されるトレーニングセットDDよりも常に小さく、トレーニングサンプルの規模の違いによる推定偏差がいくつか導入される.
    セルフサンプリング(bootstrap sampling)をベースとしたセルフサンプリング法.DDをサンプリングしてD’D’を生成する:DDからランダムに1つのサンプルを選択するたびに、それをコピーしてD’D’に入れ、DDを一定に保ち、以上の過程をmm回繰り返す.明らかに、DDの一部のサンプルはD’D’に複数回現れるが、他の一部は現れない.試料がmmサンプリング中に常に採取されない確率は(1−1 m)m(1−1 m)mであり,m→∞m→∞のとき,(1−1 m)m→1 e≒0.368(1−1 m)m→1 e≒0.368(1−1 m)m→1 e≒0.368であった.
    セルフサービス法により、DDの36.8%がD’D’に現れない.そこで、D’D’をトレーニングセットSSとし、D’D’D’D’D’をテストセットTTとし、実際の評価モデルと所望の評価モデルはいずれもmmサンプルであり、データ総量の1/3のトレーニングセットに現れていないサンプルがテストに用いられている.このような試験結果はパケット外推定(out−of−bag estimate)であった.
    セルフサービス法はデータセットが小さくS/TS/Tの区分が困難な場合に有用である.また、セルフサービス法はDDから異なるSSを生み出すことができ、集積学習などの方法においしい.セルフサービス法で発生したSSはDDの分布を変え,推定偏差を導入する.データ量が十分である場合、予約法とクロス検証法がよりよく使われます.