使用sklearn糖尿病数据集出现AttributeError: columns,如何修复?
问题分析与修复方案
为什么会触发AttributeError: columns?
这个错误的原因很明确:你调用的diabetes.columns是pandas DataFrame专属的属性,但scikit-learn通过datasets.load_diabetes()返回的是一个Bunch对象(类似字典的特殊数据结构),它存储特征名称的字段是feature_names,而非columns——你混淆了sklearn内置数据集对象和pandas数据结构的用法啦!
另外还有个容易被忽略的逻辑问题:糖尿病数据集本质是回归任务(目标变量y是连续的血糖测量值),但你使用了分类模型(LogisticRegression、RandomForestClassifier),这相当于让模型去预测连续值的"类别",逻辑上不匹配任务需求,最终输出的"准确率"也没有实际参考价值。
修复方案
1. 修正特征名称的获取代码
直接把diabetes.columns[0:]替换为diabetes.feature_names,就能正确获取所有特征的名称了。
2. 替换为适配回归任务的模型(强烈推荐)
既然是预测连续值,应该使用回归模型,比如把LogisticRegression换成LinearRegression,RandomForestClassifier换成RandomForestRegressor,这样模型训练逻辑才符合任务目标。
下面是修正后的完整代码:
from sklearn import datasets from sklearn.model_selection import train_test_split from sklearn.preprocessing import MinMaxScaler from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LinearRegression # 替换为回归模型 from sklearn.ensemble import RandomForestRegressor # 替换为回归模型 # 加载数据集 diabetes = datasets.load_diabetes() X = diabetes.data y = diabetes.target # 划分训练测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) # 数据预处理(回归任务可按需使用) mms = MinMaxScaler() X_train_norm = mms.fit_transform(X_train) X_test_norm = mms.transform(X_test) stdsc = StandardScaler() X_train_std = stdsc.fit_transform(X_train) X_test_std = stdsc.transform(X_test) # 训练线性回归模型 lr = LinearRegression() lr.fit(X_train_std, y_train) # 回归模型用R²分数评估,而非分类的准确率 print('Training R² score:', lr.score(X_train_std, y_train)) print('Test R² score:', lr.score(X_test_std, y_test)) # 训练随机森林回归模型 forest = RandomForestRegressor(n_estimators=500, random_state=1) forest.fit(X_train, y_train) importances = forest.feature_importances_ print('Feature importances:', importances) # 正确获取特征名称 feature_labels = diabetes.feature_names print('Feature labels:', feature_labels)
补充小提示
- 如果你的实际需求是分类(比如把血糖值分成高/中/低几类),需要先对
y做离散化处理(比如用pandas的pd.cut()函数),再使用分类模型,但糖尿病数据集的默认任务是回归。 - 可以通过
print(diabetes.DESCR)查看数据集的详细描述,了解特征含义、目标变量定义等信息。
内容的提问来源于stack exchange,提问作者Karina Naranjo




