Machine Learning: 逻辑回归 — 分类问题入门与电商用户行为预测指南
逻辑回归不是"回归"——它是分类利器,输出的不是数值而是概率。
1. 你将学到
- 从线性到逻辑:Sigmoid函数、概率输出、决策边界
- 损失函数:交叉熵损失,极大似然估计直觉
- 多分类扩展:One-vs-Rest与Softmax(Multinomial)
- 评估指标:Accuracy/Precision/Recall/F1/ROC-AUC,业务场景选择
- Alice的用户流失预测:SaaS场景下识别高流失风险客户
2. 一个SaaS运营的真实故事
(1) 痛点:用户流失发现太晚,挽回成本高
Alice运营的SaaS平台有50 thousand活跃用户,月流失率8%——每月流失4 thousand用户,每个用户年价值约2 thousand USD,月损失约670 thousand USD。问题是:等到用户取消订阅时已经太晚,挽回成功率不到5%。
(2) 逻辑回归的解法
逻辑回归能在用户行为出现异常信号时预测流失概率,提前2-4周预警,挽回成功率提升到30%。
PYTHON
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
model = LogisticRegression(class_weight="balanced")
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print(classification_report(y_test, y_pred, target_names=["Retained", "Churned"]))
(3) 收益:挽回1个客户价值2千USD
Alice用逻辑回归提前识别高流失风险用户,月挽回1.2 thousand用户,年增收约2.4 million USD。挽回1个客户成本约50 USD,远低于获客成本500 USD。
3. 从线性到逻辑
(1) Sigmoid函数
逻辑回归用Sigmoid函数将线性输出压缩到[0,1]区间作为概率:$\sigma(z) = \frac{1}{1+e^{-z}}$
graph LR
INPUT[Input Features x] --> LINEAR[Linear Combination<br/>z = w·x + b]
LINEAR --> SIGMOID[Sigmoid Function<br/>σ = 1/(1+e^(-z))]
SIGMOID --> PROB[P(y=1) = σ]
PROB --> DECISION{P ≥ 0.5?}
DECISION -->|Yes| CLASS1[Class 1<br/>e.g. Churned]
DECISION -->|No| CLASS0[Class 0<br/>e.g. Retained]
▶ 示例:Sigmoid函数可视化
PYTHON
import numpy as np
import matplotlib.pyplot as plt
z = np.linspace(-8, 8, 100)
sigmoid = 1 / (1 + np.exp(-z))
fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(z, sigmoid, linewidth=2, color="#2196F3")
ax.axhline(0.5, color="red", linestyle="--", alpha=0.5, label="Decision boundary")
ax.axvline(0, color="gray", linestyle="--", alpha=0.3)
ax.set_xlabel("z (linear combination)")
ax.set_ylabel("σ(z) = P(y=1)")
ax.set_title("Sigmoid Function")
ax.legend()
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig("sigmoid.png", dpi=150)
输出:
TEXT
📖 仅展示
# 执行成功
(2) 交叉熵损失
逻辑回归的损失函数是交叉熵(Log Loss):
$L = -\frac{1}{n}\sum[y\log(\hat{y}) + (1-y)\log(1-\hat{y})]$
| 真实标签 | 预测概率 | 损失值 | 直觉 |
|---|---|---|---|
| y=1 | ŷ=0.99 | 0.01 | 几乎无惩罚 |
| y=1 | ŷ=0.5 | 0.69 | 中等惩罚 |
| y=1 | ŷ=0.01 | 4.60 | 极大惩罚 |
| y=0 | ŷ=0.01 | 0.01 | 几乎无惩罚 |
| y=0 | ŷ=0.99 | 4.60 | 极大惩罚 |
4. Scikit-learn逻辑回归实现
▶ 示例:二分类 — 用户购买意向预测
PYTHON
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
import numpy as np
rng = np.random.default_rng(42)
n = 1000
X = rng.standard_normal((n, 4)) # [browsing_time, pages_viewed, cart_value, visit_count]
y = (X[:, 0] * 0.5 + X[:, 1] * 1.2 + X[:, 2] * 2.0 + rng.normal(0, 0.5, n) > 1.5).astype(int)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)
pipe = Pipeline([
("scaler", StandardScaler()),
("model", LogisticRegression(random_state=42)),
])
pipe.fit(X_train, y_train)
y_pred = pipe.predict(X_test)
y_prob = pipe.predict_proba(X_test)[:, 1] # Probability of class 1
print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")
print(f"\nConfusion Matrix:\n{confusion_matrix(y_test, y_pred)}")
print(f"\nClassification Report:\n{classification_report(y_test, y_pred)}")
print(f"\nSample probabilities: {y_prob[:5].round(3)}")
输出:
TEXT
📖 仅展示
# 执行成功
▶ 示例:Alice的SaaS用户流失预测
PYTHON
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score, precision_recall_fscore_support
import pandas as pd
import numpy as np
rng = np.random.default_rng(42)
n = 5000
df = pd.DataFrame({
"tenure_months": rng.integers(1, 60, n),
"monthly_usage_hours": rng.exponential(20, n),
"support_tickets": rng.poisson(2, n),
"payment_delay_days": rng.integers(0, 30, n),
"plan_tier": rng.choice([1, 2, 3], n, p=[0.5, 0.35, 0.15]),
})
# Churn logic: short tenure + low usage + many tickets + delays
churn_score = (
-0.05 * df["tenure_months"]
- 0.1 * df["monthly_usage_hours"]
+ 0.5 * df["support_tickets"]
+ 0.1 * df["payment_delay_days"]
+ rng.normal(0, 1, n)
)
df["churned"] = (churn_score > 2).astype(int)
print(f"Churn rate: {df['churned'].mean():.1%}")
# Train with class_weight="balanced" for imbalanced data
X = df.drop(columns=["churned"])
y = df["churned"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)
model = LogisticRegression(class_weight="balanced", max_iter=500, random_state=42)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
y_prob = model.predict_proba(X_test)[:, 1]
auc = roc_auc_score(y_test, y_prob)
precision, recall, f1, _ = precision_recall_fscore_support(y_test, y_pred, average="binary")
print(f"AUC-ROC: {auc:.4f}")
print(f"Precision: {precision:.4f}, Recall: {recall:.4f}, F1: {f1:.4f}")
输出:
TEXT
📖 仅展示
# 执行成功
5. 多分类扩展
(1) One-vs-Rest vs Softmax
▶ 示例:多分类 — 商品品类自动归类
PYTHON
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_score
X, y = load_iris(return_X_y=True)
# One-vs-Rest (default)
ovr_model = LogisticRegression(multi_class="ovr", max_iter=200)
ovr_scores = cross_val_score(ovr_model, X, y, cv=5, scoring="accuracy")
# Softmax (Multinomial)
softmax_model = LogisticRegression(multi_class="multinomial", max_iter=200)
softmax_scores = cross_val_score(softmax_model, X, y, cv=5, scoring="accuracy")
print(f"One-vs-Rest: {ovr_scores.mean():.4f} +/- {ovr_scores.std():.4f}")
print(f"Softmax: {softmax_scores.mean():.4f} +/- {softmax_scores.std():.4f}")
输出:
TEXT
📖 仅展示
# 执行成功
| 维度 | One-vs-Rest | Softmax (Multinomial) |
|---|---|---|
| 原理 | K个二分类器 | 1个多分类器 |
| 概率校准 | 不保证和为1 | 严格和为1 |
| 计算效率 | 可并行 | 需整体优化 |
| 适用场景 | 类别多 | 类别少、需概率 |
6. 分类评估指标与业务选择
(1) 混淆矩阵与派生指标
▶ 示例:ROC曲线与PR曲线
PYTHON
from sklearn.metrics import roc_curve, auc, precision_recall_curve
import matplotlib.pyplot as plt
import numpy as np
# Assume y_test and y_prob from previous example
rng = np.random.default_rng(42)
y_test = rng.choice([0, 1], 500, p=[0.85, 0.15])
y_prob = np.clip(y_test * 0.8 + rng.normal(0, 0.3, 500), 0, 1)
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# ROC Curve
fpr, tpr, _ = roc_curve(y_test, y_prob)
roc_auc = auc(fpr, tpr)
axes[0].plot(fpr, tpr, color="#2196F3", lw=2, label=f"AUC = {roc_auc:.3f}")
axes[0].plot([0, 1], [0, 1], "r--", alpha=0.5)
axes[0].set_xlabel("False Positive Rate")
axes[0].set_ylabel("True Positive Rate")
axes[0].set_title("ROC Curve")
axes[0].legend()
# PR Curve
precision_vals, recall_vals, _ = precision_recall_curve(y_test, y_prob)
axes[1].plot(recall_vals, precision_vals, color="#4CAF50", lw=2)
axes[1].set_xlabel("Recall")
axes[1].set_ylabel("Precision")
axes[1].set_title("Precision-Recall Curve")
plt.tight_layout()
plt.savefig("roc_pr_curves.png", dpi=150)
输出:
TEXT
📖 仅展示
# 执行成功
(2) 业务场景指标选择
| 场景 | 优先指标 | 原因 | 阈值策略 |
|---|---|---|---|
| 用户流失预测 | Recall | 漏掉一个流失客户损失大 | 降低阈值(0.3) |
| 垃圾邮件过滤 | Precision | 误判正常邮件不可接受 | 提高阈值(0.7) |
| 商品推荐 | F1 | 平衡精准与覆盖 | 默认(0.5) |
| 欺诈检测 | Recall | 漏掉欺诈损失巨大 | 降低阈值(0.2) |
📌 重点: 流失预测场景中,Recall比Precision更重要——漏掉1个流失客户损失2k USD,而误判1个非流失客户只浪费50 USD挽回成本。调整决策阈值可优化业务收益。
❓ 常见问题
Q 逻辑回归为什么叫"回归"?
A 历史原因——它用回归方法(线性组合)建模,但输出经过Sigmoid变为分类概率。本质是分类算法,名字容易误导。
Q class_weight=balanced是什么意思?
A 自动按类别频率的倒数加权,让少数类获得更高权重。流失率8%时,流失类权重=1/0.08=12.5,留存类权重=1/0.92=1.09。
Q 决策阈值一定要0.5吗?
A 不必须。0.5是默认值,但业务场景需要调整。流失预测可降到0.3(提高Recall),垃圾邮件可升到0.7(提高Precision)。用业务成本决定阈值。
Q ROC-AUC和PR-AUC哪个更好?
A 类别平衡时看ROC-AUC,类别严重不平衡时看PR-AUC。流失预测(8% vs 92%)建议用PR-AUC。
Q 逻辑回归能处理非线性关系吗?
A 默认不能。但可以加入多项式特征(
PolynomialFeatures)让它学习非线性决策边界。本质上是在更高维空间做线性分类。Q L1正则化对逻辑回归有什么用?
A 同线性回归——L1产生稀疏解,自动做特征选择。
LogisticRegression(penalty="l1", solver="saga")可以启用L1。📖 小节
- 逻辑回归用Sigmoid将线性输出转为概率,默认0.5为决策边界
- 交叉熵损失对"自信但错误"的预测给予极大惩罚
- class_weight="balanced"处理类别不平衡,流失预测场景必备
- 多分类:One-vs-Rest(多二分类) vs Softmax(统一概率),后者概率校准更好
- 业务指标选择:流失→Recall、垃圾邮件→Precision、推荐→F1
- 调整决策阈值可优化业务收益,不必拘泥于0.5默认值
📝 作业
- 基础题(难度⭐):用逻辑回归对Iris数据集做多分类,输出accuracy和classification_report。提示:
LogisticRegression(max_iter=200)+classification_report。 - 进阶题(难度⭐⭐):模拟一个类别不平衡的数据集(95:5),对比默认逻辑回归和class_weight="balanced"的Recall差异。提示:用
make_classification(weights=[0.95, 0.05])。 - 挑战题(难度⭐⭐⭐):实现Alice的完整流失预测——生成模拟SaaS用户数据,训练逻辑回归,绘制ROC/PR曲线,计算不同阈值下的Recall/Precision/F1,找到业务最优阈值。提示:
roc_curve+precision_recall_curve+ 遍历阈值。