2014-02-19 71 views
7

我一直试图在scikit-learn中使用加权样本,同时训练随机森林分类器。当我直接将样本权重传递给分类器时,效果很好。 RandomForestClassifier().fit(X,y,sample_weight=weights),但是当我尝试了网格搜索,以找到更好的超参数进行分类,我碰了壁:scikit-learn中的样本权重在交叉验证中破裂

要使用电网参数时传递的权重,用法:

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)调用,但现在重量未被重新采样,因此引发异常。

现在我已经在训练分类器之前通过对高重量样本进行过采样来解决这个问题,但这只是一个临时解决方法。有关如何进行的任何建议?

回答

2

我会建议编写自己的交叉验证参数选择,因为它只是python中的10-15行代码(特别是使用scikit-learn中的kfold对象),而过采样可能是一个很大的瓶颈。

+1

问题是GridSearchCV在其代码中嵌入了交叉验证。我没有修改的问题,但这样做似乎很脏。作为一个元问题,两种方法(重采样和加权)实际上是否等价?嗯,看起来有点看起来,它似乎不是,但也都工作:http://statistics.berkeley.edu/sites/default/files/tech-reports/666.pdf –

+1

我开始修改超参数搜索(grid_search.py​​中的'fit_grid_point')将类权重考虑在内,然后我意识到scikit-learn中还存在另一个明显的缺失:交叉验证中的得分不会考虑类权重(我更关心评估错误时将少数群体分类错误)。这一切都促使我重新取样,只有在我遇到性能问题时才正确解决这个问题。 –

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) 

希望可以帮助(您和其他人看到这篇文章)。

2

我的信誉太少,所以我无法对@xenocyon发表评论。我使用sklearn 0.18.1,我也在代码中使用pipeline。为我工作的解决方案是:

fit_params={'classifier__sample_weight': w}其中w是权重向量和classifier是管道中的步骤名称。

+0

这是为我做的!真是太棒了。 – bwest87