逻辑回归详解:从数学推导到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快速入门(6)——for/if/while语句
开发语言·经验分享·笔记·python
郝学胜-神的一滴2 小时前
深入解析Python字典的继承关系:从abc模块看设计之美
网络·数据结构·python·程序人生
百锦再2 小时前
Reactive编程入门:Project Reactor 深度指南
前端·javascript·python·react.js·django·前端框架·reactjs
颜酱3 小时前
图结构完全解析:从基础概念到遍历实现
javascript·后端·算法
m0_736919103 小时前
C++代码风格检查工具
开发语言·c++·算法
yugi9878383 小时前
基于MATLAB强化学习的单智能体与多智能体路径规划算法
算法·matlab
喵手3 小时前
Python爬虫实战:旅游数据采集实战 - 携程&去哪儿酒店机票价格监控完整方案(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·零基础python爬虫教学·采集结果csv导出·旅游数据采集·携程/去哪儿酒店机票价格监控
2501_944934733 小时前
高职大数据技术专业,CDA和Python认证优先考哪个?
大数据·开发语言·python
helloworldandy4 小时前
使用Pandas进行数据分析:从数据清洗到可视化
jvm·数据库·python
DuHz4 小时前
超宽带脉冲无线电(Ultra Wideband Impulse Radio, UWB)简介
论文阅读·算法·汽车·信息与通信·信号处理