一、概念
逻辑斯蒂回归(简称Logistic回归)是一种监督学习算法 ,虽然名字含"回归",但实际用于分类任务 (尤其适用于二分类)。其核心思想是:通过一个Sigmoid函数将线性回归的输出(连续值)映射到0-1之间,得到样本属于某一类别的概率,再根据概率进行分类决策。
逻辑斯蒂回归是参数模型(需要估计模型参数),属于线性分类器(决策边界是线性的),广泛应用于垃圾邮件识别、疾病预测、用户流失分析等场景。
二、核心理论
逻辑斯蒂回归的工作流程可概括为3步:
- 线性组合 :对输入特征 xxx 进行线性加权,得到 z=w⋅x+bz = w \cdot x + bz=w⋅x+b(www 为权重向量,bbb 为偏置项)。
- 概率映射 :通过Sigmoid函数将 zzz 映射到 (0,1)(0,1)(0,1) 区间,得到样本属于正类(如类别1)的概率 P(Y=1∣x)P(Y=1|x)P(Y=1∣x)。
- 分类决策 :若 P(Y=1∣x)≥0.5P(Y=1|x) \geq 0.5P(Y=1∣x)≥0.5,预测为正类;否则预测为负类(阈值0.5可根据业务调整)。
关键理论基础:
- Sigmoid函数:解决线性回归输出范围无界的问题,其值域严格在(0,1)之间,适合表示概率。
- 对数几率 :Sigmoid的反函数是"对数几率"(logP1−P\log\frac{P}{1-P}log1−PP),逻辑斯蒂回归本质是通过线性模型拟合"对数几率",因此也称为"对数几率回归"。
- 损失函数 :采用交叉熵损失(而非平方损失),因为交叉熵对参数是凸函数,可通过梯度下降高效优化;而平方损失在分类场景下是非凸的,易陷入局部最优。
三、数学公式
1. Sigmoid函数
将线性输出 zzz 映射为概率的函数:
σ(z)=11+e−z \sigma(z) = \frac{1}{1 + e^{-z}} σ(z)=1+e−z1
其中 z=w⋅x+b=w1x1+w2x2+...+wdxd+bz = w \cdot x + b = w_1x_1 + w_2x_2 + ... + w_dx_d + bz=w⋅x+b=w1x1+w2x2+...+wdxd+b(ddd 为特征维度)。
Sigmoid函数的性质:
- 值域:(0,1)(0,1)(0,1),适合表示概率;
- 导数:σ′(z)=σ(z)⋅(1−σ(z))\sigma'(z) = \sigma(z) \cdot (1 - \sigma(z))σ′(z)=σ(z)⋅(1−σ(z))(推导中会用到,简化计算);
- 单调性:随 zzz 增大单调递增,当 z=0z=0z=0 时,σ(z)=0.5\sigma(z)=0.5σ(z)=0.5。
2. 概率表示
设样本 xxx 属于正类(Y=1Y=1Y=1)的概率为 PPP,负类(Y=0Y=0Y=0)的概率为 1−P1-P1−P,则:
P(Y=1∣x)=σ(w⋅x+b)=11+e−(w⋅x+b) P(Y=1|x) = \sigma(w \cdot x + b) = \frac{1}{1 + e^{-(w \cdot x + b)}} P(Y=1∣x)=σ(w⋅x+b)=1+e−(w⋅x+b)1
P(Y=0∣x)=1−σ(w⋅x+b)=e−(w⋅x+b)1+e−(w⋅x+b) P(Y=0|x) = 1 - \sigma(w \cdot x + b) = \frac{e^{-(w \cdot x + b)}}{1 + e^{-(w \cdot x + b)}} P(Y=0∣x)=1−σ(w⋅x+b)=1+e−(w⋅x+b)e−(w⋅x+b)
3. 对数几率(Log Odds)
对概率取"对数几率"(正类概率与负类概率的比值的对数):
log(P(Y=1∣x)P(Y=0∣x))=w⋅x+b \log\left( \frac{P(Y=1|x)}{P(Y=0|x)} \right) = w \cdot x + b log(P(Y=0∣x)P(Y=1∣x))=w⋅x+b
可见,逻辑斯蒂回归本质是用线性模型拟合"对数几率",这也是其"回归"名称的由来。
4. 损失函数(交叉熵损失)
对于 nnn 个样本 {(x1,y1),(x2,y2),...,(xn,yn)}\{(x_1,y_1), (x_2,y_2), ..., (x_n,y_n)\}{(x1,y1),(x2,y2),...,(xn,yn)}(yi∈{0,1}y_i \in \{0,1\}yi∈{0,1}),损失函数定义为:
L(w,b)=−1n∑i=1n[yilog(Pi)+(1−yi)log(1−Pi)] L(w,b) = -\frac{1}{n} \sum_{i=1}^n \left[ y_i \log(P_i) + (1 - y_i) \log(1 - P_i) \right] L(w,b)=−n1i=1∑n[yilog(Pi)+(1−yi)log(1−Pi)]
其中 Pi=P(Y=1∣xi)=σ(w⋅xi+b)P_i = P(Y=1|x_i) = \sigma(w \cdot x_i + b)Pi=P(Y=1∣xi)=σ(w⋅xi+b)。
损失函数的意义:当 yi=1y_i=1yi=1 时,若 PiP_iPi 接近1,损失接近0;若 PiP_iPi 接近0,损失趋近于无穷大(惩罚错误预测)。
四、推导过程(参数求解)
目标:通过梯度下降法 最小化损失函数 L(w,b)L(w,b)L(w,b),求解最优参数 www 和 bbb。
1. 简化参数表示
为方便计算,将偏置项 bbb 纳入权重向量 www(令 w0=bw_0 = bw0=b,x0=1x_0 = 1x0=1),则 z=w⋅xz = w \cdot xz=w⋅x(www 为 (d+1)(d+1)(d+1) 维,xxx 为 (d+1)(d+1)(d+1) 维,含 x0=1x_0=1x0=1)。此时 Pi=σ(w⋅xi)P_i = \sigma(w \cdot x_i)Pi=σ(w⋅xi)。
2. 计算损失函数对参数的偏导数
对单个样本 iii,损失项为 li=−[yilog(Pi)+(1−yi)log(1−Pi)]l_i = -[y_i \log(P_i) + (1 - y_i) \log(1 - P_i)]li=−[yilog(Pi)+(1−yi)log(1−Pi)],总损失 L=1n∑liL = \frac{1}{n}\sum l_iL=n1∑li。
求 lil_ili 对 wjw_jwj(第 jjj 个权重)的偏导数:
∂li∂wj=−[yi⋅1Pi⋅∂Pi∂wj+(1−yi)⋅11−Pi⋅(−∂Pi∂wj)] \frac{\partial l_i}{\partial w_j} = -\left[ y_i \cdot \frac{1}{P_i} \cdot \frac{\partial P_i}{\partial w_j} + (1 - y_i) \cdot \frac{1}{1 - P_i} \cdot \left( -\frac{\partial P_i}{\partial w_j} \right) \right] ∂wj∂li=−[yi⋅Pi1⋅∂wj∂Pi+(1−yi)⋅1−Pi1⋅(−∂wj∂Pi)]
利用Sigmoid导数性质 ∂Pi∂wj=Pi(1−Pi)⋅xij\frac{\partial P_i}{\partial w_j} = P_i (1 - P_i) \cdot x_{ij}∂wj∂Pi=Pi(1−Pi)⋅xij(xijx_{ij}xij 为样本 iii 的第 jjj 个特征),代入上式:
∂li∂wj=−[yi(1−Pi)xij−(1−yi)Pixij]=−[yi−Pi]xij \frac{\partial l_i}{\partial w_j} = -\left[ y_i (1 - P_i) x_{ij} - (1 - y_i) P_i x_{ij} \right] = -\left[ y_i - P_i \right] x_{ij} ∂wj∂li=−[yi(1−Pi)xij−(1−yi)Pixij]=−[yi−Pi]xij
因此,总损失对 wjw_jwj 的偏导数为:
∂L∂wj=1n∑i=1n∂li∂wj=1n∑i=1n(Pi−yi)xij \frac{\partial L}{\partial w_j} = \frac{1}{n} \sum_{i=1}^n \frac{\partial l_i}{\partial w_j} = \frac{1}{n} \sum_{i=1}^n (P_i - y_i) x_{ij} ∂wj∂L=n1i=1∑n∂wj∂li=n1i=1∑n(Pi−yi)xij
3. 梯度下降更新参数
参数更新公式(α\alphaα 为学习率):
wj=wj−α⋅∂L∂wj=wj−α⋅1n∑i=1n(Pi−yi)xij w_j = w_j - \alpha \cdot \frac{\partial L}{\partial w_j} = w_j - \alpha \cdot \frac{1}{n} \sum_{i=1}^n (P_i - y_i) x_{ij} wj=wj−α⋅∂wj∂L=wj−α⋅n1i=1∑n(Pi−yi)xij
重复迭代上述更新过程,直到损失函数收敛(变化小于阈值)或达到最大迭代次数。
五、Python实现(二分类逻辑斯蒂回归)
python
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_classification
from sklearn.metrics import accuracy_score
class LogisticRegression:
def __init__(self, learning_rate=0.01, n_iterations=1000):
self.learning_rate = learning_rate # 学习率
self.n_iterations = n_iterations # 迭代次数
self.weights = None # 权重
self.bias = None # 偏置
def _sigmoid(self, z):
# 防止指数溢出(z过大时e^-z接近0,过小则接近无穷)
return 1 / (1 + np.exp(-np.clip(z, -250, 250)))
def fit(self, X, y):
n_samples, n_features = X.shape
# 初始化参数
self.weights = np.zeros(n_features)
self.bias = 0
# 梯度下降迭代
for _ in range(self.n_iterations):
# 线性输出 z = w·x + b
z = np.dot(X, self.weights) + self.bias
# 概率 P = sigmoid(z)
y_pred_proba = self._sigmoid(z)
# 计算梯度(批量梯度下降)
dw = (1 / n_samples) * np.dot(X.T, (y_pred_proba - y)) # 权重梯度
db = (1 / n_samples) * np.sum(y_pred_proba - y) # 偏置梯度
# 更新参数
self.weights -= self.learning_rate * dw
self.bias -= self.learning_rate * db
def predict_proba(self, X):
# 预测正类概率
z = np.dot(X, self.weights) + self.bias
return self._sigmoid(z)
def predict(self, X, threshold=0.5):
# 根据概率预测类别(默认阈值0.5)
y_pred_proba = self.predict_proba(X)
return (y_pred_proba >= threshold).astype(int)
# 测试代码
if __name__ == "__main__":
# 生成二分类模拟数据
X, y = make_classification(n_samples=1000, n_features=10, n_classes=2, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 训练模型
model = LogisticRegression(learning_rate=0.01, n_iterations=1000)
model.fit(X_train, y_train)
# 预测与评估
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"自定义逻辑斯蒂回归准确率:{accuracy:.4f}") # 约 0.89-0.93
六、sklearn实现
sklearn的 LogisticRegression 支持二分类和多分类(通过 multi_class 参数),并提供正则化(L1、L2等)防止过拟合。
示例(乳腺癌分类数据集)
python
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# 加载数据集(二分类:良性/恶性肿瘤)
data = load_breast_cancer()
X, y = data.data, data.target # 30维特征
# 拆分数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 初始化模型(L2正则化,学习率自适应的solver)
model = LogisticRegression(max_iter=10000, penalty='l2', solver='lbfgs', random_state=42)
# 训练
model.fit(X_train, y_train)
# 预测
y_pred = model.predict(X_test)
y_pred_proba = model.predict_proba(X_test) # 输出每个类别的概率
# 评估
accuracy = accuracy_score(y_test, y_pred)
print(f"sklearn逻辑斯蒂回归准确率:{accuracy:.4f}") # 约 0.97-0.98
七、总结
- 优点:输出为概率,可解释性强(权重反映特征重要性);训练高效(凸优化问题);适合作为基线模型。
- 缺点:仅能捕捉线性关系(需手动构造非线性特征);对异常值敏感;高维数据下可能过拟合(需正则化)。
- 适用场景:二分类任务(如风险评估、点击率预测)、多分类(通过One-vs-Rest或Softmax)。