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

如何解决糖尿病预测代码中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等参数仍报错,寻求解决方法。

错误原因分析

  1. StandardScaler用法错误:StandardScaler的构造函数不需要传入数据集,它仅初始化缩放器,数据集应传入fit()方法
  2. 特征不匹配:模型训练用的是筛选后的3个特征(Glucose、Insulin、Age),但原代码中缩放器拟合了全部8个特征,导致后续预测时特征数量不一致
  3. 输入数据类型错误:用户输入的内容是字符串,未转为数值类型,无法进行标准化计算

修正后的完整代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 06:32:03