sklearn逻辑回归/随机森林报multiclass-multioutput等错误求解
分类建模报错排查手册
核心前置代码问题(是后续绝大多数报错的根源)
- 特征与标签赋值完全错误:初始代码写了
X = dataset_df、Y = dataset_df,等于把完整数据集同时赋值给特征和标签,且后续拆分时使用的是未定义的小写变量y。正确写法:X为剔除预测标签列后的所有特征列,y为单独的待预测标签列,例如标签列名为target时,写法为:
如果标签是字符串类型,需要先用X = dataset_df.drop(columns=['target']) y = dataset_df['target']LabelEncoder转为数值型再传入模型。 - 首次训练/测试集拆分代码被包裹在单引号中,变成了不会执行的字符串,导致
X_train、X_test、y_train、y_test变量完全没有被正确生成,后续二次拆分验证集的逻辑直接基于未定义变量运行。 - 变量名大小写、命名不统一:一会定义
X_train_Std,一会调用不存在的X_test_std_pca_1;初始化的逻辑回归模型叫lr_classifier,后续调用时写的是从未定义的lr_2,必然触发未定义报错。 %matplotlib inline是Jupyter环境专属魔法命令,在普通.py脚本中运行需要删除该行。
各报错对应原因与修复方案
1. 报错:NameError: name 'lr_2' is not defined
- 原因:代码中从未定义名为
lr_2的模型变量,同时调用的X_test_std_pca_1也不存在,属于变量名拼写、命名不匹配。 - 修复:调用模型、数据集时统一使用你实际定义的变量名,不要随意更改变量名拼写和大小写。
2. 报错:ValueError: multiclass-multioutput is not supported
3. 报错:ValueError: y should be a 1d array, got an array of shape (3876, 16) instead.
- 两个报错为同一原因:传入模型的标签y是16列的完整数据集,不是要求的形状为
(样本数,)的1维单标签列。sklearn内置的逻辑回归、随机森林默认只支持单标签分类,传入多列二维标签时,模型会判定为多输出分类任务,默认配置不支持该场景就会抛出错误。 - 修复:按照前置问题中的方法正确拆分X和y,确保传入模型的y是1维单标签数组。
4. 报错:TypeError: unsupported format string passed to Series.format
- 原因:
(y_validation != y_pred).sum()返回的是pandas Series类型结果,不是纯Python数值,无法直接传入字符串格式化占位符;同时代码中混淆了y_pred和y_pred2两个预测结果变量。 - 修复:在
.sum()后追加.item()将pandas标量转为普通Python数值,同时统一预测结果变量名,修复后的代码如下:y_pred_val = lr_classifier.predict(sc.transform(X_validation)) mis_count = (y_validation != y_pred_val).sum().item() total_count = len(y_validation) print('Misclassified samples {0} out of {1}, i.e. {2:.2f}% accurate'.format( mis_count, total_count, (1 - mis_count/total_count)*100 ))
修正后的可运行基础框架
import pandas as pd import numpy as np from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler, LabelEncoder from sklearn.metrics import accuracy_score, roc_auc_score import matplotlib.pyplot as plt # 拆分特征与标签,替换'target'为你数据集实际的标签列名 X = dataset_df.drop(columns=['target']) y = dataset_df['target'] # 标签为字符串时执行编码 le = LabelEncoder() y = le.fit_transform(y) # 拆分训练/验证/测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=1) X_train, X_validation, y_train, y_validation = train_test_split(X_train, y_train, test_size=0.3, random_state=1) # 特征标准化:仅用训练集拟合scaler,验证/测试集直接transform sc = StandardScaler() sc.fit(X_train) X_train_Std = sc.transform(X_train) X_val_Std = sc.transform(X_validation) X_test_Std = sc.transform(X_test) # 初始化并训练模型 lr_classifier = LogisticRegression(C=1000, random_state=1) rf_classifier = RandomForestClassifier(max_depth=5, random_state=1) lr_classifier.fit(X_train_Std, y_train) rf_classifier.fit(X_train_Std, y_train) # 随机森林max_depth参数遍历 max_depth_params = [2, 3, 5, 10] for max_depth in max_depth_params: rf_tmp = RandomForestClassifier(max_depth=max_depth, random_state=1) rf_tmp.fit(X_train_Std, y_train) val_pred = rf_tmp.predict(X_val_Std) print(f'max depth param: {max_depth}, accuracy: {accuracy_score(y_validation, val_pred):.4f}') # 计算测试集AUC(二分类场景取正类概率,多分类需配置multi_class参数) lr_test_proba = lr_classifier.predict_proba(X_test_Std)[:, 1] print(f'逻辑回归测试集AUC: {roc_auc_score(y_test, lr_test_proba):.4f}')
内容的提问来源于stack exchange,提问作者CR. R
相关产品推荐
相关产品推荐

