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

我的Logistic Regression模型持续输出相同预测结果,原因何在?

问题分析与解决

使用糖尿病数据集构建Logistic Regression模型时,无论输入何种参数均输出“Diabetes”,核心问题及修正方案如下:

核心问题

  1. 预测输入未做归一化:训练时用MinMaxScaler将特征缩放到[0,1]区间,但预测时直接传入原始数值,特征尺度与训练数据完全不符,导致模型输出异常。
  2. K折交叉验证使用错误:当前代码中Kfold循环仅保留最后一次划分的训练/测试集,未实现交叉验证的评估逻辑,反而增加变量覆盖风险。
  3. 全局变量滥用:大量使用全局变量存储模型、数据等,易引发逻辑混乱和变量意外覆盖。

修正后的代码

import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.model_selection import KFold

class DiabetesLogReg:
    def __init__(self, p, g, bp, st, i, bmi, dpf, age):
        # 初始化用户输入特征
        self.preg = p
        self.glucose = g
        self.bp = bp
        self.skin_thickness = st
        self.insulin = i
        self.bmi = bmi
        self.diabetes_pedigree = dpf
        self.age = age
        
        # 读取数据集
        self.df = pd.read_csv("/Users/aahan_bagga/Desktop/diabetes_data.csv")
        self.X = self.df.drop(["Outcome"], axis=1)
        self.Y = self.df["Outcome"]
        
        # 初始化模型与归一化器
        self.scaler = None
        self.model = None

    def preprocessing(self):
        # 单次划分训练/测试集
        X_train, X_test, Y_train, Y_test = train_test_split(
            self.X, self.Y, test_size=0.2, random_state=19, shuffle=True
        )
        
        # 归一化并保存归一化器
        self.scaler = MinMaxScaler()
        self.x_train_s = self.scaler.fit_transform(X_train)
        self.x_test_s = self.scaler.transform(X_test)
        self.Y_train = Y_train
        self.Y_test = Y_test

    def train(self):
        # 训练模型并保存
        self.model = LogisticRegression(max_iter=2000)
        self.model.fit(self.x_train_s, self.Y_train)
        y_pred = self.model.predict(self.x_test_s)
        return f"{accuracy_score(self.Y_test, y_pred) * 100:.1f}%"
    
    def diabetes_pred(self):
        # 构造输入特征并做归一化转换
        input_features = [
            [self.preg, self.glucose, self.bp, self.skin_thickness, 
             self.insulin, self.bmi, self.diabetes_pedigree, self.age]
        ]
        input_scaled = self.scaler.transform(input_features)
        
        # 预测并返回结果
        prob = self.model.predict_proba(input_scaled)
        print(prob)
        return "Diabetes" if prob[0,1] > 0.5 else "No Diabetes"
    
    def evaluate_with_kfold(self, n_splits=9):
        # 正确实现K折交叉验证(避免数据泄露)
        scores = []
        kf = KFold(n_splits=n_splits, shuffle=True, random_state=19)
        
        for train_idx, test_idx in kf.split(self.X):
            X_train, X_test = self.X.iloc[train_idx], self.X.iloc[test_idx]
            Y_train, Y_test = self.Y.iloc[train_idx], self.Y.iloc[test_idx]
            
            scaler = MinMaxScaler()
            X_train_scaled = scaler.fit_transform(X_train)
            X_test_scaled = scaler.transform(X_test)
            
            model = LogisticRegression(max_iter=2000)
            model.fit(X_train_scaled, Y_train)
            scores.append(accuracy_score(Y_test, model.predict(X_test_scaled)))
        
        avg_score = sum(scores)/len(scores)
        return f"Average K-fold accuracy: {avg_score*100:.1f}%"

# 测试示例
d = DiabetesLogReg(2,126,45,23,340,30,0.12,29)
d.preprocessing()
print(d.train())
print(d.diabetes_pred())
# 可选:评估K折交叉验证准确率
# print(d.evaluate_with_kfold())

关键修正点说明

  • 归一化复用:保存训练时的MinMaxScaler,预测时用同一转换器处理输入数据,保证特征尺度一致。
  • 实例属性替代全局变量:用self.xxx存储模型、数据、归一化器,避免全局变量引发的逻辑混乱。
  • 正确的K折交叉验证:在每个折内单独拟合归一化器,避免数据泄露,同时计算平均准确率评估模型性能。

内容的提问来源于stack exchange,提问作者JiffyTec

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 16:26:14