首页 > 解决方案 > 如何将预测应用于 xgboost 交叉验证

问题描述

在谷歌搜索了一段时间后,我觉得这可能是一个荒谬的问题,但它就是这样。如果我使用以下代码,我可以生成一个 xgb 回归模型,然后我可以使用它来拟合训练集并评估模型

xgb_reg = xgb.XGBRegressor(objective='binary:logistic',
                           gamme = .12, 
                           eval_metric = 'logloss',
                           #eval_metric = 'auc', 
                           eta = .068,
                           subsample = .78,
                           colsample_bytree = .76,
                           min_child_weight = 9,
                           max_delta_step = 5,
                           nthread = 4)

start = time.time()
xgb_reg.fit(X_train, y_train)
print(start-time.time())

y_pred = xgb_reg.predict(X_test)
print(log_loss(y_test, y_pred))

现在,我想更进一步,使用 kfold cv 来改进模型,所以我有了这个

data_dmatrix = xgb.DMatrix(data=X_train,label=y_train)
params = {'objective':'binary:logistic','eval_metric':'logloss','eta':.068,
          'subsample':.78,'colsample_bytree':.76,'min_child_weight':9,
          'max_delta_step':5,'nthread':4}
xgb_cv = cv(dtrain=data_dmatrix, params=params, nfold=5, num_boost_round=20, metrics = 'logloss',seed=42) 

但是,这会吐出一个数据框,我不能在测试集上使用 .predict() 。

我想我可能不理解这个的基本概念,但我希望我只是忽略了一些简单的东西。

标签: pythonscikit-learnxgboost

解决方案


kfold cv 本身并不能使模型更准确。在您使用 xgb 的示例中,需要指定许多超参数,例如 (subsample, eta),并且为了了解所选参数对看不见的数据的执行情况,我们使用 kfold cv 将数据划分为许多训练和测试样本并测量样本外的准确性。

我们通常会尝试这个参数的几个可能值,以及给出最低平均误差的值。在此之后,您将使用参数重新调整您的模型。这篇文章及其答案对此进行了讨论。

例如,下面我们运行类似于您所做的事情,我们只得到一组值的训练/测试错误:

import pandas as pd
import numpy as np
import xgboost as xgb
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_classification

X, y = make_classification(n_samples=500,class_sep=0.7)
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=0.33, random_state=42)

data_dmatrix = xgb.DMatrix(data=X_train,label=y_train)
params = {'objective':'binary:logistic','eval_metric':'logloss',
          'eta':0.01,
          'subsample':0.1}
xgb_cv = xgb.cv(dtrain=data_dmatrix, params=params, nfold=5, metrics = 'logloss',seed=42) 

                 train-logloss-mean  train-logloss-std  test-logloss-mean  test-logloss-std
0            0.689600           0.000517           0.689820          0.001009
1            0.686462           0.001612           0.687151          0.002089
2            0.683626           0.001438           0.684667          0.003009
3            0.680450           0.001100           0.681929          0.003604
4            0.678269           0.001399           0.680310          0.002781
5            0.675170           0.001867           0.677254          0.003086
6            0.672349           0.002483           0.674432          0.004349
7            0.668964           0.002484           0.671493          0.004579
8            0.666361           0.002831           0.668978          0.004200
9            0.663682           0.003881           0.666744          0.003598

最后一行是上一轮的结果,这是我们用于评估的结果。

eta如果我们测试(的多个值,subsample例如:

grid = pd.DataFrame({'eta':[0.01,0.05,0.1]*2,
'subsample':np.repeat([0.1,0.3],3)})

    eta  subsample
0  0.01        0.1
1  0.05        0.1
2  0.10        0.1
3  0.01        0.3
4  0.05        0.3
5  0.10        0.3

通常我们可以为此使用GridSearchCV,但下面是使用 xgb.cv 的东西:

def fit(x):
    params = {'objective':'binary:logistic',
              'eval_metric':'logloss',
              'eta':x[0],
              'subsample':x[1]}
    xgb_cv = xgb.cv(dtrain=data_dmatrix, params=params, 
    nfold=5, metrics = 'logloss',seed=42)
    return xgb_cv[-1:].values[0]

grid[['train-logloss-mean','train-logloss-std',
'test-logloss-mean','test-logloss-std']] = grid.apply(fit,axis=1,result_type='expand')

    eta  subsample  train-logloss-mean  train-logloss-std  test-logloss-mean  test-logloss-std
0  0.01        0.1            0.663682           0.003881           0.666744          0.003598
1  0.05        0.1            0.570629           0.012555           0.580309          0.023561
2  0.10        0.1            0.503440           0.017761           0.526891          0.031659
3  0.01        0.3            0.646587           0.002063           0.653741          0.004201
4  0.05        0.3            0.512229           0.008013           0.545113          0.018700
5  0.10        0.3            0.414103           0.012427           0.472379          0.032606

我们可以看到eta = 0.10subsample = 0.3给出最好的结果,所以接下来你只需要用这些参数重新拟合模型:

xgb_reg = xgb.XGBRegressor(objective='binary:logistic',
                           eval_metric = 'logloss',
                           eta = 0.1,
                           subsample = 0.3)

xgb_reg.fit(X_train, y_train)

推荐阅读