哈喽,我是黑棠
在《当机器学会“预测”:一次搞懂三大回归技术》文章中,我们通过南瓜市场的例子,介绍了线性回归、多项式回归和逻辑回归的应用。但你可能想知道:这些模型内部的数学原理究竟是什么?它们是如何“学习”和“预测”的?

今天,我们就来揭开这层神秘的面纱,用最直观的方式理解回归背后的数学思想。


逻辑回归篇

在医院的诊断室,你很少听到医生说:“这肯定是流感。”
更多时候,你会听到:“根据你的症状,大概率是流感。”
这种“概率思维”正是逻辑回归的核心。虽然名字里有“回归”,但它其实是解决分类问题的利器。
今天,我们就通过医疗诊断的场景,看看逻辑回归如何将复杂的证据转化为清晰的概率判断。

猜硬币游戏

游戏规则

我手里藏着一枚硬币,让你猜是正面还是反面。但我会给你线索:

  • 线索1:我抛硬币的高度(高/中/低)
  • 线索2:我接住的方式(手背/手心)
  • 线索3:今天的日期(单数/双数)

你需要根据这些线索,设计一个能预测硬币正反面概率的系统。
在这里插入图片描述

这就是逻辑回归!

逻辑回归的独特思维:
它不直接说“是正面”,而是说“有70%的概率是正面”。

  1. 收集线索:记录100次抛硬币的(高度,接法,日期)和结果
  2. 计算得分:根据线索计算一个“正面积分”
    • 高抛:+2分(更容易是正面)
    • 手心接:-1分(更可能是反面)
    • 单数日:+0.5分
  3. 转换为概率:通过一个神奇的S形函数,把“正面积分”变成“正面概率”
  4. 做出决策:如果概率>50%,猜正面;否则猜反面

生活中的逻辑回归

  • 判断:根据症状,得流感概率有多大
  • 评估:贷款申请人违约的可能性
  • 预测:客户购买产品的概率
  • 诊断:肿瘤是恶性的概率

关键点:逻辑回归其实是用回归方法解决分类问题——它先计算一个“证据得分”,再把得分转化为概率,最后根据概率做分类。


⚖️ 逻辑回归:概率世界的“天平”

关键突破:从数值预测到概率预测

逻辑回归最核心的数学创新是Sigmoid函数(也叫Logistic函数)。

Sigmoid函数:

σ(𝑧) = 1 / (1 + 𝑒⁻ᶻ)

这个函数的神奇之处在于:

  • 无论输入𝑧是多少,输出都被压缩到**(0, 1)**之间
  • 当𝑧=0时,σ(𝑧)=0.5
  • 当𝑧→∞时,σ(𝑧)→1
  • 当𝑧→-∞时,σ(𝑧)→0

逻辑回归的完整公式:

  1. 首先像线性回归一样计算:𝑧 = 𝑤𝑥 + 𝑏
  2. 然后通过Sigmoid函数:𝑃(𝑦=1|𝑥) = σ(𝑧) = 1 / (1 + 𝑒⁻⁽ʷˣ⁺ᵇ⁾)

这里𝑃(𝑦=1|𝑥)表示在给定特征𝑥的条件下,样本属于类别1的概率。

损失函数的变化:从均方误差到交叉熵

线性回归用均方误差,但这对概率问题不合适。

逻辑回归使用交叉熵损失:
𝐿 = -[𝑦·log(𝑃) + (1-𝑦)·log(1-𝑃)]

这个函数的特点是:

  • 当真实标签𝑦=1时,如果预测概率𝑃接近1,损失接近0
  • 当真实标签𝑦=1时,如果预测概率𝑃接近0,损失会非常大
  • 对𝑦=0的情况对称

决策边界:

虽然我们得到的是概率,但最终需要做出分类决策。通常设置一个阈值(如0.5):

  • 如果𝑃 ≥ 0.5,预测为类别1
  • 如果𝑃 < 0.5,预测为类别0

这个0.5的阈值对应的𝑧值就是:𝑧 = 𝑤𝑥 + 𝑏 = 0
因此,𝑤𝑥 + 𝑏 = 0 定义了一条“决策边界”。
在这里插入图片描述


💻 代码实战

如何用逻辑回归决定是否批准一笔贷款?
这个脚本模拟了基于“收入”和“信用分”的审批逻辑,并画出了那条隐形的“决策边界”。

👉 代码示例:


import os![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/4a8ae5f7e11947b2a8cfe7ca81131970.png)

import sys
import io
# 设置控制台输出为 UTF-8 编码
if sys.platform == 'win32':
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
    os.system('chcp 65001 > nul 2>&1')

import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix
import matplotlib.pyplot as plt

# 配置 matplotlib 中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'DejaVu Sans']  # 使用黑体或微软雅黑
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

def generate_loan_data(n_samples=200):
    """
    生成模拟贷款数据
    特征1: 月收入 (0.5万 - 5万)
    特征2: 信用分 (300 - 850)
    标签: 0 (拒绝) 或 1 (批准)
    """
    np.random.seed(42)
    income = np.random.uniform(0.5, 5, n_samples) # 单位:万
    credit = np.random.uniform(300, 850, n_samples)
    
    # 真实的决策逻辑(包含一些随机性)
    # 综合得分 = 收入 * 2 + (信用分-600)/50
    # 如果得分 > 5,则批准概率高
    score = income * 2 + (credit - 600) / 50
    probability = 1 / (1 + np.exp(-(score - 5))) # Sigmoid转换
    
    # 根据概率生成标签
    labels = (np.random.random(n_samples) < probability).astype(int)
    
    X = np.column_stack((income, credit))
    return X, labels

def main():
    print("🤖 开始执行逻辑回归任务:贷款审批预测...\n")
    
    # 1. 准备数据
    print("1. 收集申请人数据(收入 & 信用分)...")
    X, y = generate_loan_data()
    print(f"   样本数量: {len(X)}")
    print(f"   批准比例: {np.mean(y)*100:.1f}%")
    
    # 2. 训练模型
    print("\n2. 训练逻辑回归模型...")
    model = LogisticRegression()
    model.fit(X, y)
    
    # 获取参数
    w = model.coef_[0]
    b = model.intercept_[0]
    print(f"   ✅ 模型训练完成!")
    print(f"   特征权重: 收入 w1={w[0]:.2f}, 信用分 w2={w[1]:.2f}")
    print(f"   (正权重表示该特征越高,越容易获得批准)")
    
    # 3. 模拟新申请人评估
    print("\n3. 评估新申请人...")
    applicants = [
        [1.5, 500],  # 收入低,信用低 -> 应该拒绝
        [4.0, 750],  # 收入高,信用高 -> 应该批准
        [2.5, 650]   # 中等 -> 看概率
    ]
    
    for i, app in enumerate(applicants):
        # 预测概率
        prob = model.predict_proba([app])[0][1] # 获取类别1(批准)的概率
        # 预测结果
        pred = model.predict([app])[0]
        result = "✅ 批准" if pred == 1 else "❌ 拒绝"
        
        print(f"   申请人{i+1}: 收入{app[0]}万, 信用{app[1]}分")
        print(f"     -> 批准概率: {prob*100:.1f}%")
        print(f"     -> 最终决策: {result}")
        print("-" * 30)

    # 4. 可视化决策边界
    try:
        plt.figure(figsize=(10, 6))
        
        # 绘制数据点
        plt.scatter(X[y==0][:,0], X[y==0][:,1], color='red', alpha=0.6, label='已拒绝')
        plt.scatter(X[y==1][:,0], X[y==1][:,1], color='blue', alpha=0.6, label='已批准')
        
        # 绘制决策边界 (w1*x1 + w2*x2 + b = 0)
        # x2 = -(w1*x1 + b) / w2
        x1_min, x1_max = X[:, 0].min(), X[:, 0].max()
        x1_vals = np.linspace(x1_min, x1_max, 100)
        x2_vals = -(w[0] * x1_vals + b) / w[1]
        
        plt.plot(x1_vals, x2_vals, color='green', linewidth=2, linestyle='--', label='决策边界 (50%概率线)')
        
        plt.title('逻辑回归:贷款审批决策边界')
        plt.xlabel('月收入 (万)')
        plt.ylabel('信用分')
        plt.legend()
        plt.grid(True, alpha=0.3)
        plt.ylim(300, 900) # 限制y轴范围
        plt.savefig('logistic_regression_plot.png')
        print("\n📊 决策边界图已保存为 'logistic_regression_plot.png'")
        
    except Exception as e:
        print(f"绘图失败: {e}")

if __name__ == "__main__":
    main()

试着修改代码中的申请人数据,看看模型会给出什么样的概率判断?


总结一下

💎 本期核心要点

逻辑回归本质:先计算“证据积分”,再用Sigmoid函数转换为概率
Sigmoid函数:将任意实数压缩到(0,1),完美表示概率
决策边界:概率=0.5对应的那条“分界线”
交叉熵损失:专为概率预测设计的误差衡量方式

🔍 一个巧妙类比

逻辑回归的思考过程,很像法官判案:
收集证据(症状、化验结果)→ 计算证据积分(z = w₁x₁ + w₂x₂ + …)
评估证据强度 → 通过Sigmoid函数得到“有罪概率”
做出判决(概率>0.5判有罪)→ 确定诊断结果

下一篇预告:三大回归的数学对比


本文首发于CSDN:[黑棠会长],转载请注明来源。
关注我,一起用轻松的方式读懂前沿科技。

更多推荐