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

手动实现Logistic Regression:损失不收敛且模型效果差排查求助

问题诊断与修复建议

你的Logistic回归实现和训练流程存在多处关键问题,导致模型不收敛、效果极差,具体如下:

1. 特征未做标准化处理

SGD对特征尺度极其敏感,不同特征的数值范围差异会导致梯度更新震荡,难以找到合适的学习率。你的Notebook中导入了StandardScaler但完全没有使用,这是损失不收敛的核心原因之一。

修复:在划分训练测试集后,对特征(除手动添加的偏置项)做标准化:

scaler = StandardScaler()
# 跳过第一列的偏置项(全为1)
X_train[:, 1:] = scaler.fit_transform(X_train[:, 1:])
X_test[:, 1:] = scaler.transform(X_test[:, 1:])

2. SGD仅遍历了一轮训练数据

你的fit方法只循环了一次训练样本(1个epoch),SGD需要多轮迭代才能逐步收敛,只跑一轮模型根本无法学到有效特征模式。

修复:修改fit方法,增加epoch参数并打乱样本顺序:

def fit(self, X, Y, eta=0.005, epochs=10, plot=False):
    if self.w is None:
        # 根据输入特征维度初始化权重
        self.w = np.random.randn(X.shape[1])
    if plot:
        loss_vec = np.zeros(epochs)
    for epoch in range(epochs):
        # 每轮打乱样本顺序,避免迭代顺序影响收敛
        idx = np.random.permutation(len(X))
        X_shuffled = X[idx]
        Y_shuffled = Y[idx]
        for x, y in zip(X_shuffled, Y_shuffled):
            z = np.dot(x, self.w)
            a = sigmoid(z)
            grad = x * (a - y)  # 简化梯度计算,与原代码等价
            self.w -= eta * grad
        if plot:
            loss_vec[epoch] = self.log_loss(X, Y)
    if plot:
        plt.plot(loss_vec)
        plt.xlabel('# of epochs')
        plt.ylabel('Loss')

3. 混淆矩阵计算与指标映射完全错误

你的conf_matrix方法中,混淆矩阵的位置定义和后续指标计算完全不匹配:

  • 代码注释与实际计算逻辑矛盾,后续Notebook又错误地将矩阵位置对应到指标,导致灵敏度、特异性等所有指标计算错误。
  • 混淆矩阵标准定义:行是真实标签,列是预测标签,conf_mat[0,0]为TN(真阴性),conf_mat[0,1]为FP(假阳性),conf_mat[1,0]为FN(假阴性),conf_mat[1,1]为TP(真阳性)。

修复:重写conf_matrix方法:

def conf_matrix(self, x, y):
    conf_mat = np.zeros((2, 2), dtype=int)
    y_pred = self.predict(x)
    conf_mat[0, 0] = np.sum((y == 0) & (y_pred == 0))  # TN
    conf_mat[0, 1] = np.sum((y == 0) & (y_pred == 1))  # FP
    conf_mat[1, 0] = np.sum((y == 1) & (y_pred == 0))  # FN
    conf_mat[1, 1] = np.sum((y == 1) & (y_pred == 1))  # TP
    return conf_mat

同时修正Notebook中的指标映射:

TN = conf_matrix[0, 0]
FP = conf_matrix[0, 1]
FN = conf_matrix[1, 0]
TP = conf_matrix[1, 1]

4. AUC计算错误

Notebook中用准确率(log_reg.score的返回值)代替AUC,这是概念错误。AUC是ROC曲线下的面积,需要基于预测概率计算,而非分类准确率。

修复:使用sklearn.metrics.roc_auc_score计算:

y_pred_proba = log_reg.predict_proba(X_test)
AUC = roc_auc_score(y_test, y_pred_proba)

5. 权重初始化硬编码维度

ManualLogisticRegression的__init__中硬编码了权重维度为5:self.w = np.random.randn(5),如果输入数据的特征数(加偏置)不是5,会直接报错,完全不通用。

修复:在fit方法中根据输入X的特征数动态初始化权重(已包含在上述fit方法的修复代码中)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 21:59:58