python - 具有 PredefinedSplit 评分的 Sklearn GridSearch 与独立分类器不匹配
问题描述
我正在使用 sklearn GridSearch 使用预定义的验证集查找随机森林分类的最佳参数。GridSearch 返回的最佳估计器的分数与训练具有相同参数的单独分类器获得的分数不匹配。
数据拆分定义
X = pd.concat([X_train, X_devel])
y = pd.concat([y_train, y_devel])
test_fold = -X.index.str.contains('train').astype(int)
ps = PredefinedSplit(test_fold)
GridSearch 定义
n_estimators = [10]
max_depth = [4]
grid = {'n_estimators': n_estimators, 'max_depth': max_depth}
rf = RandomForestClassifier(random_state=0)
rf_grid = GridSearchCV(estimator = rf, param_grid = grid, cv = ps, scoring='recall_macro')
rf_grid.fit(X, y)
分类器定义
clf = RandomForestClassifier(n_estimators=10, max_depth=4, random_state=0)
clf.fit(X_train, y_train)
召回是使用 sklearn.metrics.recall_score 显式计算的
y_pred_train = clf.predict(X_train)
y_pred_devel = clf.predict(X_devel)
uar_train = recall_score(y_train, y_pred_train, average='macro')
uar_devel = recall_score(y_devel, y_pred_devel, average='macro')
网格搜索
uar train: 0.32189884516029466
uar devel: 0.3328299259976279
随机森林:
uar train: 0.483040291148839
uar devel: 0.40706644557392435
这种不匹配的原因是什么?
解决方案
这里有多个问题:
你的输入参数
recall_score
是相反的。实际正确的顺序是:recall_score(y_true, y_test)
但你正在做:
recall_score(y_pred_train, y_train, average='macro')
更正为:
recall_score(y_train, y_pred_train, average='macro')
你正在做
rf_grid.fit(X, y)
网格搜索。这意味着在找到最佳参数组合后,GridSearchCV 将适合整个数据(整个 X,忽略 ,PredefinedSplit
因为它仅在交叉验证期间用于搜索最佳参数)。因此,从本质上讲,来自的估算者GridSearchCV
将看到整个数据,因此分数将与您获得的分数不同clf.fit(X_train, y_train)
推荐阅读
- python - 使用 Python 在 Postgres 数据库中插入一行 - 由于插入语句的结构中的某些内容而无法正常工作?也许
- python - 使用 Pandas 合并两个 DataFrame
- processing - 生成一个模式并在偶数行的图像之间的奇数行上渲染每个图像,使用处理
- javascript - 在 css 中转换 translateY 而不实际移动元素
- c# - 如果windbg附加到挂钩全局鼠标事件的进程,鼠标滞后
- python - 当我使用我的 discord.py 机器人时,我不断收到这个 Heroku 错误。我使用的是 Heroku 的 github 存储库,而不是工具带
- python - 让 requests.get() 等到页面完全加载?
- python - Selenium Python:单击包含 JavaScript 的 onclick 元素
- node.js - 推送通知 - 模型不是构造函数
- r - 样本集 70 并从 7 列中选择 3 列作为子集