如何使用带有 GridSearchCV 对象的 TimeSeriesSplit 来调整 scikit-learn 中的模型?

Posted

技术标签:

【中文标题】如何使用带有 GridSearchCV 对象的 TimeSeriesSplit 来调整 scikit-learn 中的模型?【英文标题】:How do I use a TimeSeriesSplit with a GridSearchCV object to tune a model in scikit-learn? 【发布时间】:2018-03-25 18:10:23 【问题描述】:

我已经搜索了sklearn docs for TimeSeriesSplit 和docs for cross-validation,但找不到一个可行的示例。

我使用的是 sklearn 0.19 版。

这是我的设置

import xgboost as xgb
from sklearn.model_selection import TimeSeriesSplit
from sklearn.grid_search import GridSearchCV
import numpy as np
X = np.array([[4, 5, 6, 1, 0, 2], [3.1, 3.5, 1.0, 2.1, 8.3, 1.1]]).T
y = np.array([1, 6, 7, 1, 2, 3])
tscv = TimeSeriesSplit(n_splits=2)
for train, test in tscv.split(X):
    print(train, test)

给予:

[0 1] [2 3]
[0 1 2 3] [4 5]

如果我尝试:

model = xgb.XGBRegressor()
param_search = 'max_depth' : [3, 5]

my_cv = TimeSeriesSplit(n_splits=2).split(X)
gsearch = GridSearchCV(estimator=model, cv=my_cv,
                        param_grid=param_search)
gsearch.fit(X, y)

它给出:TypeError: object of type 'generator' has no len()

我得到了问题:GridSearchCV 正在尝试调用 len(cv)my_cv 是一个没有长度的迭代器。但是,docs for GridSearchCV 状态我可以使用

int,交叉验证生成器或可迭代的,可选

我尝试在不使用 .split(X) 的情况下使用 TimeSeriesSplit,但它仍然不起作用。

我确定我忽略了一些简单的事情,谢谢!

【问题讨论】:

尝试使用my_cv = [(train,test) for train, test in TimeSeriesSplit(n_splits=2).split(X)] 行得通,谢谢!但是该函数不应该与迭代器一起使用吗?当观察的数量很大时(如果折叠的数量很大,则更糟)我宁愿尽可能不将那些大数组保存在内存中 是的,应该。您应该在 scikit-learn github 页面上发布问题。 【参考方案1】:

原来问题是我使用的是来自sklearn.grid_searchGridSearchCV,它已被弃用。从sklearn.model_selection 导入GridSearchCV 解决了这个问题:

import xgboost as xgb
from sklearn.model_selection import TimeSeriesSplit, GridSearchCV
import numpy as np
X = np.array([[4, 5, 6, 1, 0, 2], [3.1, 3.5, 1.0, 2.1, 8.3, 1.1]]).T
y = np.array([1, 6, 7, 1, 2, 3])

model = xgb.XGBRegressor()
param_search = 'max_depth' : [3, 5]

tscv = TimeSeriesSplit(n_splits=2)
gsearch = GridSearchCV(estimator=model, cv=tscv,
                        param_grid=param_search)
gsearch.fit(X, y)

给予:

GridSearchCV(cv=<generator object TimeSeriesSplit.split at 0x11ab4abf8>,
       error_score='raise',
       estimator=XGBRegressor(base_score=0.5, colsample_bylevel=1, colsample_bytree=1, gamma=0,
       learning_rate=0.1, max_delta_step=0, max_depth=3,
       min_child_weight=1, missing=None, n_estimators=100, nthread=-1,
       objective='reg:linear', reg_alpha=0, reg_lambda=1,
       scale_pos_weight=1, seed=0, silent=True, subsample=1),
       fit_params=None, iid=True, n_jobs=1,
       param_grid='max_depth': [3, 5], pre_dispatch='2*n_jobs',
       refit=True, return_train_score=True, scoring=None, verbose=0)

【讨论】:

也许我做错了什么,但在我看来,从当前实现开始,my_cv = TimeSeriesSplit(n_splits=2).split(X) 行实际上应该更正为 my_cv = TimeSeriesSplit( n_splits=2)。否则会报错

以上是关于如何使用带有 GridSearchCV 对象的 TimeSeriesSplit 来调整 scikit-learn 中的模型?的主要内容,如果未能解决你的问题,请参考以下文章

sklearn.SVC 在使用带有小型平衡数据集的 GridSearchCV 时返回完全不同的预测(模型)

如何使用带有 SVC 估计器的 OneVsRestClassifier 的 GridSearchCV?

带有管道和 GridSearchCV 的 StandardScaler

使用带有保留验证的 GridsearchCV ()

如何将两个估计器对象传递给 sklearn 的 GridSearchCV,以便它们在每个步骤中具有相同的参数?

sklearn - 如何从传递给 GridSearchCV 的管道中检索 PCA 组件和解释方差