当前位置: 首页 > news >正文

【机器学习学习笔记】逻辑回归实现与应用

零基础入门逻辑回归:从原理到实战

逻辑回归是机器学习里超基础、超常用的分类方法(划重点!它不是回归方法),比如判断邮件是不是垃圾邮件、用户会不会点击广告,都能用它解决。下面用大白话拆解它的核心逻辑和实战步骤,零基础也能看懂。

一、先搞懂:为什么需要逻辑回归?(从线性回归的 “缺点” 说起)

我们先从熟悉的 “线性回归” 入手,看看它处理分类问题时的不足 —— 这也是逻辑回归存在的意义。

1. 一个简单的分类问题

比如用 “学习时长” 判断 “是否通过考试”:

  • 特征(输入):学习时长(1 小时、2 小时…10 小时)
  • 标签(输出):是否通过(0 = 不通过,1 = 通过)
    这是典型的 “二分类问题”(结果只有 2 种)。

2. 试试用线性回归解决?

线性回归的核心是 “拟合一条直线”,比如用直线 y = 系数×时长 + 截距 预测结果。我们可以约定:

  • 若预测值 y > 0.5,就判断 “通过”(1)
  • 若 y ≤ 0.5,就判断 “不通过”(0)

但这样做有个大问题:线性回归的预测值可能超出 0-1 范围。比如学习时长特别短(比如 - 1 小时,虽然实际不存在),预测值可能是负数;时长特别长,预测值可能大于 1。但 “是否通过” 的概率只能在 0-1 之间,显然线性回归不适合直接做分类。

二、逻辑回归的 “核心 trick”:用 Sigmoid 函数 “压缩” 范围

逻辑回归的关键,是给线性回归加了一个 “转换工具”——Sigmoid 函数,把线性回归输出的 “任意数”,压缩到 0-1 之间(刚好对应 “概率”)。

1. Sigmoid 函数长什么样?

它的公式不用记,只需记住形状:像一条 “S 型曲线”,特点是:

  • 输入(比如线性回归的结果)不管是多大的正数,输出都无限接近 1;
  • 输入不管是多小的负数,输出都无限接近 0;
  • 输入 = 0 时,输出正好是 0.5。

这简直是为二分类量身定做的!我们可以直接用它的输出当 “概率”:

  • 若 Sigmoid 输出 > 0.5,判断为 “是”(标签 1,比如通过考试);
  • 若 ≤ 0.5,判断为 “否”(标签 0,比如不通过)。

2. 逻辑回归的完整公式(大白话版)

逻辑回归其实是 “线性回归 + Sigmoid 转换” 的组合,分两步:

  1. 第一步:算线性结果
    跟线性回归一样,把特征(比如学习时长 x)和系数(w)相乘再加截距(b),得到 z = w×x + b(如果有多个特征,就是 z = w1×x1 + w2×x2 + ... + b)。
    这里的 z 可以理解为 “分类边界的基础”。

  2. 第二步:用 Sigmoid 压缩
    把 z 代入 Sigmoid 函数,得到最终的 “概率”:
    概率 = 1 / (1 + e^(-z))(e 是数学里的常数,约等于 2.718)。

比如:

  • 当 z 很大(比如 10),e^(-10) 几乎是 0,概率≈1/1=1(几乎肯定是 1 类);
  • 当 z 很小(比如 - 10),e^(-(-10))=e^10 很大,概率≈1/(1 + 大数字)≈0(几乎肯定是 0 类)。

三、逻辑回归怎么 “学” 到最优参数?(损失函数 + 梯度下降)

模型要 “学习” 的,就是线性部分的系数 w 和截距 b。怎么判断参数好不好?需要两个关键工具:损失函数(判断误差)和梯度下降(调整参数减小误差)。

1. 损失函数:给 “误差” 打分

损失函数的作用是:计算模型预测结果和真实标签的差距有多大。差距越小,损失值越小,模型越好。

逻辑回归不用线性回归的 “平方损失”(会导致参数难优化),而是用对数损失函数。不用记公式,只需理解核心:

  • 如果真实标签是 1,模型预测的概率越接近 1,损失越小;越接近 0,损失越大(比如预测错了,罚得狠);
  • 如果真实标签是 0,模型预测的概率越接近 0,损失越小;越接近 1,损失越大。

2. 梯度下降:“一步步找最优参数”

有了损失函数,怎么找到让损失最小的 w 和 b?靠 “梯度下降”,原理像 “下山找最低点”:

  • 梯度:可以理解为 “当前位置下山最快的方向”;
  • 学习率:每一步走多大(步太大容易跨过最低点,步太小走得慢);
  • 迭代:重复 “算梯度→往梯度反方向走一步→更新参数”,直到损失不再减小(找到山脚)。

简单说,梯度下降就是让模型 “一点点调整参数”,最终找到让损失最小的最优参数。

四、实战:用代码实现逻辑回归(两种方式)

下面用真实数据集(特征 X0、X1,标签 Y=0 或 1),分别手动实现逻辑回归,再用 sklearn (机器学习库)快速实现,直观感受过程。

方式 1:手动实现(理解核心步骤)

我们把前面的逻辑(Sigmoid、损失函数、梯度下降)写成代码,步骤如下:

1. 导入工具库
import numpy as np  # 做数学计算
import pandas as pd  # 处理数据
import matplotlib.pyplot as plt  # 画图
2. 加载数据并可视化

先看看数据长什么样:

# 加载数据集(网上可直接获取)
df = pd.read_csv("https://labfile.oss.aliyuncs.com/courses/1081/course-8-data.csv")
# 画散点图:X0是横轴,X1是纵轴,颜色区分标签Y(0=深蓝,1=黄色)
plt.figure(figsize=(10,6))
plt.scatter(df['X0'], df['X1'], c=df['Y'])
plt.show()

会看到两类点分布在图上,我们要找一条线把它们分开。

3. 定义核心函数(Sigmoid、损失、梯度)
# 1. Sigmoid函数:压缩到0-1
def sigmoid(z):return 1 / (1 + np.exp(-z))# 2. 对数损失函数:计算误差
def calculate_loss(h, y):# h是预测概率,y是真实标签(0或1)return (-y * np.log(h) - (1 - y) * np.log(1 - h)).mean()# 3. 计算梯度:找下山方向
def calculate_gradient(X, h, y):# X是特征,h是预测概率,y是真实标签return np.dot(X.T, (h - y)) / y.shape[0]
4. 实现逻辑回归的训练过程
def logistic_regression(X, y, learning_rate=0.01, num_iterations=30000):"""逻辑回归模型训练函数,通过梯度下降法寻找最优参数参数:X: 特征数据,形状为 (样本数, 特征数) 的numpy数组y: 标签数据,形状为 (样本数,) 的numpy数组,值为0或1learning_rate: 学习率,控制梯度下降的步长,默认0.01num_iterations: 迭代次数,控制梯度下降的迭代轮数,默认30000返回:w: 训练好的参数,包含截距项,形状为 (特征数+1,) 的numpy数组"""# 步骤1:给特征矩阵添加截距列(全为1)# 这是为了将截距项b整合到参数w中,相当于给每个样本增加一个恒为1的特征x0# 此时模型变为 z = w0*x0 + w1*x1 + ... + wn*xn,其中x0=1,w0即截距bintercept = np.ones((X.shape[0], 1))  # 创建形状为(样本数, 1)的全1数组X = np.concatenate((intercept, X), axis=1)  # 按列拼接,新特征矩阵形状为(样本数, 特征数+1)# 步骤2:初始化参数w# 初始化为全0数组,长度等于新特征矩阵的列数(特征数+1)# w[0]对应截距项b,w[1:]对应各个特征的系数w = np.zeros(X.shape[1])  # 形状为(特征数+1,)# 步骤3:通过梯度下降法迭代优化参数for i in range(num_iterations):# 计算线性组合z = X·w(矩阵乘法)# 形状为(样本数,),每个元素对应一个样本的线性计算结果z = np.dot(X, w)# 计算Sigmoid函数值h,得到每个样本的预测概率(0-1之间)# 形状为(样本数,),h[i]表示第i个样本预测为1的概率h = sigmoid(z)# 计算梯度(损失函数对参数w的偏导数)# 形状为(特征数+1,),每个元素表示对应参数的梯度方向grad = calculate_gradient(X, h, y)# 更新参数:沿梯度反方向移动,步长为learning_rate# 这一步是梯度下降的核心,通过不断调整参数减小损失w -= learning_rate * grad# 每1000次迭代打印一次损失值,监控训练过程# 损失值逐渐减小说明模型在优化,趋于稳定说明接近最优解if i % 1000 == 0:loss = calculate_loss(h, y)  # 计算当前的平均损失print(f"迭代第{i}次,损失:{loss:.4f}")  # 保留4位小数打印return w  # 返回训练好的参数,包含截距项和各特征系数
5. 训练模型并画分类边界
# 准备数据:特征X(X0、X1),标签y(Y)
X = df[['X0', 'X1']].values
y = df['Y'].values# 训练模型
trained_w = logistic_regression(X, y)# 画分类边界(红线就是分开两类点的线)
plt.figure(figsize=(10,6))
plt.scatter(df['X0'], df['X1'], c=df['Y'])# 生成网格点(覆盖整个图的范围)
x1_min, x1_max = df['X0'].min(), df['X0'].max()
x2_min, x2_max = df['X1'].min(), df['X1'].max()
xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max), np.linspace(x2_min, x2_max))# 计算每个网格点的预测结果(判断在边界哪一侧)
grid = np.c_[xx1.ravel(), xx2.ravel()]  # 把网格点转成特征格式
# 加截距列(1),算线性结果z
z = np.dot(np.c_[np.ones(grid.shape[0]), grid], trained_w)
# 画边界:z=0的地方就是分类线(Sigmoid(z)=0.5的位置)
plt.contour(xx1, xx2, z.reshape(xx1.shape), levels=[0], colors='red', linewidths=2)
plt.show()

运行后会看到一条红线,能较好地把两类点分开 —— 这就是逻辑回归找到的 “分类边界”。

方式 2:用 sklearn 快速实现(实际工作常用)

手动实现是为了理解原理,实际工作中直接用 sklearn 库,几行代码就能搞定:

from sklearn.linear_model import LogisticRegression# 1. 初始化模型(设置参数:迭代次数足够多,确保收敛)
model = LogisticRegression(max_iter=10000, solver='liblinear')# 2. 训练模型(直接喂特征X和标签y)
model.fit(X, y)# 3. 查看模型参数(系数w和截距b)
print("系数w:", model.coef_)  # 对应X0、X1的系数
print("截距b:", model.intercept_)  # 对应手动实现中的trained_w[0]# 4. 计算准确率(模型在训练集上的正确率)
accuracy = model.score(X, y)
print(f"模型准确率:{accuracy:.4f}")  # 通常能达到0.9以上# 5. 画分类边界(和手动实现类似,红线分开两类点)
plt.figure(figsize=(10,6))
plt.scatter(df['X0'], df['X1'], c=df['Y'])
z = np.dot(grid, model.coef_.T) + model.intercept_  # 算线性结果
plt.contour(xx1, xx2, z.reshape(xx1.shape), levels=[0], colors='red', linewidths=2)
plt.show()

sklearn 已经封装好了所有复杂逻辑,我们只需调用接口,效率极高。

五、回到最初的问题:逻辑回归为什么带 “回归” 二字?

现在能回答开头的疑问了:

  • “逻辑”:来自 “逻辑分布”(Sigmoid 函数是逻辑分布的核心),代表 “是 / 否” 的二分类逻辑;
  • “回归”:因为它的核心是用线性模型(和线性回归一样的 w×X + b)构建分类边界,本质是 “线性模型的分类应用”,所以保留了 “回归” 的名字。

六、总结:逻辑回归的核心要点

  1. 本质:二分类模型,用 “线性模型 + Sigmoid” 实现概率预测;
  2. 关键工具
    • Sigmoid 函数:压缩输出到 0-1(概率);
    • 对数损失函数:衡量预测误差;
    • 梯度下降:找到最优参数(w 和 b);
  3. 优势:简单、高效、易解释,适合处理二分类问题(如垃圾邮件识别、疾病初筛);
  4. 实战:手动实现理解原理,sklearn 快速落地。

只要记住 “线性回归做基础,Sigmoid 来转换,梯度下降找最优”,逻辑回归的核心就掌握了!


文章转载自:

http://qet3dbXo.zdkzj.cn
http://GsfbAJWi.zdkzj.cn
http://ZwdMgKGk.zdkzj.cn
http://BuxPB7Bh.zdkzj.cn
http://R5OTErc6.zdkzj.cn
http://ysWSvZbc.zdkzj.cn
http://1hEHgEMT.zdkzj.cn
http://qUcumS62.zdkzj.cn
http://v3qW6X2t.zdkzj.cn
http://T6oGWYoi.zdkzj.cn
http://V1U1xQLS.zdkzj.cn
http://ESyrcYZX.zdkzj.cn
http://W1i3AzdC.zdkzj.cn
http://FfpNQ9q7.zdkzj.cn
http://eyMZdNHP.zdkzj.cn
http://0LoNcBKX.zdkzj.cn
http://xVJV21G2.zdkzj.cn
http://udyUwU1d.zdkzj.cn
http://PmSYl1Q9.zdkzj.cn
http://XtSs9Mhc.zdkzj.cn
http://WYOaRzG2.zdkzj.cn
http://foeCvUBC.zdkzj.cn
http://qepOb3Ti.zdkzj.cn
http://zsi8sDjC.zdkzj.cn
http://bXUBKmhl.zdkzj.cn
http://3QFcoZIm.zdkzj.cn
http://tgsjM4eM.zdkzj.cn
http://GwhoEOVC.zdkzj.cn
http://S7lSHgV8.zdkzj.cn
http://ZUIvU9Xf.zdkzj.cn
http://www.dtcms.com/a/364992.html

相关文章:

  • 爬取m3u8视频完整教程
  • GitHub 上那些值得收藏的英文书籍推荐(计算机 非计算机类)
  • 一键掌握服务器健康状态与安全风险
  • 前端视角下的 Web 安全攻防:XSS、CSRF、DDoS 一次看懂
  • 02、连接服务器的几种方式
  • 企业文档安全守护者全面测评:7款加密软件深度解析,让商业机密固若金汤
  • JVM分析(OOM、死锁、死循环)(JProfiler、arthas、jvm自带工具)
  • 股指期货可以通过移仓长线持有吗?
  • 基于springboot的在线答题练习系统
  • 【正则表达式】 正则表达式的元字符是什么?正则表达式的元字符有什么作用?
  • 微软rStar2-Agent:新的GRPO-RoC算法让14B模型在复杂推理时超越了前沿大模型
  • DAO LLC:怀俄明州首个承认去中心化自治组织法人化的新里程碑
  • Android Looper源码阅读
  • 手搓一个企业级Agent智能体
  • PyTorch 面试题及详细答案120题(116-120)-- 综合应用与实践
  • 英语四级学习指南
  • 《单链表学习手册:从原理到代码实现(含头插 / 尾插 / 销毁)》
  • go-mapus为局域网地图协作而生
  • 充电枪结构-常规特征设计
  • 小程序点击之数据绑定
  • 【数学建模学习笔记】相关性分析
  • Git在idea中的实战使用经验(二)
  • Elasticsearch 数字字段随机取多值查询缓慢-原理分析与优化方案
  • 408考研——单链表代码题常见套路总结
  • [光学原理与应用-375]:ZEMAX - 分析 - 物理光学图
  • Debezium报错处理系列之第130篇:OutOfMemoryError: Java heap space
  • 复杂网络环境不用愁,声网IoT多通道传输实战经验丰富
  • 数据结构---双向链表
  • 明确用户提问的核心
  • 【计算机网络】TCP状态转移