如何使用 RandomizedSearchCV 正确实现 StratifiedKFold

Posted

技术标签:

【中文标题】如何使用 RandomizedSearchCV 正确实现 StratifiedKFold【英文标题】:How to correctly implement StratifiedKFold with RandomizedSearchCV 【发布时间】:2019-01-27 09:10:41 【问题描述】:

我正在尝试使用 layerifiedKFold 和 RandomizedSearchCV 来实现一个随机森林分类器。问题是我可以看到 RandomizedSearchCV 的“cv”参数用于进行交叉验证。但我不明白这怎么可能。 我需要有 X_train、X_test、y_train、y_test 数据集,如果我尝试按照我所看到的方式实现我的代码,就不可能拥有这四个数据集...... 我见过类似以下的事情:

cross_val = StratifiedKFold(n_splits=split_number)
clf = RandomForestClassifier()
n_iter_search = 45
random_search = RandomizedSearchCV(clf, param_distributions=param_dist,
                               n_iter=n_iter_search,
                               scoring=Fscorer, cv=cross_val,
                               n_jobs=-1)
random_search.fit(X, y) 

但问题是我需要用 X_train 和 y_train 数据集拟合我的数据,并使用 X_train 和 X_test 数据集预测结果,以便能够比较训练数据和测试数据中的结果以评估可能过拟合... 这是我的一段代码,我知道我做了两次工作,但我不知道如何正确使用 stratifiedKfold 和 RandomizedSearchCV:

...
cross_val = StratifiedKFold(n_splits=split_number)
index_iterator = cross_val.split(features_dataframe, classes_dataframe)
clf = RandomForestClassifier()
random_grid = _create_hyperparameter_finetuning_grid()
clf_random = RandomizedSearchCV(estimator = clf, param_distributions = random_grid, n_iter = 100, cv = cross_val,
                                verbose=2, random_state=42, n_jobs = -1)
for train_index, test_index in index_iterator:
    X_train, X_test = np.array(features_dataframe)[train_index], np.array(features_dataframe)[test_index]
    y_train, y_test = np.array(classes_dataframe)[train_index], np.array(classes_dataframe)[test_index]
    clf_random.fit(X_train, y_train)
    clf_list.append(clf_random)
    y_train_pred = clf_random.predict(X_train)
    train_accuracy = np.mean(y_train_pred.ravel() == y_train.ravel())*100
    train_accuracy_list.append(train_accuracy)
    y_test_pred = clf_random.predict(X_test)
    test_accuracy = np.mean(y_test_pred.ravel() == y_test.ravel())*100

    confusion_matrix = pd.crosstab(y_test.ravel(), y_test_pred.ravel(), rownames=['Actual Cultives'],
                                   colnames=['Predicted Cultives'])
...

如您所见,我正在做两次分层 K 折叠的工作,(或者这就是我认为我正在做的事情......)只是为了能够获得评估我的系统所需的四个数据集. 提前感谢您的帮助。

【问题讨论】:

【参考方案1】:

RandomizedSearchCV 用于寻找分类器的最佳参数。它选择随机参数并使用它们拟合您的模型。之后它需要评估这个模型,你可以选择策略,它是 cv 参数。然后用另一个参数。你不需要做两次。你可以写:

cross_val = StratifiedKFold(n_splits=split_number)
index_iterator = cross_val.split(features_dataframe, classes_dataframe)
clf = RandomForestClassifier()
random_grid = _create_hyperparameter_finetuning_grid()
clf_random = RandomizedSearchCV(estimator = clf, param_distributions = random_grid, n_iter = 100, cv = cross_val,
                                verbose=2, random_state=42, n_jobs = -1)
clf_random.fit(X, y)

一切都会自动完成。之后你应该查看 cv_results_ 或 best_estimator_ 等参数。如果您不想为分类器搜索最佳参数 - 您不应该使用 RandomizedSearchCV。它只是为了做到这一点。

这是一个很好的example。

统一更新: 尝试这样做:

clf = RandomForestClassifier()
random_grid = _create_hyperparameter_finetuning_grid()
clf_random = RandomizedSearchCV(estimator = clf, param_distributions = random_grid, 
                                score = 'accuracy', n_iter = 100, 
                                cv = StratifiedKFold(n_splits=split_number),
                                verbose=2, random_state=42, n_jobs = -1)
clf_random.fit(X, y)
print(clf_random.cv_results_)

这是你想要的吗?

cv_results_ 显示了所有拆分和所有迭代的训练和测试的准确性。

【讨论】:

感谢您的回答。但我还是有些疑惑。我需要 X_train、y_train、X_test、y_test 集来执行以下代码: y_train_pred = clf_random.predict(X_train) train_accuracy = np.mean(y_train_pred.ravel() == y_train.ravel())*100 train_accuracy_list.append( train_accuracy) y_test_pred = clf_random.predict(X_test) test_accuracy = np.mean(y_test_pred.ravel() == y_test.ravel())*100 我知道一切都在 RandomizedSearchCV 中完成。但我需要预测测试数据集和训练数据集的准确性。 您需要使用 StratifiedKFold 执行此操作还是仅用于固定训练和测试? 我更喜欢使用 stratifiedKFold 来避免过度拟合,而不是静态地创建训练集和测试集。 谢谢安娜!我没有看到我认为这是我需要的更新!我会告诉你...谢谢!!!【参考方案2】:
params =  
    'n_estimators': [200, 500],
    'max_features': ['auto', 'sqrt', 'log2'],
    'max_depth' : [4,5,6,7,8],
    'criterion' :['gini', 'entropy']

【讨论】:

【参考方案3】:
cross_val = StratifiedKFold(n_splits=5)
index_iterator = cross_val.split(X_train, y_train)
clf = RandomForestClassifier()
clf_random = RandomizedSearchCV(estimator = clf, param_distributions = params, n_iter =100, cv = cross_val,
                            verbose=2, random_state=42, n_jobs = -1,scoring='roc_auc')
clf_random.fit(X, y)

【讨论】:

以上是关于如何使用 RandomizedSearchCV 正确实现 StratifiedKFold的主要内容,如果未能解决你的问题,请参考以下文章

Scikit:如何检查对象是 RandomizedSearchCV 还是 RandomForestClassifier?

我如何知道 RandomizedSearchCV 测试了哪些参数?

如何在 RandomizedSearchCV 中输入自定义指标?

如何为 RandomizedSearchCV 使用预定义拆分

sklearn:在 RandomizedSearchCV 中使用管道?

RandomizedSearchCV 溢出错误:无法将“int”放入索引大小的整数中