逻辑回归详解:从数学推导到Python实战

文章目录

引言

  • 逻辑回归是机器学习中最基础且重要的分类算法之一,广泛应用于各种二分类问题。本文将从数学原理出发,详细讲解逻辑回归的工作机制,并通过Python代码实现帮助初学者真正掌握这一算法。

逻辑回归基础

  • 逻辑回归虽然名字中有"回归",但它实际上是一种分类算法,主要用于解决二分类问题。其核心思想是通过sigmoid函数将线性回归的输出映射到(0,1)区间,表示样本属于某一类的概率。

Sigmoid函数

  • Sigmoid函数(也称为逻辑函数)的数学表达式为:
    g ( z ) = 1 1 + e − z g(z) = \frac{1}{1 + e^{-z}} g(z)=1+e−z1
  • 函数有的特性:它的导数可以用自身表示:
    g ′ ( z ) = g ( z ) ( 1 − g ( z ) ) g'(z) = g(z)(1 - g(z)) g′(z)=g(z)(1−g(z))
  • 详细推导:Sigmoid函数导数推导详解

损失函数 数学推导

  • 逻辑回归使用交叉熵损失函数 (也称为对数损失),对于单个样本,损失函数为:
    J ( θ ) = − y log ⁡ ( h θ ( x ) ) − ( 1 − y ) log ⁡ ( 1 − h θ ( x ) ) J(\theta) = -y\log(h_\theta(x)) - (1-y)\log(1-h_\theta(x)) J(θ)=−ylog(hθ(x))−(1−y)log(1−hθ(x))
    其中 h θ ( x ) = g ( θ T x ) h_\theta(x) = g(\theta^T x) hθ(x)=g(θTx)是我们的预测函数。

梯度下降

  • 为了找到最优参数 θ \theta θ,我们需要最小化损失函数。梯度下降法通过不断沿着梯度的反方向更新参数来实现这一目标。参数更新公式为:

θ j : = θ j − α ∂ ∂ θ j J ( θ ) \theta_j := \theta_j - \alpha \frac{\partial}{\partial \theta_j} J(\theta) θj:=θj−α∂θj∂J(θ)

其中 α \alpha α是学习率,控制每次更新的步长。

偏导数推导

  • 推导损失函数对 θ j \theta_j θj的偏导数:
    ∂ ∂ θ j J ( θ ) = − 1 m ∑ i = 1 m ( y i 1 h θ ( x i ) − ( 1 − y i ) 1 1 − h θ ( x i ) ) ∂ ∂ θ j h θ ( x i ) = − 1 m ∑ i = 1 m ( y i 1 g ( θ T x i ) − ( 1 − y i ) 1 1 − g ( θ T x i ) ) g ( θ T x i ) ( 1 − g ( θ T x i ) ) x i j = − 1 m ∑ i = 1 m ( y i ( 1 − g ( θ T x i ) ) − ( 1 − y i ) g ( θ T x i ) ) x i j = 1 m ∑ i = 1 m ( h θ ( x i ) − y i ) x i j \begin{align*} \frac{\partial}{\partial \theta_j} J(\theta) &= -\frac{1}{m}\sum_{i=1}^m \left(y_i \frac{1}{h_\theta(x_i)} - (1-y_i)\frac{1}{1-h_\theta(x_i)}\right) \frac{\partial}{\partial \theta_j} h_\theta(x_i) \\ &= -\frac{1}{m}\sum_{i=1}^m \left(y_i \frac{1}{g(\theta^T x_i)} - (1-y_i)\frac{1}{1-g(\theta^T x_i)}\right) g(\theta^T x_i)(1-g(\theta^T x_i)) x_i^j \\ &= -\frac{1}{m}\sum_{i=1}^m \left(y_i(1-g(\theta^T x_i)) - (1-y_i)g(\theta^T x_i)\right) x_i^j \\ &= \frac{1}{m}\sum_{i=1}^m (h_\theta(x_i) - y_i) x_i^j \end{align*} ∂θj∂J(θ)=−m1i=1∑m(yihθ(xi)1−(1−yi)1−hθ(xi)1)∂θj∂hθ(xi)=−m1i=1∑m(yig(θTxi)1−(1−yi)1−g(θTxi)1)g(θTxi)(1−g(θTxi))xij=−m1i=1∑m(yi(1−g(θTxi))−(1−yi)g(θTxi))xij=m1i=1∑m(hθ(xi)−yi)xij
  • 有趣的是,最终的表达式与线性回归的梯度形式相同,尽管它们的损失函数完全不同。

Python实现

python 复制代码
import numpy as np
from sklearn import datasets
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

# 加载鸢尾花数据集
iris = datasets.load_iris()
X = iris["data"][:, 3:]  # 只使用花瓣宽度特征
y = (iris["target"] == 2).astype(np.int64)  # 1 if Iris-Virginica, else 0

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建并训练逻辑回归模型
log_reg = LogisticRegression(solver='sag', max_iter=1000)
log_reg.fit(X_train, y_train)

# 预测新数据
X_new = np.linspace(0, 3, 1000).reshape(-1, 1)
y_proba = log_reg.predict_proba(X_new)
y_pred = log_reg.predict(X_new)

# 可视化优化版本
plt.figure(figsize=(10, 6))
plt.plot(X_new, y_proba[:, 1], "g-", label="Probability of Iris-Virginica")
plt.plot(X_new, y_proba[:, 0], "b--", label="Probability of Not Iris-Virginica")

# 寻找概率为0.5时的X值作为决策边界
decision_boundary = X_new[np.abs(y_proba[:, 1] - 0.5).argmin()]
plt.axvline(x=decision_boundary[0], color='r', linestyle='--', label='Decision Boundary (P=0.5)')

plt.xlabel("Petal Width (cm)")
plt.ylabel("Probability")
plt.legend(loc="center left")
plt.title("Logistic Regression - Probability of Class Membership")
plt.grid(True)
plt.show()

# 评估模型
print("Test accuracy:", log_reg.score(X_test, y_test))

正则化

  • 为了防止过拟合,我们可以在损失函数中加入正则化项。常用的有L1正则化和L2正则化。

正则化损失函数

J ( θ ) = 1 m ∑ i = 1 m [ − y ( i ) log ⁡ ( h θ ( x ( i ) ) ) − ( 1 − y ( i ) ) log ⁡ ( 1 − h θ ( x ( i ) ) ) ] + λ 2 m ∑ j = 1 n θ j 2 J(\theta) = \frac{1}{m}\sum_{i=1}^m \left[-y^{(i)}\log(h_\theta(x^{(i)})) - (1-y^{(i)})\log(1-h_\theta(x^{(i)}))\right] + \frac{\lambda}{2m}\sum_{j=1}^n \theta_j^2 J(θ)=m1i=1∑m[−y(i)log(hθ(x(i)))−(1−y(i))log(1−hθ(x(i)))]+2mλj=1∑nθj2

  • 对应的梯度为:

∂ J ( θ ) ∂ θ j = 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) + λ m θ j \frac{\partial J(\theta)}{\partial \theta_j} = \frac{1}{m}\sum_{i=1}^m (h_\theta(x^{(i)}) - y^{(i)})x_j^{(i)} + \frac{\lambda}{m}\theta_j ∂θj∂J(θ)=m1i=1∑m(hθ(x(i))−y(i))xj(i)+mλθj

  • 在scikit-learn中,通过参数C控制正则化强度,其中 C = 1 λ C = \frac{1}{\lambda} C=λ1。
python 复制代码
# 使用正则化的逻辑回归
log_reg_l2 = LogisticRegression(penalty='l2', C=0.1, solver='lbfgs', max_iter=1000)
log_reg_l2.fit(X_train, y_train)

log_reg_l1 = LogisticRegression(penalty='l1', C=0.1, solver='liblinear', max_iter=1000)
log_reg_l1.fit(X_train, y_train)

总结

  1. 逻辑回归是一种概率分类模型,输出0到1之间的概率值。
  2. 使用sigmoid函数将线性输出映射到概率空间。
  3. 通过交叉熵损失函数衡量预测与真实值的差异。
  4. 使用梯度下降法优化模型参数。
  5. 可以加入正则化项防止过拟合。
  6. 在实践中,可以使用scikit-learn等库方便地实现逻辑回归。
相关推荐
草明1 分钟前
Python pip 以及 包的升级
windows·python·pip
新知图书4 分钟前
OpenCV+Python实战人脸检测
人工智能·python·opencv
GettingReal31 分钟前
Python 构建壳来启动加密的 SpringBoot Jar 包,增加反编译难度
spring boot·python·jar·加密
bluemliu39 分钟前
django rest_framework 前端网页实现Token认证
前端·python·django
黄狗操作员41 分钟前
Django 创建APP urls.py path views.index 报错,NameError: name ‘views‘ is not defined
前端·python·django
黎茗Dawn1 小时前
第1章: 伯努利模型的极大似然估计与贝叶斯估计
python
AI量化投资实验室1 小时前
十年年化50%+的策略如何进化?兼容机器学习流程的量化策略开发,附python代码
人工智能·python·机器学习
The丶Star1 小时前
【解决CMD命令行下无法正常打开jupyter notebook的特殊办法(关闭防火墙版)】
ide·python·jupyter
不讲魔法讲道理1 小时前
(202506最新)Jupyter Notebook显示目录的导航栏
ide·python·jupyter
m0_640743562 小时前
华为OD-2024年E卷-中文分词模拟器[200分] -- python
python·华为od·中文分词