Iris数据集Logistic回归准确率为1的问题排查及解决方案求助
Iris数据集Logistic Regression准确率=1的问题排查与修复方案
经理指出:“K fold validation无法解决train-test split问题,它仅用于事后验证,请查阅正确的划分方法。”
问题核心分析
在Iris数据集上得到准确率=1的结果并非模型性能优异,而是数据划分或流程存在漏洞导致的异常。K-fold交叉验证仅用于评估模型在训练集上的稳定性,无法替代正确的训练-测试集划分逻辑,这也是你当前问题未解决的关键原因。
可能的问题原因
数据集划分逻辑错误
- Iris数据集默认按类别排序(前50条为setosa,中间50条为versicolor,后50条为virginica),若直接按固定位置切割(如前120条训练、后30条测试),测试集会完全属于单一类别,模型只需简单匹配特征就能得到全对结果。
- 手动划分时未打乱数据,或使用
train_test_split时关闭了shuffle参数,导致训练集与测试集类别分布严重失衡。
数据泄露
- 预处理阶段(如标准化、归一化)直接使用整个数据集的统计量(均值、标准差),而非仅基于训练集计算,导致测试集信息提前泄露给模型。
训练数据混入测试集
- 代码失误导致训练时传入了整个数据集,而非仅训练集数据,模型直接“记住”了测试集的所有样本。
排查步骤
检查类别分布
运行以下代码确认训练集与测试集的类别分布是否均衡:import pandas as pd from sklearn.datasets import load_iris iris = load_iris() df = pd.DataFrame(data=iris.data, columns=iris.feature_names) df['target'] = iris.target # 替换为你实际的划分索引 train_df = df.iloc[train_idx] test_df = df.iloc[test_idx] print("训练集类别分布:") print(train_df['target'].value_counts()) print("\n测试集类别分布:") print(test_df['target'].value_counts())若测试集仅包含单一类别,或与训练集类别完全重叠,即可确认划分逻辑错误。
核查预处理流程
检查是否存在“先预处理整个数据集,再划分训练测试集”的操作,这种做法必然导致数据泄露。验证训练代码
确认model.fit()方法传入的是训练集数据(X_train、y_train),而非整个数据集。
修复方案
正确划分数据集
使用train_test_split并开启打乱、分层抽样,保证训练集与测试集类别分布一致:from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split( iris.data, iris.target, test_size=0.2, random_state=42, stratify=iris.target # 按类别分层抽样,保证分布一致 )若手动划分,需先打乱索引再切割:
import numpy as np shuffled_indices = np.random.permutation(len(df)) train_size = int(0.8 * len(df)) train_idx = shuffled_indices[:train_size] test_idx = shuffled_indices[train_size:]规范预处理流程
仅基于训练集计算预处理统计量,再分别转换训练集与测试集:from sklearn.preprocessing import StandardScaler scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) # 仅在训练集上拟合 X_test_scaled = scaler.transform(X_test) # 用训练集的统计量转换测试集重新评估模型性能
用正确划分后的数据集训练模型,结合K-fold交叉验证做事后验证:from sklearn.linear_model import LogisticRegression from sklearn.model_selection import cross_val_score model = LogisticRegression(max_iter=200) model.fit(X_train_scaled, y_train) # 测试集准确率 test_acc = model.score(X_test_scaled, y_test) print(f"测试集准确率:{test_acc:.4f}") # K-fold交叉验证(训练集上的事后验证) cv_scores = cross_val_score(model, X_train_scaled, y_train, cv=5) print(f"交叉验证准确率均值:{cv_scores.mean():.4f},标准差:{cv_scores.std():.4f}")
关键提醒
K-fold交叉验证的作用是在训练集内部评估模型的稳定性,辅助调参,不能替代训练-测试集的划分。必须先完成独立的训练-测试集划分,再用K-fold对训练集做验证,避免数据泄露。
内容的提问来源于stack exchange,提问作者RISHAV BHARDWAJ
相关产品推荐
相关产品推荐

