2016-06-25 5 views
13

〜300ポイントと32の別個のラベルを持つデータセットがあり、グリッド検索とLabelKFold検証を使用して学習曲線をプロットすることで、LinearSVRモデルを評価したいと考えています。LabelKFoldをネストする方法は?

私が持っているコードは次のようになります。

import numpy as np 
from sklearn import preprocessing 
from sklearn.svm import LinearSVR 
from sklearn.pipeline import Pipeline 
from sklearn.cross_validation import LabelKFold 
from sklearn.grid_search import GridSearchCV 
from sklearn.learning_curve import learning_curve 
    ... 
#get data (x, y, labels) 
    ... 
C_space = np.logspace(-3, 3, 10) 
epsilon_space = np.logspace(-3, 3, 10) 

svr_estimator = Pipeline([ 
    ("scale", preprocessing.StandardScaler()), 
    ("svr", LinearSVR), 
]) 

search_params = dict(
    svr__C = C_space, 
    svr__epsilon = epsilon_space 
) 

kfold = LabelKFold(labels, 5) 

svr_search = GridSearchCV(svr_estimator, param_grid = search_params, cv = ???) 

train_space = np.linspace(.5, 1, 10) 
train_sizes, train_scores, valid_scores = learning_curve(svr_search, x, y, train_sizes = train_space, cv = ???, n_jobs = 4) 
    ... 
#plot learning curve 

私の質問はどのようにグリッドサーチのためのセットアップCV属性を、それがトレーニングとテストセットに私の元のセットが解除されますように曲線を学習することドン学習曲線を計算するためのラベルを共有しないでください。これらのトレーニングセットから、グリッド検索のラベルを共有することなくトレーニングセットとテストセットに分けます。

基本的に、ネストされたLabelKFoldを実行するにはどうすればよいですか?


I、この質問に対して報奨金を作成したユーザーには、sklearnから入手可能なデータを使用して、次の再現性の例を書きました。あなたの質問から

import numpy as np 
from sklearn.datasets import load_digits 
from sklearn.ensemble import RandomForestClassifier 
from sklearn.metrics import make_scorer, roc_auc_score 
from sklearn.grid_search import GridSearchCV 
from sklearn.cross_validation import cross_val_score, LabelKFold 

digits = load_digits() 
X = digits['data'] 
Y = digits['target'] 
Z = np.zeros_like(Y) ## this is just to make a 2-class problem, purely for the sake of an example 
Z[np.where(Y>4)]=1 

strata = [x % 13 for x in xrange(Y.size)] # define the strata for use in 

## define stuff for nested cv... 
mtry = [5, 10] 
tuned_par = {'max_features': mtry} 
toy_rf = RandomForestClassifier(n_estimators=10, max_depth=10, random_state=10, 
           class_weight="balanced") 
roc_auc_scorer = make_scorer(roc_auc_score, needs_threshold=True) 

## define outer k-fold label-aware cv 
outer_cv = LabelKFold(labels=strata, n_folds=5) 

############################################################################# 
## this works: using regular randomly-allocated 10-fold CV in the inner folds 
############################################################################# 
vanilla_clf = GridSearchCV(estimator=toy_rf, param_grid=tuned_par, scoring=roc_auc_scorer, 
         cv=5, n_jobs=1) 
vanilla_results = cross_val_score(vanilla_clf, X=X, y=Z, cv=outer_cv, n_jobs=1) 

########################################################################## 
## this does not work: attempting to use label-aware CV in the inner loop 
########################################################################## 
inner_cv = LabelKFold(labels=strata, n_folds=5) 
nested_kfold_clf = GridSearchCV(estimator=toy_rf, param_grid=tuned_par, scoring=roc_auc_scorer, 
           cv=inner_cv, n_jobs=1) 
nested_kfold_results = cross_val_score(nested_kfold_clf, X=X, y=Y, cv=outer_cv, n_jobs=1) 

答えて

3

再びLabelKFoldを使用して、この外側LabelKFoldの反復のそれぞれであなたのパイプラインのパラメータをグリッド検索中に、あなたは、あなたのデータのLabelKFoldスコアを探しています。

outer_cv = LabelKFold(labels=strata, n_folds=3) 
strata = np.array(strata) 
scores = [] 
for outer_train, outer_test in outer_cv: 
    print "Outer set. Train:", set(strata[outer_train]), "\tTest:", set(strata[outer_test]) 
    inner_cv = LabelKFold(labels=strata[outer_train], n_folds=3) 
    print "\tInner:" 
    for inner_train, inner_test in inner_cv: 
     print "\t\tTrain:", set(strata[outer_train][inner_train]), "\tTest:", set(strata[outer_train][inner_test]) 
    clf = GridSearchCV(estimator=toy_rf, param_grid=tuned_par, scoring=roc_auc_scorer, cv= inner_cv, n_jobs=1) 
    clf.fit(X[outer_train],Z[outer_train]) 
    scores.append(clf.score(X[outer_test], Z[outer_test])) 

コード、最初の反復利回り実行:それは唯一のループとる独創私はそれを達成することができませんでしたが、そこで

Outer set. Train: set([0, 1, 4, 5, 7, 8, 10, 11]) Test: set([9, 2, 3, 12, 6]) 
Inner: 
    Train: set([0, 10, 11, 5, 7]) Test: set([8, 1, 4]) 
    Train: set([1, 4, 5, 8, 10, 11]) Test: set([0, 7]) 
    Train: set([0, 1, 4, 8, 7])  Test: set([10, 11, 5]) 

を、それがしやすいです意図したとおりに実行されることを確認してください。クロスバリデーションのスコアはリストscoresにあり、簡単に処理できます。私はあなたの最後のコードで定義したstrataのような変数を使用しました。

+0

これは、自分でkfoldループを実行して、個々のフォールドでグリッド検索を実行する必要があったのとほぼ同じです。私は元の質問者ですが、私はこの質問に賞金をあげた人ではありません。私はそれがどのように動作するのか分かりませんが、私が知っている最良の解決策であるので、私はこの答えをupvoteするつもりです。しかし、私は答えを受け入れる前に賞金の所持者の応答を待つつもりです。 – Alex

+0

これは非常に実行可能に見えます - 私はこれを旋風にします。これが正しい方法だと思われます。どうもありがとうございました。 FWIW、@Alex、私は賞金を授与することができると信じています。だから、ジオマルクは24時間以内にそれを楽しみにしています。 – Sycorax

関連する問題