逻辑回归基本原理
在上一节的线性回归中,我们解决的是回归问题(预测连续值)。而在模式识别与机器学习中,我们更常遇到的是 分类任务 ,例如判断一封邮件是否为垃圾邮件,或者判断一个人是否患有某种疾病。
对于这类二分类问题,输出标签通常为 。如果我们直接使用线性回归模型预测,输出值可能会远超 0 到 1 的范围,这在概率解释上是不合理的。为此,我们在线性模型的基础上引入了一个非线性激活函数 ,将线性预测值映射为类别标签的后验概率 。
对数几率回归
在 逻辑回归(Logistic Regression) 中,选用的激活函数为 Sigmoid 函数 ,其表达式为:
模型的预测目标是样本属于正类( )的后验概率:
为了简化公式,我们通常采用 增广向量 的形式:
- 增广特征向量
- 增广权重向量
此时,样本属于负类( )的后验概率为:
通过推导,我们可以发现线性模型 与概率之间的关系:
该公式左侧为典型的 线性函数 ,右侧则是将后验概率之比(数学上称为 几率 ,Odds)通过对数变换映射至实数域,这种建立线性预测值与 对数几率 之间映射关系的方法,也正是 Logistic 回归被称为 对数几率回归 的由来。

逻辑回归代码讲解
下面我们使用 Python 的 NumPy 库来手写实现一个逻辑回归模型。为了让代码结构更加紧凑,并能够直接表达数学公式的含义,示例中会用到 匿名函数(Lambda Function) 来定义核心运算。
值得注意的是,为了与前面理论部分所使用的 增广向量(Augmented Vector) 保持一致,我们会在输入特征矩阵 的最左侧额外添加一列常数 1,从而把偏置项 吸收到权重向量 中统一处理。这样不仅使参数更新的形式更加整齐,也顺便修复了原版本代码中函数返回值与参数解包数量不匹配的问题,使整体实现更加规范和可靠。
下面给出逻辑回归的完整代码:
import numpy as npnp.random.seed(0)X = np.random.randn(100, 2)true_w = np.array([2, -1])sigmoid = lambda x: 1 / (1 + np.exp(-x))y = (sigmoid(X @ true_w) > 0.5).astype(int)
# 激活函数sigmoid = lambda x: 1 / (1 + np.exp(-x))# 损失函数loss_func = lambda X, y, w: -np.mean( y * np.log(sigmoid(X @ w)) + (1 - y) * np.log(1 - sigmoid(X @ w)))# 梯度下降gradient = lambda X, y, w: X.T @ (sigmoid(X @ w) - y) / len(y)def grad_desc(cur_w, alpha, X, y): grad = gradient(X, y, cur_w) updated_w = cur_w - alpha * grad return updated_w# 主函数def main(X, y, initial_w, alpha, num_iter): w = initial_w # 定义一个list保存所有的损失函数值,用来显示下降的过程 cost_list = [] for i in range(num_iter): cost_list.append(loss_func(X, y, w)) w, b = grad_desc(w, alpha, X, y) return [w, b, cost_list]
# 设置超参数alpha = 0.1initial_w = np.zeros(X.shape[1])num_iter = 1000# 执行代码if __name__ == "__main__": w, cost_list = main(X, y, initial_w, alpha, num_iter) print("\n训练结束") print("w =", w) cost = loss_func(X, y, w) print("cost =", cost)1. 损失函数
与线性回归使用均方误差(MSE)不同,逻辑回归采用的是 交叉熵损失(Cross-Entropy Loss)。其核心原因在于:如果将 Sigmoid 函数套入 MSE 中,所得损失函数在参数空间里会变成一个 非凸函数(Non-Convex),可能具有多个局部极小值,从而使梯度下降难以稳定地找到全局最优解。相比之下,交叉熵损失在逻辑回归的模型结构下是一个凸函数,具备更好的优化特性,因此成为逻辑回归的标准选择。
更多细节可以参考以下视频深入了解
先来看一下代码中的损失函数实现:
loss_func = lambda X, y, w: -np.mean( y * np.log(sigmoid(X @ w)) + (1 - y) * np.log(1 - sigmoid(X @ w)))对应的数学表达式为交叉熵损失函数:
其中 表示模型对第 个样本的预测概率。
2. 梯度下降
逻辑回归在模型形式上与线性回归非常相似,只是在预测输出上多了一层 Sigmoid 激活函数 。从微积分角度来看,这仅仅增加了链式法则中的一个环节。代码中梯度计算的实现非常简洁:
gradient = lambda X, y, w: X.T @ (sigmoid(X @ w) - y) / len(y)
def grad_desc(cur_w, alpha, X, y): grad = gradient(X, y, cur_w) updated_w = cur_w - alpha * grad return updated_w其数学推导如下:
- 预测值
- 损失函数
- 权重梯度
可以看到,这一梯度推导的最终形式与线性回归在结构上几乎一致,只是将预测值替换为逻辑回归中的 。正因为两者在形式上的高度相似,逻辑回归也被视为 广义线性模型(GLM) 的一个典型特例。
3. 内容拓展
Logistic 回归本质上是一个 线性分类器 ,其决策边界是线性的(即 是一个超平面)。对于 线性不可分 的数据,我们可以通过 特征工程 来提升模型的表达能力。
常见的特征扩展(Feature Expansion)方法包括:
- 多项式特征:引入 、 、 等高阶项使决策边界变为二次曲线。
- 交互式特征:构造特征之间的乘积、比值等,刻画变量间的耦合关系。
本质上,这是通过将低维的原始特征映射到高维空间,使得数据在高维空间中变得线性可分。但需要警惕的是,特征维度过高容易导致 过拟合(Overfitting) ,通常需要配合正则化(L1/L2 Regularization)使用。
深层问题探究
-
为什么逻辑回归在线性回归的基础上套一层激活函数就可以进行分类呢?
这个问题可以从 直观理解 和 数学本质 两个层面来回答:
直观理解:数值区间的映射 线性回归的预测输出 的范围是 ,而二分类任务要求的概率 必须处于 之间。Sigmoid 函数 的作用就是将任意实数 映射(压缩) 到 区间,使其具有概率的物理意义。
数学本质:对数几率的线性假设 逻辑回归本质上是 广义线性模型 的一种。我们并非随意选择了一个激活函数,而是基于一个核心假设:样本为正类的对数几率与输入特征之间存在线性关系 。
几率定义为正类概率与负类概率的比值:
对几率取对数,即得到 Logit 变换:
如果我们对上述公式进行 逆变换 ,求解 就会自然导出 Sigmoid 函数的形式:
结论:Sigmoid 函数并非仅仅是套在外部的一层壳,它是 对数几率线性假设 在概率空间上的 逆映射 。