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

手写数字识别:OneVsRest+LogisticRegression预测维度错误排查

问题根源与解决方案

1. 核心错误:predict()传错了数据

你调用ovr_model_best_fit.predict(y)时,把标签数组y当成了预测用的特征数据,完全搞反了用途:

  • 模型训练时,fit(X_train_scaled, y_train)里的X是785维的手写像素特征,y是0-9的数字标签
  • predict()需要传入特征数据(和训练时X同维度:N个样本×785特征),而不是标签数据

2. 代码里的其他逻辑错误

(1)数据拆分顺序混乱

原代码里train_test_split用到的y还没定义就调用了,而且筛选标签的条件冗余,正确顺序应该是:

# 筛选标签>7的样本(原条件(train['label']>3)&(train['label']>7)等价于label>7)
train = train.loc[train['label'] > 7]
# 先拆分特征和标签
y = train['label']
X = train.drop(['label'], axis=1)
# 再划分训练集测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.50, random_state=42)

(2)标准化对象错误

原代码用MinMaxScaler处理了带标签的X_train,应该只标准化特征矩阵:

min_max_scaler = MinMaxScaler()
X_train_scaled = min_max_scaler.fit_transform(X_train)
X_test_scaled = min_max_scaler.transform(X_test)  # 测试集复用训练集的缩放规则

3. 标签数据的正确用法

标签y(形状(4125,))不需要额外reshape,scikit-learn的分类模型直接接受1D数组作为标签,训练时直接传y_train即可。之前的维度报错,是因为你错误地把标签当成特征传入predict()导致的,不是标签本身的维度问题。

修正后的完整代码

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split, RandomizedSearchCV, cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.multiclass import OneVsRestClassifier
from sklearn.preprocessing import MinMaxScaler

# 加载数据
train = pd.read_csv("../data/DigitRecognizer/train.csv")
test = pd.read_csv("../data/DigitRecognizer/test.csv")

# 筛选标签>7的样本
train = train.loc[train['label'] > 7]

# 拆分特征与标签
X = train.drop(['label'], axis=1)
y = train['label']

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.50, random_state=42)

# 特征标准化
min_max_scaler = MinMaxScaler()
X_train_scaled = min_max_scaler.fit_transform(X_train)
X_test_scaled = min_max_scaler.transform(X_test)

# 模型与参数搜索
ovr_model = OneVsRestClassifier(LogisticRegression())
param_grid = {
    'estimator__max_iter': [2500, 4500, 6500, 9500, 14000],
    'estimator__C': [0.1, 1, 100, 200]
}
ovr_grid_param = RandomizedSearchCV(ovr_model, param_grid, cv=5, n_jobs=3, error_score="raise")
ovr_fit = ovr_grid_param.fit(X_train_scaled, y_train)

# 输出搜索结果
print("\nOVR最佳估算器:\n", ovr_fit.best_estimator_)
print("\nOVR最佳得分:\n", ovr_fit.best_score_)
print("\nOVR最佳参数:\n", ovr_fit.best_params_)

# 用最佳参数训练模型
ovr_model_best = OneVsRestClassifier(LogisticRegression(multi_class='ovr', C=200, max_iter=9500, solver='liblinear'))
ovr_model_best_fit = ovr_model_best.fit(X_train_scaled, y_train)

# 正确预测:传入测试集特征数据
ovr_model_best_pred = ovr_model_best_fit.predict(X_test_scaled)

# 交叉验证:传入标准化后的特征和标签
ovr_score = cross_val_score(ovr_model_best, X_train_scaled, y_train, cv=3, scoring="accuracy")
print("\n交叉验证准确率:\n", ovr_score)

关键提醒

  • 严格区分特征X(预测输入,维度N×特征数)和标签y(预测目标,1D数组)
  • 模型训练完成后,predict()必须传入和训练时X维度一致的特征数据,不能传标签
  • scikit-learn分类模型对标签的要求是1D数组,不需要额外reshape,只有特征数据需要是2D数组

内容的提问来源于stack exchange,提问作者Data Science Analytics Manager

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 20:47:54