在 GridSearchCV 中使用 sample_weight
Posted
技术标签:
【中文标题】在 GridSearchCV 中使用 sample_weight【英文标题】:Using sample_weight in GridSearchCV 【发布时间】:2012-10-14 15:21:48 【问题描述】:是否可以执行 GridSearchCV
(以获得最佳 SVM 的 C)并使用 scikit-learn 指定 sample_weight
?
这是我的代码和我遇到的错误:
gs = GridSearchCV(
svm.SVC(C=1),
[
'kernel': ['linear'],
'C': [.1, 1, 10],
'probability': [True],
'sample_weight': sw_train,
]
)
gs.fit(Xtrain, ytrain)
>> ValueError:估计器 SVC 的参数 sample_weight 无效
编辑:我通过获取最新的 scikit-learn 版本并使用以下内容解决了这个问题:
gs.fit(Xtrain, ytrain, fit_params='sample_weight': sw_train)
【问题讨论】:
如果您有答案,请将其作为答案发布并接受。否则,问题就会悬而未决。 我确认fit_params
技巧是正确的答案。请回答你自己并验证你的答案。
@ogrisel 会不会导致 fit
被调用时使用每个折叠的整个权重列表,而不仅仅是折叠中数据点的权重?
这是一个很好的评论,但这种情况实际上是由内部交叉验证例程正确处理的:github.com/scikit-learn/scikit-learn/blob/master/sklearn/…
@ogrisel 很好的发现,谢谢。
【参考方案1】:
只是想解决这个长期悬而未决的问题......
您需要获取最新版本的 SKL 并使用以下内容:
gs.fit(Xtrain, ytrain, fit_params='sample_weight': sw_train)
但是,将fit_params
传递给构造函数更符合文档:
gs = GridSearchCV(svm.SVC(C=1), ['kernel': ['linear'], 'C': [.1, 1, 10], 'probability': [True], 'sample_weight': sw_train], fit_params='sample_weight': sw_train)
gs.fit(Xtrain, ytrain)
【讨论】:
根据文档,fit_params
应该传递给构造函数,而不是 fit
方法
sw_train
的形状是什么?我试过sw_train=[1:1]
,但它不起作用。任何帮助表示赞赏。【参考方案2】:
以前的答案现在已经过时了。字典fit_params
应该传递给fit
方法。
来自GridSearchCV 的文档:
fit_params:字典,可选
传递给 fit 方法的参数。
自 0.19 版起已弃用:作为构造函数参数的 fit_params 在 0.19 版中已弃用,并将在 0.21 版中删除。而是将 fit 参数传递给 fit 方法。
【讨论】:
有没有人确认这可以与sample_weight
一起正常工作? GridSearchCV
使用 Xtrain
和 ytrain
的不同子集重复调用估计器的 fit()
方法。它是否每次都使用相应的样本权重子集?我猜它没有;它每次只调用fit(..., **fit_params)
。这对于 verbose
等与特定样本无关的参数非常有效。
我曾经对sample_weight
过去的工作方式有过类似的疑问。您可以在此处查看问题和答案;我认为这个问题的动机与你在这里表达的同样的担忧,但它有点老了。我不知道sklearn
的较新版本是否以更直观的方式工作。 ***.com/questions/49581104/…
谢谢。我进行了更多搜索,发现github.com/scikit-learn/scikit-learn/issues/2879,这表明GridSearchCV
现在被编程为在每次调用估计器的fit()
方法时传递sample_weight
的正确子集。人们仍然不满意,因为没有简单的方法可以使用sample_weight
在GridSearchCV
中进行评分。
啊!有趣的。很高兴知道至少在这方面取得了一些进展。我链接的线程中的解决方案是功能性的,但在简单性方面确实有一些不足之处。【参考方案3】:
在0.16.1版本中,如果使用Pipeline
,需要将参数传递给GridSearchCV
构造函数:
clf = pipeline.Pipeline([('svm', svm_model)])
model = grid_search.GridSearchCV(estimator = clf, param_grid=param_grid,
fit_params='svm__sample_weight': sw_train)
【讨论】:
这里是讨论,我注意到这种行为仍然存在于 0.17 sourceforge.net/p/scikit-learn/mailman/message/34191031sw_train
的形状是什么?我试过sw_train=[1:1]
,但它不起作用。任何帮助表示赞赏。
@AzizJaved 参数可以在特定classifier 的文档中找到。在这种情况下,它是一个一维数组,每个样本有一个权重(示例)。【参考方案4】:
以下适用于 Sklearn 0.23.1,
grid_cv = GridSearchCV(clf, param_grid=param_grid,
scoring='recall', n_jobs=-1, cv=10)
grid_cv.fit(x_train_orig, y=y_train_orig,
sample_weight=my_sample_weights)
【讨论】:
【参考方案5】:OP 的编辑和其他答案并不完全正确。虽然拟合 fit_params='sample_weight': weights
有效,但这些权重不会用于计算验证损失! (github issue)。
因此,交叉验证将报告未加权损失,因此超参数调整可能会被引导到错误的方向。
这是我使用准确性作为指标对类权重进行交叉验证的解决方法。还应该与其他指标一起使用。
from sklearn.metrics import accuracy_score
from sklearn.utils import compute_sample_weight
from sklearn.metrics import make_scorer
def weighted_accuracy_eval(y_pred, y_true, **kwargs):
balanced_class_weights_eval = compute_sample_weight(
class_weight='balanced',
y=y_true
)
out = accuracy_score(y_pred=y_pred, y_true=y_true, sample_weight=balanced_class_weights_eval, **kwargs)
return out
weighted_accuracy_eval_skl = make_scorer(weighted_accuracy_eval)
gridsearch = GridSearchCV(
estimator=model,
scoring=weighted_accuracy_eval,
param_grid=paramGrid,
)
cv_result = gridsearch.fit(
X_train,
y_train,
fit_params=fit_params
)
【讨论】:
您能详细说明一下吗?在这种情况下,fit_params
应该是什么?是class_weight: weights_array
吗?这是否适合并使用指定的权重数组进行评估?我不清楚这段代码应该做什么。
如您所见,这是一个非常高级和复杂的示例。 OP 已经提供了一个答案以及其他答案,说“使用fit_params
,所以我在这里的答案确实是另一种情况。如果我要写一个关于权重拟合的适当教程,然后解释我的解决方法,它会变成一篇中等文章。
尽管如此,fit_params
是一个参数字典,将传递给估计器的 .fit
方法。当使用 sklearn 管道与编写自定义循环时,您突然无法控制深层行为,例如API 不提供为不平衡训练指定 class_weights
的方法。但是您可以使用fit_params
所以,fit_params
中的 class_weights
应该符合 estimator.fit(..., class_weights=weights_array)
-- 参见此线程 ***.com/questions/30972029/…以上是关于在 GridSearchCV 中使用 sample_weight的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Scikit-Learn 的详细输出中估计 GridSearchCV 的进度?
为啥在 GridSearchCV 中使用 StandardScaler 时会得到不同的结果?
我正在使用 GridSearchCV 训练一个 Ann 机器学习模型,但在 gridSearchCV 中遇到了 IndexError