逻辑回归:像医生做诊断一样分类
想象你是一位医生,要根据患者的 体检数据(如年龄、血压、血糖)判断他们是否患有某种疾病(患病=1,健康=0)。逻辑回归就像你的“诊断公式”:将各项指标加权求和后,通过一个“概率转换器”(Sigmoid函数)输出患病概率。
核心步骤
-
数据准备:收集患者的体检数据(特征)和诊断结果(标签)。
-
模型搭建:定义“诊断公式”(线性层 + Sigmoid)。
-
训练模型:通过不断调整权重,让预测结果逼近真实标签。
-
预测:对新患者数据输出患病概率。
我们用PyTorch实现逻辑回归
1. 数据准备
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
# 生成模拟数据:100个样本,每个样本2个特征
X = torch.randn(100, 2) # 体检数据(如年龄、血糖)
y = (X[:, 0] + 2*X[:, 1] > 0).float() # 患病标签(简单线性决策边界)
# 可视化数据
plt.scatter(X[:, 0], X[:, 1], c=y, cmap='bwr')
plt.xlabel("Feature 1 (e.g., Age)")
plt.ylabel("Feature 2 (e.g., Blood Sugar)")
plt.title("Medical Diagnosis Data")
plt.show()
2. 定义模型
class LogisticRegression(nn.Module):
def __init__(self, input_dim):
super().__init__()
self.linear = nn.Linear(input_dim, 1) # 线性层
self.sigmoid = nn.Sigmoid() # 概率转换器
def forward(self, x):
return self.sigmoid(self.linear(x)) # 输出概率
model = LogisticRegression(input_dim=2)
print(model) # 输出模型结构
3. 定义损失函数和优化器
criterion = nn.BCELoss() # 二元交叉熵损失(用于二分类)
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
4.训练模型
epochs = 100
losses = []
for epoch in range(epochs):
# 前向传播
y_pred = model(X).squeeze() # 压缩维度:[100,1] → [100]
# 计算损失
loss = criterion(y_pred, y)
losses.append(loss.item())
# 反向传播
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 每10轮打印损失
if (epoch+1) % 10 == 0:
print(f"Epoch {epoch+1}, Loss: {loss.item():.4f}")
# 绘制损失曲线
plt.plot(losses)
plt.xlabel("Epoch")
plt.ylabel("Loss")
plt.title("Training Loss")
plt.show()
5.模型评估
# 预测概率转类别(>0.5为患病)
with torch.no_grad():
predictions = (model(X).squeeze() > 0.5).float()
# 计算准确率
accuracy = (predictions == y).float().mean()
print(f"Accuracy: {accuracy.item()*100:.2f}%")
期间我问了deepseek,AI告诉我中间一些需要注意的点,我觉得可以借鉴,我贴出来供大家参考:
-
为什么不用均方误差(MSE)?
答:逻辑回归输出概率,MSE会导致梯度消失问题,BCE更适合概率比较。 -
输入特征需要归一化吗?
答:建议归一化(尤其是特征尺度差异大时),可加速训练。 -
学习率如何选择?
答:尝试不同值(如0.1, 0.01),观察损失是否稳定下降。
总结
-
逻辑回归本质:线性分类器 + 概率转换。
-
PyTorch步骤:定义模型 → 计算损失 → 反向传播 → 更新权重。
-
适用场景:二分类问题(如垃圾邮件检测、疾病诊断)。