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

GridSearchCV输出nan分数及TypeError: fit()缺少必填参数'y'问题排查求助

解决GridSearchCV中的fit报错与score=nan问题

咱们一步步拆解你遇到的两个核心问题:TypeError: fit() missing 1 required positional argument: 'y'和所有交叉验证分数全为nan的情况。

1. 为什么会出现fit参数缺失的报错?

这是因为你自定义的Foo类违反了Sklearn Estimator的核心规则:fit方法必须返回自身(self)。

你当前的fit方法最后返回的是处理后的X,而不是类实例本身。当GridSearchCV调用estimator.fit(X_train, y_train)后,它期望得到一个训练好的Foo实例,结果拿到的却是一个numpy数组。后续流程中,GridSearchCV会尝试用这个“假estimator”继续执行操作,自然会抛出参数错误——因为数组根本没有fit方法,更别说接收y参数了。

修复方案:修改fit方法,最后返回self,同时把需要保留的训练数据存为实例属性:

def fit(self, X, y):
    # 先复制原始X,避免污染外部数据
    X_copy = X.copy().reshape(-1, 1)  # 转为二维数组,符合Sklearn输入规范
    X_, X_val, y_, y_val = train_test_split(X_copy, y, test_size=0.20, random_state=42)
    # 防止索引越界:取end和X长度的最小值
    end_idx = min(self.end, len(X_copy))
    for i in range(self.start, end_idx):
        X_copy[i] = X_copy[i]**2 * y[i]
    # 把处理后的X存为实例属性,供predict使用
    self.X_processed = X_copy
    return self

2. 为什么score全是nan?

这个问题的直接诱因是fit执行失败,交叉验证无法计算有效分数,只能返回nan。另外你的自定义评分函数也不符合Sklearn的要求:

Sklearn的make_scorer要求评分函数必须接受至少两个参数:y_true(真实标签)和y_pred(模型预测结果)(无监督场景可调整,但你这里属于监督任务)。而你的accuracy方法只接受一个参数x,这会导致GridSearchCV传递参数时不匹配,即使修复了fit,评分还是会出错。

修复评分函数:

def accuracy(self, y_true, y_pred):
    # 这里可以根据你的实际需求调整逻辑,以下是贴合你原逻辑的示例
    if y_pred > 50:
        return 100
    else:
        return 1

创建scorer时,直接传递类方法即可:

scoring = make_scorer(Foo.accuracy, greater_is_better=False)

3. 其他需要注意的细节

  • predict方法逻辑:你当前的predict直接取输入X的最大值,但没有应用训练时的处理逻辑(对指定索引的元素平方)。修复后可以在predict中复用训练时的处理规则,保证前后逻辑一致。
  • 输入维度问题:Sklearn要求输入的X是二维数组(形状为(n_samples, n_features)),你原来的X是一维的,所以需要在fit和predict中转为二维,避免潜在错误。

修复后的完整代码示例

import numpy as np
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import make_scorer
from sklearn.base import BaseEstimator
from sklearn.model_selection import train_test_split

class Foo(BaseEstimator):
    def __init__(self, start=0, end=0):
        self.start = start
        self.end = end
        self.X_processed = None  # 初始化实例属性

    def fit(self, X, y):
        X_copy = X.copy().reshape(-1, 1)
        X_, X_val, y_, y_val = train_test_split(X_copy, y, test_size=0.20, random_state=42)
        end_idx = min(self.end, len(X_copy))
        for i in range(self.start, end_idx):
            X_copy[i] = X_copy[i]**2 * y[i]
        self.X_processed = X_copy
        return self

    def predict(self, X):
        # 对测试数据应用相同的处理逻辑
        X_test = X.copy().reshape(-1, 1)
        end_idx = min(self.end, len(X_test))
        for i in range(self.start, end_idx):
            X_test[i] = X_test[i]**2
        val = np.max(X_test)
        return val

    def accuracy(self, y_true, y_pred):
        if y_pred > 50:
            return 100
        else:
            return 1

# 主程序
X = np.array(np.random.random(200)*100)
y = np.array(np.random.randint(2,size=200))
param_grid = {'start':[0, 10, 50], 'end':[60, 80, 100]}
foo = Foo()
scoring = make_scorer(Foo.accuracy, greater_is_better=False)
grid = GridSearchCV(foo, param_grid=param_grid, scoring=scoring, verbose = 3, cv=2, refit=True)
grid.fit(X, y)
print(grid.best_params_)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 00:12:30