私はsklearnバージョン0.22を使用してKFloldとRepeatedKFoldを比較しています。よるとドキュメント:RepeatedKFoldは、「繰り返し、各繰り返しで異なるランダムでK倍n回。」一つは、唯一の1リピート(n_repeats = 1)でRepeatedKFoldの実行結果はいつも同じKFoldになることを期待します。
私は、単純な比較を実行しました:
import numpy as np
from sklearn.linear_model import SGDClassifier
from sklearn.datasets import load_digits
from sklearn.model_selection import StratifiedKFold, KFold, RepeatedKFold, RepeatedStratifiedKFold
from sklearn import metrics
X, y = load_digits(return_X_y=True)
classifier = SGDClassifier(loss='hinge', penalty='elasticnet', fit_intercept=True)
scorer = metrics.accuracy_score
results = []
n_splits = 5
kf = KFold(n_splits=n_splits)
for train_index, test_index in kf.split(X, y):
x_train, y_train = X[train_index], y[train_index]
x_test, y_test = X[test_index], y[test_index]
classifier.fit(x_train, y_train)
results.append(scorer(y_test, classifier.predict(x_test)))
print ('KFold')
print('mean = ', np.mean(results))
print('std = ', np.std(results))
print()
results = []
n_repeats = 1
rkf = RepeatedKFold(n_splits=n_splits, n_repeats = n_repeats)
for train_index, test_index in rkf.split(X, y):
x_train, y_train = X[train_index], y[train_index]
x_test, y_test = X[test_index], y[test_index]
classifier.fit(x_train, y_train)
results.append(scorer(y_test, classifier.predict(x_test)))
print ('RepeatedKFold')
print('mean = ', np.mean(results))
print('std = ', np.std(results))
出力は、
KFold
mean = 0.9082079851439182
std = 0.04697225962068869
RepeatedKFold
mean = 0.9493562364593006
std = 0.017732595698953055
私は違いが統計的に有意であることを確認するには、この実験に十分な回繰り返します。
私は何かが足りないが、無駄にしていますかどうかを確認するためにマニュアルを読み、再読しようとしていました。
ところで、同じことがStratifiedKFoldとRepeatedStratifiedKFoldにも当てはまります。
StratifiedKFold
mean = 0.9159935004642525
std = 0.026687786392525545
RepeatedStratifiedKFold
mean = 0.9560476632621479
std = 0.014405630805910506
このデータセットの場合、StratifiedKFoldはKFoldと一致します。RepeatedStratifiedKFoldはRepeatedSKFoldと一致します。
UPDATE @Danと@SergeyBushmanovからの提案に続いて、私はシャッフルとrandom_stateを含みます
def run_nfold(X,y, classifier, scorer, cv, n_repeats):
results = []
for n in range(n_repeats):
for train_index, test_index in cv.split(X, y):
x_train, y_train = X[train_index], y[train_index]
x_test, y_test = X[test_index], y[test_index]
classifier.fit(x_train, y_train)
results.append(scorer(y_test, classifier.predict(x_test)))
return results
kf = KFold(n_splits=n_splits)
results_kf = run_nfold(X,y, classifier, scorer, kf, 10)
print('KFold mean = ', np.mean(results_kf))
kf_shuffle = KFold(n_splits=n_splits, shuffle=True, random_state = 11)
results_kf_shuffle = run_nfold(X,y, classifier, scorer, kf_shuffle, 10)
print('KFold Shuffled mean = ', np.mean(results_kf_shuffle))
rkf = RepeatedKFold(n_splits=n_splits, n_repeats = n_repeats, random_state = 111)
results_kf_repeated = run_nfold(X,y, classifier, scorer, rkf, 10)
print('RepeatedKFold mean = ', np.mean(results_kf_repeated)
生成
KFold mean = 0.9119255648406066
KFold Shuffled mean = 0.9505304859176724
RepeatedKFold mean = 0.950754100897555
また、コルモゴロフ - スミルノフ検定を使用して:
print ('Compare KFold with KFold shuffled results')
ks_2samp(results_kf, results_kf_shuffle)
print ('Compare RepeatedKFold with KFold shuffled results')
ks_2samp(results_kf_repeated, results_kf_shuffle)
デフォルトの非シャッフルKFoldは統計的に有意に低い結果を生成するのに対し、KFoldはシャッフルとRepeatedKFold(デフォルトではシャッフルされ、あなたが右@Danているに見える)ことを示しているが、統計的に同じです。
Compare KFold with KFold shuffled results
Ks_2sampResult(statistic=0.66, pvalue=1.3182765881237494e-10)
Compare RepeatedKFold with KFold shuffled results
Ks_2sampResult(statistic=0.14, pvalue=0.7166468440414822)
さて、私が使用したノート異なる KFoldとRepeatedKFoldためrandom_stateを。だから、その答え、またはむしろ部分的な答えは、結果の差が非シャッフル対シャッフルによるものであるということです。これは、正確な分割を変更することができます異なるrandom_stateを使用しているので、理にかなって、それは複数回の実行の平均と同様に、統計的性質を変更しないでください。
私は今、シャッフルは、この効果をもたらす理由で混乱しています。私は(私はそれがどんなstackoverflowのルールを破るはありません願っていますが、私は別の質問を作成する必要はありません)この混乱を反映するために、質問のタイトルを変更しました。
UPDATE私はSergeyBushmanovの提案@に同意します。私はそれとして投稿新しい質問
作るためにRepeatedKFold
と結果は似てKFold
お持ちに:
np.random.seed(42)
n = np.random.choice([0,1],10,p=[.5,.5])
kf = KFold(2,shuffle=True, random_state=42)
list(kf.split(n))
[(array([2, 3, 4, 6, 9]), array([0, 1, 5, 7, 8])),
(array([0, 1, 5, 7, 8]), array([2, 3, 4, 6, 9]))]
kfr = RepeatedKFold(n_splits=2, n_repeats=1, random_state=42)
list(kfr.split(n))
[(array([2, 3, 4, 6, 9]), array([0, 1, 5, 7, 8])),
(array([0, 1, 5, 7, 8]), array([2, 3, 4, 6, 9]))]
RepeatedKFold
用途は KFold
あなただけ必ず両方が類似していそれを作るために必要な、折り目を生成しますrandom_state
。