You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用GridSearchCV为多分类Keras模型自定义评分的KerasClassifier问题

我之前也碰到过一模一样的问题!其实根本原因是sklearn默认的那些分类评分指标(比如F1、精确率)都是为二分类场景设计的,直接套用到多分类任务上就会因为参数不匹配报错。完全不用自己写网格搜索代码,靠sklearn自带的make_scorer工具就能完美解决,下面给你一步步讲怎么操作:

解决方法:用sklearn的make_scorer适配多分类评分

核心思路是:通过make_scorer工具,给多分类场景下的评分指标指定必要的参数(比如类别平均方式),把它包装成符合sklearn接口要求的评分器,再传给cross_val_score或GridSearchCV的scoring参数。

1. 基础用法:单自定义评分指标

下面是基于Iris数据集的可运行示例,演示如何用自定义F1、精确率指标做交叉验证:

from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_score, GridSearchCV
from sklearn.metrics import f1_score, precision_score, recall_score, make_scorer
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.wrappers.scikit_learn import KerasClassifier

# 加载Iris多分类数据集
iris = load_iris()
X, y = iris.data, iris.target

# 定义Keras多分类模型构建函数
def create_model():
    model = Sequential()
    model.add(Dense(8, input_dim=4, activation='relu'))
    model.add(Dense(3, activation='softmax'))  # 对应3个类别,softmax输出概率
    # 多分类损失函数选sparse_categorical_crossentropy(标签为整数格式)
    model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model

# 用KerasClassifier包装模型,适配sklearn的接口
model = KerasClassifier(build_fn=create_model, epochs=100, batch_size=5, verbose=0)

# 包装多分类F1评分器:指定average参数(可选macro/weighted/micro)
custom_f1_scorer = make_scorer(f1_score, average='macro')
# 执行交叉验证,现在不会报错了
f1_scores = cross_val_score(model, X, y, cv=5, scoring=custom_f1_scorer)
print(f"Macro F1分数: {f1_scores.mean():.4f} ± {f1_scores.std():.4f}")

# 同理,包装加权精确率评分器
custom_precision_scorer = make_scorer(precision_score, average='weighted')
precision_scores = cross_val_score(model, X, y, cv=5, scoring=custom_precision_scorer)
print(f"Weighted Precision分数: {precision_scores.mean():.4f} ± {precision_scores.std():.4f}")

2. 进阶用法:同时评估多个自定义评分

如果想在GridSearchCV里同时查看多个评分指标的结果,可以给scoring参数传一个字典,键是你自定义的评分名称,值是对应的make_scorer对象:

# 定义多个多分类评分器
scoring_dict = {
    'macro_f1': make_scorer(f1_score, average='macro'),
    'weighted_precision': make_scorer(precision_score, average='weighted'),
    'micro_recall': make_scorer(recall_score, average='micro')
}

# 网格搜索示例:调优batch_size参数
param_grid = {'batch_size': [5, 10, 15]}
# refit指定以哪个指标为基准选择最佳模型
grid = GridSearchCV(estimator=model, param_grid=param_grid, scoring=scoring_dict, cv=3, refit='macro_f1', verbose=1)
grid_result = grid.fit(X, y)

# 输出最佳结果
print(f"\n最佳Macro F1分数: {grid_result.best_score_:.4f}")
print(f"最佳参数组合: {grid_result.best_params_}")

# 查看所有评分的最优结果
print("\n各评分指标的最优值:")
for metric_name in scoring_dict.keys():
    best_metric = grid_result.cv_results_[f'mean_test_{metric_name}'].max()
    print(f"{metric_name}: {best_metric:.4f}")

关键注意事项

  • average参数的选择:
    • 'macro':对每个类别的指标取算术平均,不考虑类别样本数量差异
    • 'weighted':按类别样本数量加权平均,适合样本不均衡的场景
    • 'micro':把所有样本混在一起计算全局指标,等价于准确率(当所有类别都被关注时)
      根据你的业务需求选择合适的平均方式。
  • 模型输出匹配:确保Keras模型的输出是多分类格式(比如用softmax激活,输出维度等于类别数),损失函数要和标签格式匹配(整数标签用sparse_categorical_crossentropy,one-hot标签用categorical_crossentropy)。

这样就不用手动实现网格搜索或交叉验证逻辑,直接用sklearn原生工具就能完成多分类场景下的自定义评分需求啦!

内容的提问来源于stack exchange,提问作者Dan Brice

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:17:15