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

如何在无监督学习的GridSearchCV中使用自定义评分函数

无监督聚类模型GridSearchCV自定义评分函数解决方案

问题背景

想用GridSearchCV调优DBSCAN这类无监督聚类模型的超参数,自定义轮廓系数作为评分指标,但遇到两个报错:

  • TypeError: my_custom_function() takes 2 positional arguments but 3 were given
  • AttributeError: 'DBSCAN' object has no attribute 'predict'

错误原因与修复方法

  1. TypeError 修复
    GridSearchCV会给评分函数传递3个参数:模型实例、特征数据X、标签y(无监督场景下y为None),哪怕你用不上y,自定义函数也必须把它作为参数声明。

  2. AttributeError 修复
    DBSCAN属于无监督密度聚类算法,没有predict方法,要获取聚类标签,得先让模型拟合当前数据,再通过labels_属性提取结果。


完整可运行代码

from sklearn.datasets import make_blobs
from sklearn.model_selection import GridSearchCV
from sklearn.cluster import DBSCAN
from sklearn.metrics import silhouette_score, make_scorer

# 自定义轮廓系数评分函数
def silhouette_scorer(estimator, X, y=None):
    # 拟合数据获取聚类标签
    estimator.fit(X)
    labels = estimator.labels_
    # 处理全噪声的极端情况,避免silhouette_score报错
    unique_labels = set(labels)
    if len(unique_labels) == 1 and -1 in unique_labels:
        return -1.0
    return silhouette_score(X, labels)

# 用make_scorer包装自定义函数,明确评分越高越好
custom_scorer = make_scorer(silhouette_scorer, greater_is_better=True)

# 生成测试数据集
X, _ = make_blobs(n_samples=500, centers=3, random_state=42)

# 初始化模型与待调参网格
dbscan = DBSCAN()
param_grid = {'eps': [0.1*i for i in range(1,6)], 'min_samples': [2,3,4]}

# 初始化网格搜索,传入自定义评分器
grid_search = GridSearchCV(estimator=dbscan, param_grid=param_grid, scoring=custom_scorer, cv=3)
grid_search.fit(X)

# 输出最优结果
print("最优参数组合:", grid_search.best_params_)
print("最优轮廓系数得分:", grid_search.best_score_)

关键细节说明

  • 用make_scorer包装是scikit-learn的标准操作,通过greater_is_better=True告诉网格搜索:轮廓系数越高,模型效果越好。
  • 增加了全噪声场景的判断:如果所有样本都被标记为噪声(labels全是-1),直接返回最低分-1.0,避免silhouette_score因聚类数量为1抛出异常。
  • GridSearchCV会自动完成交叉验证的数据集拆分,无需手动处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 04:20:32