如何解决糖尿病预测代码中StandardScaler的TypeError参数错误?
糖尿病预测代码中的StandardScaler错误解决方法
问题背景
我从GitHub获取了一套糖尿病预测代码,代码可通过输入数据输出0或1判断是否患糖尿病。运行时原作者提示“X does not have valid feature names, but StandardScaler was fitted with feature names”,我误解提示给StandardScaler()传入了x_test参数,触发错误:
TypeError: StandardScaler.__init__() takes 1 positional argument but 2 were given
尝试传入x_train、y_train等参数仍报错,寻求解决方法。
错误原因分析
- StandardScaler用法错误:
StandardScaler的构造函数不需要传入数据集,它仅初始化缩放器,数据集应传入fit()方法 - 特征不匹配:模型训练用的是筛选后的3个特征(Glucose、Insulin、Age),但原代码中缩放器拟合了全部8个特征,导致后续预测时特征数量不一致
- 输入数据类型错误:用户输入的内容是字符串,未转为数值类型,无法进行标准化计算
修正后的完整代码
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split from sklearn.feature_selection import SelectKBest, chi2 from sklearn.metrics import accuracy_score, f1_score, confusion_matrix, classification_report, recall_score, auc, roc_curve from sklearn.preprocessing import StandardScaler from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import RandomForestClassifier from sklearn.svm import SVC from sklearn.neural_network import MLPClassifier # 加载数据 df = pd.read_csv('/Users/______/Desktop/Daiabities_1.csv', delimiter=";", decimal=",") pd.set_option('display.max_rows', 1000) pd.set_option('display.max_columns', 1000) pd.set_option('display.width', 1000) df.info() print(df.head(4)) print(df.shape) print(df.describe()) print(df.corr()) # 特征选择 x_full = df.iloc[:,0:8] y = df.iloc[:,-1] best_features = SelectKBest(score_func=chi2, k=3) fit = best_features.fit(x_full, y) df_scores = pd.DataFrame(fit.scores_) df_columns = pd.DataFrame(x_full.columns) features_scores = pd.concat([df_columns, df_scores], axis=1) features_scores.columns = ['Features', 'Score'] features_scores.sort_values(by='Score', ascending=False, inplace=True) print(features_scores) # 使用筛选后的特征 x = df[['Glucose', 'Insulin', 'Age']] y = df['Outcome'] x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.4, random_state=100) # 训练多个模型 models = [ LogisticRegression(), DecisionTreeClassifier(), RandomForestClassifier(), SVC(kernel='poly'), MLPClassifier(hidden_layer_sizes=(128), max_iter=100) ] for model in models: model.fit(x_train, y_train) y_pred = model.predict(x_test) print(f"Model {model}") print(f"Accuracy score: {accuracy_score(y_test, y_pred)}") print(f"F1 score: {f1_score(y_test, y_pred)}") print(f"Recall: {recall_score(y_test, y_pred)}") print(f"Confusion Matrix:\n{confusion_matrix(y_test, y_pred)}") print(f"Classification report:\n{classification_report(y_test, y_pred)}") print("-------------------------------------------------------") # ROC曲线绘制(仅支持返回概率的模型) try: y_score = model.predict_proba(x_test)[:,1] fpr, tpr, _ = roc_curve(y_test, y_score) roc_auc = auc(fpr, tpr) plt.plot(fpr, tpr, label=f"AUC={roc_auc:.2f}") plt.plot([0, 1], [0, 1], color='green', lw=2, linestyle='--') plt.title('ROC Curve') plt.ylabel('True Positive Rate') plt.xlabel('False Positive Rate') plt.legend(loc=4) plt.show() except AttributeError: print("当前模型不支持predict_proba,无法绘制ROC曲线") # 数据可视化 num_columns = len(df.columns.drop('Outcome')) num_rows = (num_columns + 1) // 2 # 小提琴图 plt.figure(figsize=(10, 5*num_rows)) for i, column in enumerate(df.columns.drop('Outcome')): plt.subplot(num_rows, 2, i+1) sns.violinplot(x=df[column], color='#2E63E6') plt.title(f'Violin plot of {column}') plt.tight_layout() plt.show() # KDE图 plt.figure(figsize=(10, 5*num_rows)) for i, column in enumerate(df.columns.drop('Outcome')): plt.subplot(num_rows, 2, i+1) sns.kdeplot(data=df[column], fill=True, color='#36CD40') plt.title(f'KDE plot of {column}') plt.tight_layout() plt.show() # 配对图 sns.pairplot(df, hue='Outcome', markers=["o", "s"], palette=['blue','lightgreen']) plt.show() # 预测模块 try: gluc = float(input("请输入葡萄糖含量:")) insu = float(input("请输入胰岛素水平:")) age = float(input("请输入年龄:")) # 仅保留模型训练用的3个特征 input_selected = [gluc, insu, age] input_data_numpy = np.asarray(input_selected).reshape(1, -1) # 正确初始化StandardScaler并拟合训练特征 scaler = StandardScaler() scaler.fit(x_train) std_data = scaler.transform(input_data_numpy) print(f"标准化后的输入数据:{std_data}") # 训练SVM分类器 classifier = SVC(kernel="linear") classifier.fit(x_train, y_train) prediction = classifier.predict(std_data) print(f"预测结果:{prediction}") if prediction[0] == 0: print("该人员未患糖尿病") else: print("该人员患有糖尿病") except ValueError: print("请输入有效的数值类型数据")
关键修正点说明
- StandardScaler正确使用:先无参实例化
StandardScaler(),再用fit()传入训练集数据(和模型训练用的特征一致) - 特征一致性:模型训练、缩放器拟合、输入预测都统一使用筛选后的3个特征(Glucose、Insulin、Age),避免特征数量不匹配
- 输入数据处理:将用户输入转为
float类型,确保能进行标准化计算 - 解决特征名警告:保持输入缩放器的是带列名的DataFrame(x_train),后续传入数组时自动匹配特征数量,避免警告
内容的提问来源于stack exchange,提问作者Vlada b
相关产品推荐
相关产品推荐

