データセット分割方法

5602 ワード

機械学習モデリングの過程で、データセットをトレーニングセットとテストセットに分けるのが一般的です.テストセットは訓練とは独立したデータであり,最終モデルの評価にはまったく参加しない.訓練の過程で,モデルは訓練データによく一致するが,訓練セット外のデータをうまく予測できないという問題がしばしば発生する.この時点でモデルパラメータを調整するためにテストデータを使用すると、トレーニング時に既知のテストデータの一部の情報に相当し、最終評価結果の正確性に影響します.通常の方法は,モデルの訓練効果を評価するために訓練データの一部を検証(Validation)データとして分割することである.検証データは、トレーニングデータから取得されるが、トレーニングに参加しないため、トレーニングセット以外のデータに対するモデルのマッチングの程度を比較的客観的に評価することができる.モデルの検証データでの評価では、クロス検証が一般的であり、ループ検証とも呼ばれます.元のデータをKグループ(K-Fold)に分割し、各サブセットデータをそれぞれ検証セットとし、残りのK-1グループのサブセットデータをトレーニングセットとしてKモデルを得る.このK個のモデルはそれぞれ検証セットにおいて結果を評価し,最後の誤差MSE(Mean Squared Error)の加算と平均化で交差検証誤差を得た.クロス検証は限られたデータを有効に利用し,評価結果はできるだけモデルのテストセットでの表現に近づくことができ,モデル最適化の指標として使用できる.

一、ランダム区分


train_test_splitは最も簡単なデータセット分割関数であり,サンプルを比例的に分割する機能を果たす.
# coding = utf-8
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn import datasets

iris = datasets.load_iris()
X = iris.data
y = iris.target

x_train,x_test,y_train,y_test = train_test_split(X, y, test_size=0.2,
                                                 stratify=y,  #  
                                                 shuffle=True, #  
                                                 random_state=1)   #  
x_train,x_valid,y_train,y_valid = train_test_split(x_train, y_train, test_size=0.4,
                                                 stratify=y_train,
                                                 shuffle=True,
                                                 random_state=1) 

しかし、この方法はあまりよくなく、2つの大きな欠点があります.1つはデータの浪費、2つはフィットしやすく、矯正が不便です.

二、K割引区分


1、KFold


K-Foldは最も簡単なK折り返し交差で、n-splitはK値で、shuffleはデータをシャッフルするかどうかを指し、random_stateがランダムシードK値の選択はbiasとvirianceに影響します.Kが大きいほど,毎回投入される訓練セットのデータが多くなり,モデルのBiasは小さくなる.しかし、Kが大きいほど、選択される各トレーニングセットの前の相関が大きくなることを意味し、このような大きな相関は、最終的なtest errorがより大きなVarianceを有することをもたらす.一般的に、経験に基づいてk=5または10を選択します.
# coding = utf-8
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.model_selection import KFold
from sklearn import datasets
from sklearn.ensemble import GradientBoostingClassifier as GBDT
from sklearn.metrics import precision_score

iris = datasets.load_iris()
X = iris.data
y = iris.target

x_train,x_test,y_train,y_test = train_test_split(X, y, test_size=0.2,
                                                 stratify=y,  #  
                                                 shuffle=True, #  
                                                 random_state=1)   #  

clf = GBDT(n_estimators=100)
precision_scores = []

kf = KFold(n_splits=5, random_state=0, shuffle=False)
for train_index, valid_index in kf.split(x_train, y_train):
    x_train, x_valid = X[train_index], X[valid_index]
    y_train, y_valid = y[train_index], y[valid_index]
    clf.fit(x_train, y_train)
    y_pred = clf.predict(x_valid)
    precision_scores.append(precision_score(y_valid, y_pred, average='micro'))

print('Precision', np.mean(precision_scores))

2、StratifiedKFold


StratifiedKFoldはKfoldに似ていますが、トレーニングセット、検証セットの各種類のサンプルの割合が元のデータセットと同じであることを確認するために階層的にサンプリングされています.
# coding = utf-8
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.model_selection import KFold
from sklearn import datasets
from sklearn.ensemble import GradientBoostingClassifier as GBDT
from sklearn.metrics import precision_score

iris = datasets.load_iris()
X = iris.data
y = iris.target

x_train,x_test,y_train,y_test = train_test_split(X, y, test_size=0.2,
                                                 stratify=y,  #  
                                                 shuffle=True, #  
                                                 random_state=1)   #  

clf = GBDT(n_estimators=100)
precision_scores = []

kf = StratifiedKFold(n_splits=5, random_state=0, shuffle=False)
for train_index, valid_index in kf.split(x_train, y_train):
    x_train, x_valid = X[train_index], X[valid_index]
    y_train, y_valid = y[train_index], y[valid_index]
    clf.fit(x_train, y_train)
    y_pred = clf.predict(x_valid)
    precision_scores.append(precision_score(y_valid, y_pred, average='micro'))

print('Precision', np.mean(precision_scores))

3、StratifiedShuffleSplit


StratifiedShuffleSplitでは、train/validペアのtrainとvalidの比率を設定できます.
# coding = utf-8
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.model_selection import StratifiedShuffleSplit
from sklearn import datasets
from sklearn.ensemble import GradientBoostingClassifier as GBDT
from sklearn.metrics import precision_score

iris = datasets.load_iris()
X = iris.data
y = iris.target

x_train,x_test,y_train,y_test = train_test_split(X, y, test_size=0.2,
                                                 stratify=y,  #  
                                                 shuffle=True, #  
                                                 random_state=1)   #  

clf = GBDT(n_estimators=100)
precision_scores = []

kf = StratifiedShuffleSplit(n_splits=10, train_size=0.6, test_size=0.4, random_state=0)
for train_index, valid_index in kf.split(x_train, y_train):
    x_train, x_valid = X[train_index], X[valid_index]
    y_train, y_valid = y[train_index], y[valid_index]
    clf.fit(x_train, y_train)
    y_pred = clf.predict(x_valid)
    precision_scores.append(precision_score(y_valid, y_pred, average='micro'))

print('Precision', np.mean(precision_scores))

他の方法、例えばRepeatedStratifiedKFold、GroupKFoldなどはsklearn公式ドキュメントを参照してください.拡張読書