手动实现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
相关产品推荐
相关产品推荐

