在训练随机森林分类器时,我一直试图在scikit-learn中使用加权样本。当我直接将样本权重传递给分类器时,它很有效,例如RandomForestClassifier().fit(X,y,sample_weight=weights)
,但是当我尝试使用网格搜索为分类器找到更好的超参数时,我碰到了一堵墙:
要在使用grid参数时传递权重,用法为:
grid_search = GridSearchCV(RandomForestClassifier(), params, n_jobs=-1,
fit_params={"sample_weight"=weights})
问题是交叉验证器不知道样本权重,因此不会将它们与实际数据一起重新采样,因此调用grid_search.fit(X,y)
失败:交叉验证器创建X的子集和y,sub_X和sub_y以及最终使用classifier.fit(sub_X, sub_y, sample_weight=weights)
调用分类器,但现在权重尚未重新采样,因此抛出异常。
目前我已经在训练分类器之前通过对高重量样本进行过度采样来解决这个问题,但这是一个临时的解决方法。有关如何进行的任何建议吗?
答案 0 :(得分:5)
编辑:我从下面看到的分数似乎不太合适。这可能是因为,如上所述,即使在装配中使用重量时,它们也可能不会被用于评分。
现在看来已经解决了这个问题。我正在运行sklearn版本0.15.2。我的代码看起来像这样:
model = SGDRegressor()
parameters = {'alpha':[0.01, 0.001, 0.0001]}
cv = GridSearchCV(model, parameters, fit_params={'sample_weight': weights})
cv.fit(X, y)
希望有帮助(你和其他人看到这篇文章)。
答案 1 :(得分:3)
我声名太低,所以我无法对@xenocyon发表评论。我使用了sklearn 0.18.1,并且我在代码中也使用了管道。对我有用的解决方案是:
fit_params={'classifier__sample_weight': w}
其中w
是权重向量,classifier
是管道中的步骤名称。
答案 2 :(得分:2)
我建议编写自己的交叉验证参数选择,因为在python中只有10-15行代码(特别是使用scikit-learn中的kfold对象),而过采样可能是一个很大的瓶颈。