2017-02-14 80 views
4

我試圖獲得SVR模型的最佳參數集。 我想使用GridSearchCV而不是C的不同值。然而,從之前的測試中我注意到,訓練/測試集合higlhy影響整體性能(本例中爲r2)。 爲了解決這個問題,我想實施重複的5倍交叉驗證(10 x 5CV)。是否有內置的方式使用GridSearchCV執行它?scikit-learn GridSearchCV具有多個重複

快速的解決方案:

NUM_TRIALS = 10 
scores = [] 
for i in range(NUM_TRIALS): 
    cv = KFold(n_splits=5, shuffle=True, random_state=i) 
    clf = GridSearchCV(estimator=svr, param_grid=p_grid, cv=cv) 
    scores.append(clf.best_score_) 
print "Average Score: {0} STD: {1}".format(numpy.mean(scores), numpy.std(scores)) 
+0

爲了更好地理解,您的目標是重複5CV以瞭解SVR的行爲方式?這意味着你將爲每個參數組合使用10x5不同的分割?在任何情況下,您都可以提供自定義cv函數來執行此操作,並根據需要多次生成數據集分割,或根據需要對其進行自定義。 GridSearchCV會將它視爲每次使用所選參數的運行,並且它將像往常一樣在最後收集結果。 – mkaran

回答

6

這被稱爲嵌套cross_validation:

繼在科幻試劑盒offical documentation提出的想法,一個快速的解決方案由下式表示。你可以看official documentation example引導你進入正確的方向,也可以看看我的other answer here類似的方法。

您可以調整的步驟,以滿足您的需要:

svr = SVC(kernel="rbf") 
c_grid = {"C": [1, 10, 100, ... ]} 

# CV Technique "LabelKFold", "LeaveOneOut", "LeaveOneLabelOut", etc. 

# To be used within GridSearch (5 in your case) 
inner_cv = KFold(n_splits=5, shuffle=True, random_state=i) 

# To be used in outer CV (you asked for 10) 
outer_cv = KFold(n_splits=10, shuffle=True, random_state=i) 

# Non_nested parameter search and scoring 
clf = GridSearchCV(estimator=svr, param_grid=c_grid, cv=inner_cv) 
clf.fit(X_iris, y_iris) 
non_nested_score = clf.best_score_ 

# Pass the gridSearch estimator to cross_val_score 
# This will be your required 10 x 5 cvs 
# 10 for outer cv and 5 for gridSearch's internal CV 
clf = GridSearchCV(estimator=svr, param_grid=c_grid, cv=inner_cv) 
nested_score = cross_val_score(clf, X=X_iris, y=y_iris, cv=outer_cv).mean() 

編輯 - 嵌套的交叉驗證與cross_val_score()GridSearchCV()說明

  1. CLF = GridSearchCV(估計,param_grid,CV = inner_cv)。
  2. 通行證clf, X, y, outer_cvcross_val_score
  3. 作爲source code of cross_val_score看到,這X將使用outer_cv分爲X_outer_train, X_outer_test。 y一樣。
  4. X_outer_test將被阻止,並且X_outer_train將傳遞到clf for fit()(在我們的例子中爲GridSearchCV)。 假設X_outer_train從這裏開始被稱爲X_inner,因爲它被傳遞給內部估計器,假設y_outer_trainy_inner
  5. X_inner現在將在GridSearchCV中使用inner_cv拆分爲X_inner_trainX_inner_test。 y相同
  6. 現在,將使用X_inner_trainy_train_inner對網格搜索估算器進行訓練,並使用X_inner_testy_inner_test對其進行評分。
  7. 步驟5和6對於inner_cv_iters(在這種情況下爲5)將重複
  8. 將所有迭代的平均分數最好的參數傳遞到clf.best_estimator_並適用於所有數據,即X_train
  9. 然後使用X_outer_testy_outer_testclfgridsearch.best_estimator_)進行評分。
  10. 步驟3到9會反覆爲outer_cv_iters(10此處)和分數的數組將從cross_val_score
  11. 返回然後,我們使用均值()找回nested_score
+0

我不想嵌套CV,我只想重複CV 10次,每次使用不同的數據分割成訓練和測試集。 –

+0

據我所知,這就是'outer_cv'正在做的事情。它會將數據分成訓練和測試10次('n_split'),'cross_val_score'將對grid_search('clf')進行評分,然後分割傳入的數據(即來自'outer_cv'的訓練數據)再次進入火車並測試以找到最佳參數。 –

+0

你能舉一個你想要做什麼的例子嗎? –

2

您可以向GridSearchCV提供不同的交叉驗證生成器。二進制或多類分類問題的缺省值爲StratifiedKFold。否則,它使用KFold。但你可以提供你自己的。在你的情況下,它看起來像你想要RepeatedKFoldRepeatedStratifiedKFold

from sklearn.model_selection import GridSearchCV, RepeatedStratifiedKFold 

# Define svr here 
... 

# Specify cross-validation generator, in this case (10 x 5CV) 
cv = RepeatedKFold(n_splits=5, n_repeats=10) 
clf = GridSearchCV(estimator=svr, param_grid=p_grid, cv=cv) 

# Continue as usual 
clf.fit(...) 
+0

這對我不起作用。我得到以下錯誤:'TypeError:'RepeatedKFold'對象不可迭代' – tmastny

+1

@tmastny我無法重現此錯誤。它與[這篇文章](https://stackoverflow.com/questions/43176916/typeerror-shufflesplit-object-is-not-iterable)有關嗎?也就是說,你的'GridSearchCV'是來自'sklearn.model_selection'還是'sklearn.grid_search'? – AdamRH

+0

真棒,它現在有效。謝謝你的耐心。這絕對是最新的答案,並且使重複的k-fold調整非常簡單。 – tmastny