LogisticRegressionCV 用 f1_macro 报 pos_label 重复:评分器重建冲突
scikit-learn1.9二分类使用LogisticRegressionCV和字符串f1_macro时,内置评分器的pos_label与交叉验证重建参数冲突。1.9.1仍保留该路径,可明确创建不预置pos_label的宏平均评分器。
二分类任务中,LogisticRegressionCV(scoring="f1_macro") 在拟合时抛出 make_scorer() got multiple values for keyword argument 'pos_label'。如果正在使用 scikit-learn 1.9,先检查内部评分器重建,而不是去改特征矩阵的列数。
这项回归明确出现在 1.9.0,正式 1.9.1 也仍保留相关组合:内置 f1_macro 评分器预置了 pos_label=None,交叉验证的二分类分支重建评分器时又加入一份 pos_label。两份关键字在函数调用处冲突,错误发生在真正计算该项分数之前。
保留宏平均指标,明确构建评分器
对于标签为 0、1 的二分类任务,可以显式创建只带宏平均参数、不预置 pos_label 的评分器:
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegressionCV
from sklearn.metrics import f1_score, make_scorer
X, y = make_classification(
n_samples=100, n_features=20, n_classes=2, random_state=0
)
macro_f1 = make_scorer(f1_score, average="macro")
model = LogisticRegressionCV(cv=3, random_state=0, scoring=macro_f1)
model.fit(X, y)
示例保留宏平均 F1,不把指标换成 accuracy 或二分类默认 F1。内部重建仍可能添加二分类正类参数,但不再与评分器已有的同名项冲突。实际项目应保留原来的 Cs、交叉验证划分、正则化和随机配置,而不是为了使用这段小例子重新生成训练集。
标签不是 0、1,或评分依赖额外权重、元数据路由和自定义响应方式时,需要检查自己的评分器契约。上面只覆盖明确的简单场景,不能把所有 scorer 重建错误都归为同一个重复参数。
不直接删除私有评分器字典里的项
不建议取得内置 scorer 后修改其 _kwargs,也不要编辑安装目录中的 _logistic.py。这些是私有实现状态,可能影响其他评分调用。通过公开的 make_scorer 构建清楚的指标配置,更容易核对参数与后续版本兼容。
把 scoring 整项删除虽然可能开始拟合,却改用另一个选优标准;选择出的正则化参数可能因此变化。宏平均会分别计算各类别再平均,不能仅因任务是二分类就默认改成只看某个正类的 F1。
这也不同于多指标之间共享概率缓存导致分数变化的问题。本题一个宏平均指标就能在调用处抛错,交换指标字典顺序并不能解决。
验收每折分数与最终选优结果
修正后使用原数据和同一组训练、验证索引,确认每折评分完成,分数确实按宏平均 F1 计算,并检查最终选择的参数与模型状态。不能只看 .fit() 返回就认定指标未变。
采用后续正式修正时,可比较字符串 f1_macro 与显式等价评分器,在相同划分与随机状态下的分数和选优结果。已有失败运行可能留下不完整对象,应重建并重新拟合,不沿用异常中断时的状态作为已训练模型。


