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

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

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

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

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

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. 梯度下降:"一步步找最优参数"

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

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

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

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

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

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

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

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

先看看数据长什么样:

python 复制代码
# 加载数据集(网上可直接获取)
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、损失、梯度)
python 复制代码
# 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. 实现逻辑回归的训练过程
python 复制代码
def logistic_regression(X, y, learning_rate=0.01, num_iterations=30000):
    """
    逻辑回归模型训练函数,通过梯度下降法寻找最优参数
    
    参数:
    X: 特征数据,形状为 (样本数, 特征数) 的numpy数组
    y: 标签数据,形状为 (样本数,) 的numpy数组,值为0或1
    learning_rate: 学习率,控制梯度下降的步长,默认0.01
    num_iterations: 迭代次数,控制梯度下降的迭代轮数,默认30000
    
    返回:
    w: 训练好的参数,包含截距项,形状为 (特征数+1,) 的numpy数组
    """
    # 步骤1:给特征矩阵添加截距列(全为1)
    # 这是为了将截距项b整合到参数w中,相当于给每个样本增加一个恒为1的特征x0
    # 此时模型变为 z = w0*x0 + w1*x1 + ... + wn*xn,其中x0=1,w0即截距b
    intercept = 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. 训练模型并画分类边界
python 复制代码
# 准备数据:特征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 库,几行代码就能搞定:

python 复制代码
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 来转换,梯度下降找最优",逻辑回归的核心就掌握了!

相关推荐
SHIPKING3933 小时前
【机器学习&深度学习】LLM:在检索与重排序中的适用场景
人工智能·深度学习·机器学习·llm
THMAIL4 小时前
机器学习从入门到精通 - 降维艺术:PCA与t-SNE带你玩转高维数据可视化
人工智能·python·决策树·随机森林·机器学习·分类·bootstrap
diablobaal4 小时前
云计算学习100天-第39天
学习·云计算
@Dai4 小时前
【跨境电商】上中下游解释,以宠物行业为例
经验分享·笔记·学习·其他·宠物
品牌AI前线4 小时前
AI生成内容的版权迷局:GPT-4输出的“创意”版权风险与规避之道
人工智能·深度学习·机器学习
辰熙咨询洪千武4 小时前
《华为基本法》——企业文化的精髓,你学习了几条?
学习·职场和发展·创业创新·业界资讯
AnySpaceOne5 小时前
MP4视频太大如何压缩?分享6种简单便捷的压缩小技巧
学习·音视频
hansang_IR5 小时前
【线性代数基础 | 那忘算9】基尔霍夫(拉普拉斯)矩阵 & 矩阵—树定理证明 [详细推导]
c++·笔记·线性代数·算法·矩阵·矩阵树定理·基尔霍夫矩阵
尚久龙5 小时前
安卓学习 之 模拟登录界面
java·学习·手机·android studio·安卓