データセットの分割方法

20802 ワード

1モデル評価方法


現実的なタスクでは,多くのモデルが選択可能であり,一般に候補モデルの汎化誤差を推定することによって,汎化誤差が最も小さいモデルを選択する.したがって、学習器の新しいサンプルに対する判別能力を検出し、テストセット上の「テスト誤差」を汎化誤差の近似とする「テストセット」が必要であり、ここでは、テストセットもサンプルの実際の分布から独立して同分布サンプリングして得られると仮定する.
学習タスクの中に,m m m個のサンプルを含むデータセットD={(x 1,y 1),(x 2,y 2),⋯&ThinSpac;,(( x m,y m)}D={(textbf{x}_1,y_1),(textbf{x}_2,y_2),cdots,((textbf{x}_m,y_m)}D={(x 1,y 1),(x 2,y 2),⋯,(xm,ym)}があると仮定すれば,我々は適切な方法で適切なことができる.トレーニングセットS S SとテストセットT T T Tが生成され、T T TとS S Sができるだけ反発することが要求される.すなわち、試験サンプルは、できるだけ訓練セットに現れず、訓練中に使用されたことがない.いくつかの一般的な区分方法を紹介します.

1.1留置法


「留去法」は直接データセットD D Dを二つの反発の集合に分け、一つは訓練セットS S S、一つはテストセットT T、すなわちD=S∪T、S∩T=∅である.D=S\cup T,S\cap T=\emptyset. D=S∪T,S∩T=∅.モデル学習をS S S上で行い,その後,汎化誤差の推定としてT T Tを用いてその試験誤差を評価した.
単回使用残法で得られた推定結果は不安定で信頼性が低いことが多く,残法を使用する場合,モデル評価を数回ランダムに分割し,繰り返して行った後,平均値を残法の評価結果としてとるのが一般的である.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Feb 25 10:57:29 2019

@author: lihui
"""

from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC # 
from sklearn.metrics import accuracy_score


data = datasets.load_iris() # 
X = data['data']
y = data['target']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3) # 

clf = SVC()
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)

print(accuracy_score(y_test, y_pred)) # 



1.2クロス検証法


「クロス検証法」は、まずデータセットD D Dをk k個の同じ大きさの反発サブセット、すなわちD=D 1≒D 2≒D K,D i∩D j=∅(i≠j)に分割する.D=D_1\cup D_2\cup\cdots\cup D_k,D_i\cap D_j=\emptyset(ieq j). D=D1​∪D2​∪⋯∪Dk​,Di​∩Dj​=∅(i̸​=j).各サブセットD i D_i Diは、データ分布の整合性をできるだけ維持しなければならない.すなわち、D D Dから階層サンプリングによって得られる.
そして,その都度その中のk−1 k−1 k−1個のサブセットを訓練セットとし,残りの1個を試験セットとすることで,k k k組の訓練セット/試験セットを得ることができ,k k次モデルの学習が可能となり,このk k個の試験結果の平均値を評価結果とし,通常交差検証法を「k k k折交差検証」と呼ぶ.
データセットD D Dをk k kサブセットに分割するには、サンプル分割によって導入される差を低減するために、k k k折交差検証は、ランダムに異なる分割を用いてp p p p回を繰り返すことができ、最終的な評価の結果、このp p p p回k折交差検証結果の平均値である.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Feb 25 11:27:09 2019

@author: lihui
"""

from sklearn import datasets
from sklearn.model_selection import KFold, RepeatedKFold
from sklearn.linear_model import LogisticRegression # 
from sklearn.metrics import accuracy_score

data = datasets.load_iris() # 
X = data['data']
y = data['target']

clf = LogisticRegression(solver='newton-cg') # 

k_fold = 10 # 10 
kf = KFold(n_splits=k_fold) 
averg_score = 0
for train_index, test_index in kf.split(X):
    X_train, X_test = X[train_index], X[test_index]
    y_train, y_test = y[train_index], y[test_index]
    clf.fit(X_train, y_train)
    y_pred = clf.predict(X_test)
    averg_score += accuracy_score(y_test, y_pred)
print("%d %f"%(k_fold, averg_score / k_fold))

averg_score = 0
repeats_num = 10
rkf = RepeatedKFold(n_splits=k_fold, n_repeats=repeats_num)
for train_index, test_index in rkf.split(X):
    X_train, X_test = X[train_index], X[test_index]
    y_train, y_test = y[train_index], y[test_index]
    clf.fit(X_train, y_train)
    y_pred = clf.predict(X_test)
    averg_score += accuracy_score(y_test, y_pred)
averg_score = averg_score / (repeats_num * k_fold)
print("%d %d %f"%(repeats_num, k_fold, averg_score))


k=m k=m k=mとすると、クロス検証の特例が得られる:留一法、留一法で使用されるトレーニングセットは、初期データセットに比べて1つのサンプルしか少なくないので、留一法で実際に評価されたモデルは、D D Dで訓練されたモデルと類似している.従って,留一法の評価結果は比較的正確と考えられることが多いが,欠陥はビッグデータセットに遭遇した場合,オーバーヘッドを計算する際に受け入れられないことである.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Feb 25 12:07:23 2019

@author: lihui
"""

from sklearn import datasets
from sklearn.model_selection import KFold, RepeatedKFold, LeaveOneOut
from sklearn.linear_model import LogisticRegression # 
from sklearn.metrics import accuracy_score

data = datasets.load_iris() # 
X = data['data']
y = data['target']

clf = LogisticRegression(solver='newton-cg') # 

averg_score = 0
loo = LeaveOneOut()
for train_index, test_index in loo.split(X):
        X_train, X_test = X[train_index], X[test_index]
        y_train, y_test = y[train_index], y[test_index]
        #print(X_train, X_test, y_train, y_test)
        clf.fit(X_train, y_train)
        y_pred = clf.predict(X_test)
        averg_score += accuracy_score(y_test, y_pred)
averg_score = averg_score / len(y)
print(" %f"%averg_score)


1.3セルフサービス法


試験のための試料の一部を留保法と交差検証法で保持したが,モデルはD D Dを用いて訓練されたものであることを期待した.従って、「セルフサービス法」は、データセットD D Dをサンプリングして新しいデータセットD′D^{′}D′を生成する比較的良い解決方法である:D D Dから戻されるランダムサンプリングを行うたびに、取得サンプルをD′D^{′}D′に入れ、D′D^{′}D′のサンプル個数までmとする.m.m.明らかに、D D D Dの一部のサンプルがD’D^{'}D’に複数回出現する可能性があり、いずれのサンプルに対しても、m m m mサブサンプリングで取られなかった確率は(1−1 m)m(1−frac{1}{m})^{m}(1−m 1)mであり、サンプル個数m→+∞mto+infty m→+∞の場合、lim⁡m→+∞(1−1 m)m=1 e≒0.368lim_{mto+infty}{(1−frac{1}{m})^{m}=frac{1}{e}approx 0.368 m→+∞lim(1−m 1)m=e 1≒0.368は自己居住法によりサンプリングされ、データセットD D D D D Dの約36.8%36.8%36.8%のサンプルがデータセットD’D^{'}D’に現れず、D’D^{'}D’をトレーニングセットとして使用することができ、D/D’D/D^{'}D'をテストセットとして使用することができる.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Feb 25 12:17:03 2019

@author: lihui
"""

import numpy as np
from sklearn import datasets
from sklearn.linear_model import LogisticRegression # 
from sklearn.metrics import accuracy_score
import random

data = datasets.load_iris() # 
X = data['data']
y = data['target']

clf = LogisticRegression(solver='newton-cg') # 

train_index = [random.randint(0, len(y)-1) for i in range(len(y))] # 
test_index = list(set(np.arange(len(y))) - set(train_index)) 
X_train = X[train_index] # X 
X_test = X[test_index]
y_train = y[train_index]
y_test = y[test_index]
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
print(" %f"%accuracy_score(y_test, y_pred))


セルフ・サービス法は、データセットが小さく、トレーニング/テストセットを効率的に区別することが困難な場合に役立ちます.また,セルフ・サービス法は初期データ・セットから複数の異なるトレーニング・セットを生成することができ,統合学習などの方法に大きなメリットがある.しかし,セルフ・サービス法により生成されたデータセットは初期データセットの分布を変化させ,これは偏差を導入する.したがって、初期データセットが十分に多い場合、予約法とクロス検証法がより一般的に使用されます.
ドキュメントの説明:
本文は主に个人が周志華先生の《机械学习》を学ぶ时にした记录で、そして个人のコードを添付して、もし疑问があれば私信に连络してください!