用Python手撸逻辑回归从乳腺癌数据集到95%准确率的癌细胞分类模型在医疗诊断领域机器学习正在发挥越来越重要的作用。想象一下如果能够通过计算机程序快速准确地识别癌细胞将极大提高早期诊断的效率。今天我们就用Python从零开始实现一个逻辑回归模型在乳腺癌数据集上达到95%以上的分类准确率。不同于直接调用scikit-learn等现成库我们将仅使用NumPy一步步推导公式、编写代码深入理解逻辑回归的核心原理。这不仅适合机器学习初学者夯实基础也能帮助有经验的开发者更好地掌握算法本质。1. 理解乳腺癌数据集与逻辑回归乳腺癌数据集(Breast Cancer Wisconsin Diagnostic Dataset)是机器学习领域的经典二分类数据集包含569个样本每个样本有30个特征和1个标签。特征包括半径从中心到边缘点的平均距离纹理灰度值的标准偏差周长细胞核的周长面积细胞核的面积平滑度半径变化的局部差异以及其他25个形态学特征标签为0表示良性1表示恶性。我们的目标是建立一个模型根据这30个特征预测细胞是良性还是恶性。逻辑回归虽然名字中有回归但实际上是用于二分类的线性模型。其核心是通过sigmoid函数将线性组合的结果映射到(0,1)区间表示属于正类的概率$$ P(y1|x) \frac{1}{1e^{-(\theta^Tx)}} $$其中θ是模型参数x是特征向量。2. 数据准备与预处理在开始建模前我们需要对数据进行适当的预处理import numpy as np from sklearn.datasets import load_breast_cancer from sklearn.model_selection import train_test_split # 加载数据集 data load_breast_cancer() X data.data y data.target # 划分训练集和测试集 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42) # 特征标准化 def standardize(X): mean np.mean(X, axis0) std np.std(X, axis0) return (X - mean) / std X_train standardize(X_train) X_test standardize(X_test) # 添加偏置项 X_train np.c_[np.ones(X_train.shape[0]), X_train] X_test np.c_[np.ones(X_test.shape[0]), X_test]注意特征标准化是重要步骤可以加速梯度下降的收敛。添加偏置项(全1列)是为了将截距项θ₀纳入统一的矩阵运算。3. 实现逻辑回归核心组件3.1 Sigmoid函数sigmoid函数是逻辑回归的核心它将任意实数映射到(0,1)区间def sigmoid(z): return 1 / (1 np.exp(-z))3.2 损失函数逻辑回归使用交叉熵损失函数$$ J(\theta) -\frac{1}{m}\sum_{i1}^m [y^{(i)}\log(h_\theta(x^{(i)})) (1-y^{(i)})\log(1-h_\theta(x^{(i)}))] $$Python实现def compute_loss(y, y_pred): m y.shape[0] return -np.mean(y * np.log(y_pred) (1 - y) * np.log(1 - y_pred))3.3 梯度计算为了使用梯度下降优化参数我们需要计算损失函数对参数θ的梯度$$ \frac{\partial J(\theta)}{\partial \theta_j} \frac{1}{m}\sum_{i1}^m (h_\theta(x^{(i)}) - y^{(i)})x_j^{(i)} $$向量化实现def compute_gradient(X, y, y_pred): m y.shape[0] return (1/m) * X.T.dot(y_pred - y)4. 梯度下降优化有了上述组件我们可以实现梯度下降算法来优化模型参数def gradient_descent(X, y, learning_rate0.01, n_iters1000): m, n X.shape theta np.zeros(n) loss_history [] for i in range(n_iters): # 计算预测值 z X.dot(theta) y_pred sigmoid(z) # 计算损失 loss compute_loss(y, y_pred) loss_history.append(loss) # 计算梯度并更新参数 grad compute_gradient(X, y, y_pred) theta - learning_rate * grad # 每100次迭代打印损失 if i % 100 0: print(fIter {i}, Loss: {loss:.4f}) return theta, loss_history训练模型theta, loss_history gradient_descent(X_train, y_train, learning_rate0.1, n_iters3000)提示学习率(learning_rate)是重要超参数过大可能导致不收敛过小则收敛缓慢。可以通过观察损失函数下降曲线来调整。5. 模型评估与预测训练完成后我们需要评估模型在测试集上的表现def predict(X, theta): y_pred sigmoid(X.dot(theta)) return (y_pred 0.5).astype(int) # 测试集预测 y_pred predict(X_test, theta) # 计算准确率 accuracy np.mean(y_pred y_test) print(fTest Accuracy: {accuracy:.4f})为了更全面评估模型我们可以计算混淆矩阵实际\预测良性(0)恶性(1)良性(0)TNFP恶性(1)FNTP实现代码def confusion_matrix(y_true, y_pred): TP np.sum((y_true 1) (y_pred 1)) TN np.sum((y_true 0) (y_pred 0)) FP np.sum((y_true 0) (y_pred 1)) FN np.sum((y_true 1) (y_pred 0)) return np.array([[TN, FP], [FN, TP]]) cm confusion_matrix(y_test, y_pred) print(Confusion Matrix:) print(cm)6. 性能优化技巧要让模型达到95%以上的准确率我们可以尝试以下优化方法6.1 学习率调整尝试不同的学习率组合learning_rates [0.001, 0.01, 0.1, 0.5] for lr in learning_rates: theta, _ gradient_descent(X_train, y_train, learning_ratelr, n_iters1000) y_pred predict(X_test, theta) acc np.mean(y_pred y_test) print(fLR: {lr}, Accuracy: {acc:.4f})6.2 正则化加入L2正则化防止过拟合def compute_loss_reg(y, y_pred, theta, lambda_): m y.shape[0] loss -np.mean(y * np.log(y_pred) (1 - y) * np.log(1 - y_pred)) reg (lambda_ / (2 * m)) * np.sum(theta[1:]**2) # 不惩罚截距项 return loss reg def compute_gradient_reg(X, y, y_pred, theta, lambda_): m y.shape[0] grad (1/m) * X.T.dot(y_pred - y) grad[1:] (lambda_ / m) * theta[1:] # 不惩罚截距项 return grad6.3 特征工程尝试不同的特征组合或多项式特征# 添加交互特征 X_train_interact np.c_[X_train, X_train[:, 1:5].prod(axis1, keepdimsTrue)] X_test_interact np.c_[X_test, X_test[:, 1:5].prod(axis1, keepdimsTrue)]在实际项目中通过调整这些参数和技巧我们通常可以轻松达到95%以上的分类准确率。更重要的是通过这种从零实现的方式我们深入理解了逻辑回归的每个细节为学习更复杂的机器学习模型打下了坚实基础。