首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何计算cv_results_和best_score_的测试分数?

如何计算cv_results_和best_score_的测试分数?
EN

Stack Overflow用户
提问于 2021-03-23 16:53:15
回答 1查看 745关注 0票数 2

我正在使用来自scikit-optimizescikit-optimize来优化一个XGBoost模型,以适应我拥有的一些数据。虽然模型很适合,但我对诊断信息中所提供的分数感到困惑,无法复制它们。

下面是一个使用波士顿房价数据集来说明我的观点的示例脚本:

代码语言:javascript
复制
from sklearn.datasets import load_boston

import numpy as np
import pandas as pd

from xgboost.sklearn import XGBRegressor

from skopt import BayesSearchCV
from skopt.space import Real, Categorical, Integer
from sklearn.model_selection import KFold, train_test_split 

boston = load_boston()

# Dataset info:
print(boston.keys())
print(boston.data.shape)
print(boston.feature_names)
print(boston.DESCR)

# Put data into dataframe and label column headers:

data = pd.DataFrame(boston.data)
data.columns = boston.feature_names

# Add target variable to dataframe

data['PRICE'] = boston.target

# Split into X and y

X, y = data.iloc[:, :-1],data.iloc[:,-1]

# Split into training and validation datasets 

X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42, shuffle = True) 

# For cross-validation, split training data into 5 folds

xgb_kfold = KFold(n_splits = 5,random_state = 42)

# Run fit

xgb_params = {'n_estimators': Integer(10, 3000, 'uniform'),
               'max_depth': Integer(2, 100, 'uniform'),
               'subsample': Real(0.25, 1.0, 'uniform'),
               'learning_rate': Real(0.0001, 0.5, 'uniform'),
               'gamma': Real(0.0001, 1.0, 'uniform'),
               'colsample_bytree': Real(0.0001, 1.0, 'uniform'),
               'colsample_bylevel': Real(0.0001, 1.0, 'uniform'),
               'colsample_bynode': Real(0.0001, 1.0, 'uniform'),
               'min_child_weight': Real(1, 6, 'uniform')}

xgb_fit_params = {'early_stopping_rounds': 15, 'eval_metric': 'mae', 'eval_set': [[X_val, y_val]]}

xgb_pipe = XGBRegressor(random_state = 42,  objective='reg:squarederror', n_jobs = 10)

xgb_cv = BayesSearchCV(xgb_pipe, xgb_params, cv = xgb_kfold, n_iter = 5, n_jobs = 1, random_state = 42, verbose = 4, scoring = None, fit_params = xgb_fit_params)

xgb_cv.fit(X_train, y_train)

运行此操作后,xgb_cv.best_score_为0.816,xgb_cv.best_index_为3。看看xgb_cv.cv_results_,我想为每个折叠找到最好的分数:

代码语言:javascript
复制
print(xgb_cv.cv_results_['split0_test_score'][xgb_cv.best_index_], xgb_cv.cv_results_['split1_test_score'][xgb_cv.best_index_], xgb_cv.cv_results_['split2_test_score'][xgb_cv.best_index_], xgb_cv.cv_results_['split3_test_score'][xgb_cv.best_index_], xgb_cv.cv_results_['split4_test_score'][xgb_cv.best_index_])

这意味着:

代码语言:javascript
复制
0.8023562337946979,
 0.8337404778903412,
 0.861370681263761,
 0.8749312273014963,
 0.7058815015739375

我不知道这里计算的是什么,因为在我的代码中,scoring设置为None。XGBoost的文档帮助不大,但是根据xgb_cv.best_estimator_.score?,它应该是预测值的R2。无论如何,当我手动计算fit中使用的数据的每一倍的分数时,我无法获得这些值:

代码语言:javascript
复制
# First, need to get the actual indices of the data from each fold:

kfold_indexes = {}
kfold_cnt = 0

for train_index, test_index in xgb_kfold.split(X_train):
    kfold_indexes[kfold_cnt] = {'train': train_index, 'test': test_index}
    kfold_cnt = kfold_cnt+1

# Next, calculate the score for each fold   
for p in range(5): print(xgb_cv.best_estimator_.score(X_train.iloc[kfold_indexes[p]['test']], y_train.iloc[kfold_indexes[p]['test']]))

这给了我以下几点:

代码语言:javascript
复制
0.9954929618573786
0.994844803666101
0.9963108152027245
0.9962274544089832
0.9931314653538819

BayesSearchCV是如何计算每个折叠的分数的,为什么我不能使用score函数复制它们?如果能在这个问题上提供任何帮助,我将不胜感激。

(同时,手工计算这些分数的平均值为:0.8156560.,而xgb_cv.best_score_则给出:0.8159277.不知道为什么这里有精度差异。)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-23 20:04:09

best_estimator_是重新修正的估计量,在选择了超参数后,整个训练集上都会有相应的参数,因此,在训练集的任何部分对其进行评分都是乐观的偏倚。要再现cv_results_,您需要将估计器修改到每个训练折叠,并将score修改为相应的测试折叠。

除此之外,XGBoost random_state似乎没有涵盖更多的随机性。还有一个参数seed;设置为我提供了一致的结果。(这里有一些旧的帖子(example)报告了类似的问题,即使使用了seed集,但是这些问题可能已经通过较新版本的xgb解决了。)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66767677

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档