web-dev-qa-db-ja.com

sklearn.cross_validationでのtrain_test_splitとcross_val_scoreの使用の違い

20列の行列があります。最後の列は0/1ラベルです。

データへのリンクは here です。

交差検証を使用して、データセットでランダムフォレストを実行しようとしています。これを行うには2つの方法を使用します。

  1. sklearn.cross_validation.cross_val_scoreを使用
  2. sklearn.cross_validation.train_test_splitを使用

まったく同じだと思うことをすると、異なる結果が得られます。例として、以下のコードのように、上記の2つの方法を使用して2重交差検証を実行します。

import csv
import numpy as np
import pandas as pd
from sklearn import ensemble
from sklearn.metrics import roc_auc_score
from sklearn.cross_validation import train_test_split
from sklearn.cross_validation import cross_val_score

#read in the data
data = pd.read_csv('data_so.csv', header=None)
X = data.iloc[:,0:18]
y = data.iloc[:,19]

depth = 5
maxFeat = 3 

result = cross_val_score(ensemble.RandomForestClassifier(n_estimators=1000, max_depth=depth, max_features=maxFeat, oob_score=False), X, y, scoring='roc_auc', cv=2)

result
# result is now something like array([ 0.66773295,  0.58824739])

xtrain, xtest, ytrain, ytest = train_test_split(X, y, test_size=0.50)

RFModel = ensemble.RandomForestClassifier(n_estimators=1000, max_depth=depth, max_features=maxFeat, oob_score=False)
RFModel.fit(xtrain,ytrain)
prediction = RFModel.predict_proba(xtest)
auc = roc_auc_score(ytest, prediction[:,1:2])
print auc    #something like 0.83

RFModel.fit(xtest,ytest)
prediction = RFModel.predict_proba(xtrain)
auc = roc_auc_score(ytrain, prediction[:,1:2])
print auc    #also something like 0.83

私の質問は:

train_test_splitを使用すると、なぜ異なる結果が得られるのですか。つまり、AUC(使用しているメトリック)が高いのはなぜですか。

注:より多くのフォールド(たとえば10フォールド)を使用すると、結果に何らかのパターンがあり、最初の計算で常に最高のAUCが得られます。

上記の例の2分割交差検証の場合、最初のAUCは常に2番目のものより高くなります。それは常に0.70と0.58のようなものです。

ご協力いただきありがとうございます!

10
evianpring

Cross_val_scoreを使用する場合、KFoldsまたはStratifiedKFoldsイテレーターを頻繁に使用する必要があります。

http://scikit-learn.org/0.10/modules/cross_validation.html#computing-cross-validated-metrics

http://scikit-learn.org/0.10/modules/generated/sklearn.cross_validation.KFold.html#sklearn.cross_validation.KFold

デフォルトでは、cross_val_scoreはデータをランダム化しません。そのため、データが最初からランダムでない場合、このような奇妙な結果が生成される可能性があります。

KFoldsイテレーターにはランダムな状態パラメーターがあります。

http://scikit-learn.org/stable/modules/generated/sklearn.cross_validation.KFold.html

デフォルトでランダム化するtrain_test_splitも同様です。

http://scikit-learn.org/stable/modules/generated/sklearn.cross_validation.train_test_split.html

あなたが説明したようなパターンは、通常、トレーニング/テストセットのランダム性の欠如の結果です。

13
KCzar