逻辑回归(Logistic Regression)
从零到实战:原理 + 公式 + 代码 + 可视化 + 进阶技巧
一句话定义:
逻辑回归 = 线性回归 + Sigmoid → 输出 0~1 概率,用于分类(尤其是二分类)
一、核心思想(类比)
| 任务 | 线性回归 | 逻辑回归 |
|---|---|---|
| 预测房价 | → 任意实数 | → 概率 0~1 |
| 判断是否垃圾邮件 | 不能 | 能!输出 P(垃圾) = 0.9 |
本质:
- 先用线性模型算一个“得分”
- 用 Sigmoid 把得分压缩到 [0,1] 区间 → 概率
二、数学公式
1. 线性部分(同线性回归)
$$
z = wX + b
$$
2. Sigmoid 函数(把任意数 → 概率)
$$
\boxed{\sigma(z) = \frac{1}{1 + e^{-z}}}
$$
- $ z \to +\infty $ → $ \sigma \to 1 $
- $ z \to -\infty $ → $ \sigma \to 0 $
3. 最终预测概率
$$
\boxed{\hat{y} = P(y=1|X) = \sigma(wX + b)}
$$
4. 分类规则
$$
\boxed{\text{pred} =
\begin{cases}
1, & \hat{y} \geq 0.5 \
0, & \hat{y} < 0.5
\end{cases}}
$$
三、损失函数:交叉熵(Cross Entropy)
为什么不用 MSE?
MSE 会导致梯度消失,训练慢!
公式(二分类)
$$
\boxed{L = -\frac{1}{n} \sum \left[ y_i \log(\hat{y}_i) + (1-y_i) \log(1-\hat{y}_i) \right]}
$$
| 真实 y | 预测 ŷ | 损失贡献 |
|---|---|---|
| 1 | 0.9 | 小(-log(0.9)) |
| 1 | 0.1 | 大(-log(0.1)) |
| 0 | 0.1 | 小 |
| 0 | 0.9 | 大 |
四、梯度下降更新
$$
w := w – \alpha \cdot \frac{1}{n} \sum (\hat{y}_i – y_i) X_i
$$
$$
b := b – \alpha \cdot \frac{1}{n} \sum (\hat{y}_i – y_i)
$$
跟线性回归梯度一模一样!只不过 $ \hat{y} = \sigma(z) $
五、Python 完整实战(5 分钟跑通)
# ===== 1. 导入库 =====
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
# ===== 2. 生成可分数据 =====
X, y = make_classification(
n_samples=200, n_features=2, n_redundant=0,
n_informative=2, n_clusters_per_class=1,
random_state=42
)
# ===== 3. 训练逻辑回归 =====
model = LogisticRegression()
model.fit(X, y)
# ===== 4. 预测与评估 =====
y_pred = model.predict(X)
print(f"准确率: {accuracy_score(y, y_pred):.3f}")
print(classification_report(y, y_pred))
输出:
准确率: 0.955
precision recall f1-score support
0 0.94 0.97 0.96 100
1 0.97 0.94 0.95 100
六、可视化:决策边界 + 概率热图
import numpy as np
import matplotlib.pyplot as plt
from sklearn.inspection import DecisionBoundaryDisplay
# 画决策边界
plt.figure(figsize=(10, 4))
# 子图1:分类结果
plt.subplot(1, 2, 1)
DecisionBoundaryDisplay.from_estimator(
model, X, cmap='RdBu', alpha=0.8, response_method="predict"
)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap='RdBu', edgecolor='k')
plt.title('逻辑回归分类结果')
# 子图2:预测概率(热图)
plt.subplot(1, 2, 2)
DecisionBoundaryDisplay.from_estimator(
model, X, cmap='RdBu', alpha=0.8, response_method="predict_proba"
)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap='RdBu', edgecolor='k')
plt.title('预测概率 P(y=1)')
plt.tight_layout()
plt.show()
你会看到:
- 红蓝分界线:决策边界
- 颜色深浅:预测概率(越红越接近1)
七、从零手推 Sigmoid + 梯度下降
# ===== 手写逻辑回归 =====
def sigmoid(z):
return 1 / (1 + np.exp(-z))
# 初始化
w = np.zeros(X.shape[1])
b = 0
alpha = 0.1
n_iters = 1000
for _ in range(n_iters):
z = X.dot(w) + b
y_hat = sigmoid(z)
# 梯度
dw = (1/len(X)) * X.T.dot(y_hat - y)
db = (1/len(X)) * np.sum(y_hat - y)
# 更新
w -= alpha * dw
b -= alpha * db
# 预测
y_pred_manual = (sigmoid(X.dot(w) + b) >= 0.5).astype(int)
print("手推准确率:", accuracy_score(y, y_pred_manual))
输出 ≈ 0.95,和
sklearn一致!
八、多分类?用 Softmax 回归(One-vs-Rest 或 multinomial)
# 鸢尾花三分类
from sklearn.datasets import load_iris
iris = load_iris()
X, y = iris.data, iris.target
model = LogisticRegression(multi_class='multinomial', solver='lbfgs')
model.fit(X, y)
print("三分类准确率:", model.score(X, y))
九、评估指标大全
| 指标 | 解释 | 代码 |
|---|---|---|
| 准确率 | 正确率 | accuracy_score |
| 精确率 | 预测为1的中有多少真1 | precision_score |
| 召回率 | 真实1中有多少被抓到 | recall_score |
| F1 | 精确率和召回率的调和平均 | f1_score |
| 混淆矩阵 | 四格表 | confusion_matrix |
from sklearn.metrics import confusion_matrix
import seaborn as sns
cm = confusion_matrix(y, y_pred)
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues')
plt.xlabel('预测')
plt.ylabel('真实')
plt.show()
十、常见问题 & 解决
| 问题 | 原因 | 解决 |
|---|---|---|
| 类别不平衡 | 1很少 | class_weight='balanced' |
| 特征尺度差异 | 影响收敛 | 标准化(StandardScaler) |
| 过拟合 | 特征多 | 加 L2正则(C=1.0 控制) |
| 决策边界不线性 | 数据非线性可分 | 加多项式特征或用 SVM |
model = LogisticRegression(C=1.0, class_weight='balanced') # 防过拟合 + 平衡
十一、概率校准(让概率更准)
from sklearn.calibration import CalibratedClassifierCV
calibrated = CalibratedClassifierCV(model, method='sigmoid', cv=3)
calibrated.fit(X, y)
prob = calibrated.predict_proba(X[:1])
print("校准后概率:", prob)
十二、保存与部署
import joblib
joblib.dump(model, 'spam_classifier.pkl')
# 部署时:model = joblib.load('spam_classifier.pkl')
十三、一键完整代码(复制即用)
# ===== 逻辑回归完整流程 =====
import numpy as np, matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
from sklearn.inspection import DecisionBoundaryDisplay
# 1. 数据
X, y = make_classification(n_samples=300, n_features=2, n_redundant=0,
n_informative=2, n_clusters_per_class=1, random_state=42)
# 2. 模型
model = LogisticRegression()
model.fit(X, y)
# 3. 评估
print("准确率:", accuracy_score(y, model.predict(X)))
# 4. 可视化
plt.figure(figsize=(8,6))
DecisionBoundaryDisplay.from_estimator(model, X, cmap='RdBu', alpha=0.8)
plt.scatter(X[:,0], X[:,1], c=y, cmap='RdBu', edgecolor='k')
plt.title('逻辑回归决策边界')
plt.show()
十四、总结公式卡
| 项目 | 公式 |
|---|---|
| 模型 | $ \hat{y} = \sigma(wX + b) $ |
| Sigmoid | $ \sigma(z) = \frac{1}{1+e^{-z}} $ |
| 损失 | $ L = -\frac{1}{n} \sum [y\log\hat{y} + (1-y)\log(1-\hat{y})] $ |
| 梯度 | $ \frac{\partial L}{\partial w} = \frac{1}{n} \sum (\hat{y}-y)X $ |
你想深入哪一步?
- 多项式特征 + 逻辑回归(非线性分类)
- 处理不平衡数据(SMOTE + class_weight)
- 用真实数据做项目(如信用卡欺诈检测)
- 概率校准 + ROC 曲线分析
回复 1–4,我立刻带你实战!