《计算机视觉:模型、学习和推理》第 8 章-回归模型

目录

前言

[8.1 线性回归](#8.1 线性回归)

核心概念

[8.1.1 学习(最小二乘法求解)](#8.1.1 学习(最小二乘法求解))

完整代码(含可视化对比)

代码解释

运行效果

[8.1.2 线性回归模型的问题](#8.1.2 线性回归模型的问题)

可视化对比(线性回归拟合非线性数据)

运行效果

[8.2 贝叶斯线性回归](#8.2 贝叶斯线性回归)

核心概念

[8.2.1 实际考虑](#8.2.1 实际考虑)

[8.2.2 拟合方差](#8.2.2 拟合方差)

[完整代码(贝叶斯线性回归 + 方差可视化)](#完整代码(贝叶斯线性回归 + 方差可视化))

运行效果

[8.3 非线性回归](#8.3 非线性回归)

核心概念

[8.3.1 最大似然法](#8.3.1 最大似然法)

[8.3.2 贝叶斯非线性回归](#8.3.2 贝叶斯非线性回归)

完整代码(非线性回归对比)

运行效果

[8.4 核与核技巧](#8.4 核与核技巧)

核心概念

代码(核技巧实现非线性回归)

运行效果

[8.5 高斯过程回归](#8.5 高斯过程回归)

核心概念

完整代码

运行效果

[8.6 稀疏线性回归](#8.6 稀疏线性回归)

核心概念

[代码(稀疏回归 vs 普通回归)](#代码(稀疏回归 vs 普通回归))

运行效果

[8.7 二元线性回归](#8.7 二元线性回归)

核心概念

代码(二元回归分类)

运行效果

[8.8 相关向量回归](#8.8 相关向量回归)

核心概念

[8.9 多变量数据回归](#8.9 多变量数据回归)

核心概念

代码(多变量回归:预测波士顿房价)

运行效果

[8.10 应用](#8.10 应用)

[8.10.1 人体姿势估计](#8.10.1 人体姿势估计)

[8.10.2 位移专家](#8.10.2 位移专家)

简化示例代码(模拟位移预测)

运行效果

讨论

备注

习题

总结

前言

大家好!今天我们来拆解《计算机视觉:模型、学习和推理》这本经典教材的第 8 章 ------ 回归模型 。回归是计算机视觉中最基础也最核心的技术之一,不管是人体姿势估计、目标跟踪还是图像拟合,都离不开回归的身影。

这篇文章不会堆砌复杂公式,而是用「大白话 + 可直接运行的代码 + 可视化对比图」的方式,把线性回归、贝叶斯回归、非线性回归等核心知识点讲透,所有代码都适配 Mac 系统的 Matplotlib 中文显示,复制就能跑!

8.1 线性回归

核心概念

线性回归就像**「找一根最贴合数据点的直线」** ,比如用身高预测体重、用像素值预测物体位置。它的核心逻辑是:假设输入特征 x 和输出标签 y 之间满足线性关系 y=wx+b+ϵ(ϵ 是噪声),我们的目标是找到最优的权重 w 和偏置 b ,让预测值和真实值的误差最小

8.1.1 学习(最小二乘法求解)

最小二乘法是线性回归最常用的求解方法,核心是「让所有数据点到直线的垂直距离平方和最小」。

完整代码(含可视化对比)
复制代码
import numpy as np
import matplotlib.pyplot as plt

# ==================== Mac系统Matplotlib中文显示配置 ====================
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.family'] = 'Arial Unicode MS'
plt.rcParams['axes.facecolor'] = 'white'

# ==================== 生成模拟数据 ====================
# 真实模型:y = 2x + 1 + 噪声(模拟真实世界的误差)
np.random.seed(42)  # 固定随机种子,保证结果可复现
x = np.linspace(0, 10, 100)  # 生成0-10之间的100个均匀分布的数
noise = np.random.normal(0, 1, size=x.shape)  # 高斯噪声
y_true = 2 * x + 1  # 真实值(无噪声)
y = y_true + noise  # 带噪声的观测值

# ==================== 最小二乘法求解线性回归 ====================
# 构造X矩阵(添加偏置项,即常数项1)
X = np.vstack([x, np.ones_like(x)]).T
# 最小二乘法公式:w = (X^T X)^-1 X^T y
w = np.linalg.inv(X.T @ X) @ X.T @ y
w_slope = w[0]  # 斜率(对应公式中的w)
w_intercept = w[1]  # 截距(对应公式中的b)

# 生成预测值
y_pred = w_slope * x + w_intercept

# ==================== 可视化对比(原始数据+真实直线+拟合直线) ====================
plt.figure(figsize=(10, 6))
# 绘制带噪声的原始数据点
plt.scatter(x, y, label='带噪声的观测数据', color='lightcoral', alpha=0.7)
# 绘制真实的线性模型
plt.plot(x, y_true, label='真实模型: y=2x+1', color='darkgreen', linewidth=2, linestyle='--')
# 绘制拟合的线性模型
plt.plot(x, y_pred, label=f'拟合模型: y={w_slope:.2f}x+{w_intercept:.2f}', color='royalblue', linewidth=2)

plt.xlabel('输入特征 x', fontsize=12)
plt.ylabel('输出标签 y', fontsize=12)
plt.title('线性回归最小二乘法拟合效果对比', fontsize=14)
plt.legend(fontsize=10)
plt.grid(True, alpha=0.3)
plt.show()

# 输出拟合结果
print(f"拟合得到的斜率:{w_slope:.4f}(真实值:2)")
print(f"拟合得到的截距:{w_intercept:.4f}(真实值:1)")
代码解释

1.数据生成:模拟了真实线性关系 + 高斯噪声的数据集,更贴近实际场景;

2.最小二乘法求解:通过矩阵运算直接求解最优权重,避免手动迭代;

3.可视化对比:把「带噪声的原始数据」「真实直线」「拟合直线」放在同一张图里,直观看到拟合效果。

运行效果

会弹出一个窗口,显示:

  • 浅红色散点:带噪声的观测数据;
  • 绿色虚线:真实的 y=2x+1;
  • 蓝色实线:拟合的直线(接近真实值)。

8.1.2 线性回归模型的问题

线性回归的「硬伤」很明显,用大白话总结就是:

  1. 过拟合风险 :当特征维度远大于数据量时,模型会「死记硬背」噪声,泛化能力差;
  2. 对异常值敏感 :最小二乘法会放大异常值的影响(比如一个离群点能把拟合直线拉偏);
  3. 无法拟合非线性关系 :如果数据本身是曲线(比如 y=x²),线性回归的拟合效果会极差。
可视化对比(线性回归拟合非线性数据)
python 复制代码
import numpy as np
import matplotlib.pyplot as plt

# ==================== Mac系统Matplotlib中文显示配置 ====================
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.family'] = 'Arial Unicode MS'
plt.rcParams['axes.facecolor'] = 'white'

# ==================== 生成非线性数据 ====================
np.random.seed(42)
x = np.linspace(-2, 2, 100)
y_true = x**2 + 0.5 * x + 1  # 二次函数(非线性)
y = y_true + np.random.normal(0, 0.3, size=x.shape)

# ==================== 线性回归拟合 ====================
X = np.vstack([x, np.ones_like(x)]).T
w = np.linalg.inv(X.T @ X) @ X.T @ y
y_pred_linear = w[0] * x + w[1]

# ==================== 可视化对比 ====================
plt.figure(figsize=(10, 6))
plt.scatter(x, y, label='非线性观测数据', color='lightcoral', alpha=0.7)
plt.plot(x, y_true, label='真实非线性模型: y=x²+0.5x+1', color='darkgreen', linewidth=2, linestyle='--')
plt.plot(x, y_pred_linear, label=f'线性回归拟合', color='royalblue', linewidth=2)

plt.xlabel('输入特征 x', fontsize=12)
plt.ylabel('输出标签 y', fontsize=12)
plt.title('线性回归拟合非线性数据的效果对比', fontsize=14)
plt.legend(fontsize=10)
plt.grid(True, alpha=0.3)
plt.show()
运行效果

能明显看到:线性回归的直线完全无法贴合二次函数的曲线,这就是线性回归的核心局限性。

8.2 贝叶斯线性回归

核心概念

如果说普通线性回归是「一次性算出最优解」,贝叶斯线性回归就是「给解加个 "置信区间"」------ 它不追求单一的最优 w 和 b,而是给出 w 的概率分布 ,能回答**「这个拟合结果有多可信?」**。

举个例子:普通线性回归告诉你「拟合斜率是 2」,贝叶斯线性回归会告诉你「斜率有 95% 的概率在 1.9~2.1 之间」,这对计算机视觉中需要评估预测不确定性的场景(比如自动驾驶的距离预测)非常重要。

8.2.1 实际考虑

贝叶斯线性回归的核心是「先验 + 似然 = 后验」:

  • 先验:对权重 w 的初始假设(比如假设 w 服从高斯分布);
  • 似然:观测数据对 w 的支持程度;
  • 后验:结合先验和数据后,w 的最终概率分布。

8.2.2 拟合方差

拟合方差反映了「模型对不同数据集的敏感程度」------ 方差大,说明换一批数据拟合出来的直线差异大;方差小,说明拟合结果稳定。贝叶斯线性回归能直接计算方差,而普通线性回归做不到。

完整代码(贝叶斯线性回归 + 方差可视化)
复制代码
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm

# ==================== Mac字体配置 ====================
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.family'] = 'Arial Unicode MS'
plt.rcParams['axes.facecolor'] = 'white'

# ==================== 生成数据 ====================
np.random.seed(42)
x = np.linspace(0, 10, 50)
y_true = 1.5 * x + 2
y = y_true + np.random.normal(0, 1.2, size=x.shape)
X = np.vstack([x, np.ones_like(x)]).T

# ==================== 贝叶斯线性回归求解 ====================
# 超参数:先验的方差、似然的方差
alpha = 1.0  # 先验w ~ N(0, alpha^-1 I)
beta = 10.0  # 似然y | x, w ~ N(w^T x, beta^-1)

# 后验协方差矩阵:Sigma = (alpha I + beta X^T X)^-1
Sigma = np.linalg.inv(alpha * np.eye(X.shape[1]) + beta * X.T @ X)
# 后验均值:mu = beta Sigma X^T y
mu = beta * Sigma @ X.T @ y

# 生成预测区间
x_test = np.linspace(0, 10, 100)
X_test = np.vstack([x_test, np.ones_like(x_test)]).T
# 预测均值
y_pred_mean = X_test @ mu
# 预测方差(包含模型不确定性+噪声)
y_pred_var = 1/beta + np.diag(X_test @ Sigma @ X_test.T)
# 95%置信区间
y_pred_upper = y_pred_mean + 2 * np.sqrt(y_pred_var)
y_pred_lower = y_pred_mean - 2 * np.sqrt(y_pred_var)

# ==================== 可视化 ====================
plt.figure(figsize=(10, 6))
plt.scatter(x, y, label='观测数据', color='lightcoral', alpha=0.7)
plt.plot(x_test, y_pred_mean, label='贝叶斯回归均值', color='royalblue', linewidth=2)
# 填充95%置信区间(方差可视化)
plt.fill_between(x_test, y_pred_lower, y_pred_upper, color='skyblue', alpha=0.3, label='95%置信区间')
plt.plot(x, y_true, label='真实模型', color='darkgreen', linestyle='--', linewidth=2)

plt.xlabel('输入特征 x', fontsize=12)
plt.ylabel('输出标签 y', fontsize=12)
plt.title('贝叶斯线性回归拟合效果(含方差可视化)', fontsize=14)
plt.legend(fontsize=10)
plt.grid(True, alpha=0.3)
plt.show()

# 输出后验均值和方差
print(f"权重后验均值:w={mu[0]:.4f}, b={mu[1]:.4f}")
print(f"权重后验方差:\n{Sigma}")
运行效果

图中蓝色填充区域就是 95% 置信区间(方差的体现),区间越宽,说明该位置的预测不确定性越大,这是普通线性回归无法提供的关键信息。

8.3 非线性回归

核心概念

非线性回归就是「用曲线拟合数据」,解决线性回归无法处理的非线性问题。

核心思路是:把原始线性模型 y=wx+b 中的「线性项 wx」换成「非线性函数 φ(x)」,变成 y=wTφ(x)+b。

比如 φ(x)=[x, x², x³],就能拟合三次曲线;φ(x)=[sin (x), cos (x)],就能拟合周期数据。

8.3.1 最大似然法

和线性回归的最小二乘法本质是一回事(高斯噪声下,最大似然等价于最小二乘),只是把特征换成了非线性特征。

8.3.2 贝叶斯非线性回归

在非线性特征空间中应用贝叶斯框架,既能拟合非线性数据,又能评估预测不确定性。

完整代码(非线性回归对比)
复制代码
import numpy as np
import matplotlib.pyplot as plt

# ==================== Mac字体配置 ====================
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.family'] = 'Arial Unicode MS'
plt.rcParams['axes.facecolor'] = 'white'

# ==================== 生成非线性数据(正弦曲线+噪声) ====================
np.random.seed(42)
x = np.linspace(0, 2*np.pi, 100)
y_true = np.sin(x) + 0.5 * np.cos(2*x)
y = y_true + np.random.normal(0, 0.15, size=x.shape)

# ==================== 1. 线性回归(对比组) ====================
X_linear = np.vstack([x, np.ones_like(x)]).T
w_linear = np.linalg.inv(X_linear.T @ X_linear) @ X_linear.T @ y
y_pred_linear = X_linear @ w_linear

# ==================== 2. 非线性回归(多项式特征,最大似然) ====================
# 构造非线性特征:[x, x², x³, x⁴, 1](4次多项式)
X_nonlinear = np.vstack([x, x**2, x**3, x**4, np.ones_like(x)]).T
w_nonlinear = np.linalg.inv(X_nonlinear.T @ X_nonlinear) @ X_nonlinear.T @ y
y_pred_nonlinear = X_nonlinear @ w_nonlinear

# ==================== 3. 贝叶斯非线性回归 ====================
alpha = 1.0
beta = 50.0
Sigma = np.linalg.inv(alpha * np.eye(X_nonlinear.shape[1]) + beta * X_nonlinear.T @ X_nonlinear)
mu = beta * Sigma @ X_nonlinear.T @ y
y_pred_bayes = X_nonlinear @ mu
# 计算预测方差
y_pred_var = 1/beta + np.diag(X_nonlinear @ Sigma @ X_nonlinear.T)
y_pred_upper = y_pred_bayes + 2 * np.sqrt(y_pred_var)
y_pred_lower = y_pred_bayes - 2 * np.sqrt(y_pred_var)

# ==================== 可视化对比 ====================
plt.figure(figsize=(12, 7))
plt.scatter(x, y, label='观测数据', color='lightcoral', alpha=0.7, s=30)
plt.plot(x, y_true, label='真实非线性模型(正弦+余弦)', color='darkgreen', linewidth=2, linestyle='--')
plt.plot(x, y_pred_linear, label='线性回归拟合', color='orange', linewidth=2)
plt.plot(x, y_pred_nonlinear, label='非线性回归(4次多项式)', color='royalblue', linewidth=2)
plt.fill_between(x, y_pred_lower, y_pred_upper, color='skyblue', alpha=0.3, label='贝叶斯非线性回归95%置信区间')

plt.xlabel('输入特征 x', fontsize=12)
plt.ylabel('输出标签 y', fontsize=12)
plt.title('线性回归 vs 非线性回归 vs 贝叶斯非线性回归 效果对比', fontsize=14)
plt.legend(fontsize=10)
plt.grid(True, alpha=0.3)
plt.show()
运行效果
  • 橙色直线:线性回归完全拟合不了正弦曲线;
  • 蓝色曲线:非线性回归(4 次多项式)几乎和真实曲线重合;
  • 浅蓝色填充:贝叶斯非线性回归的置信区间,能看到曲线两端的不确定性略大(数据少)。

8.4 核与核技巧

核心概念

核技巧是非线性回归的「神器」,可以理解为「不用显式计算高维非线性特征,就能间接在高维空间做线性回归」。

打个比方:你想把二维平面的非线性数据分开,直接在二维空间做不到,但核技巧能「偷偷把数据映射到三维空间」,在三维空间用平面分开后,再映射回二维,就得到了非线性的分隔曲线。

常用的核函数:

  • 高斯核(RBF 核):最常用,能拟合任意复杂的非线性关系;
  • 多项式核:对应多项式特征映射;
  • 线性核:等价于普通线性回归。
代码(核技巧实现非线性回归)
复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import Ridge
from sklearn.kernel_ridge import KernelRidge

# ==================== Mac字体配置 ====================
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.family'] = 'Arial Unicode MS'
plt.rcParams['axes.facecolor'] = 'white'

# ==================== 生成数据 ====================
np.random.seed(42)
x = np.linspace(-3, 3, 100).reshape(-1, 1)  # sklearn要求输入是2D数组
y_true = np.exp(-x**2) + 3 * np.exp(-(x-2)**2)
y = y_true + np.random.normal(0, 0.1, size=x.shape)

# ==================== 核回归 ====================
# 1. 线性核(对比组)
kr_linear = KernelRidge(kernel='linear', alpha=0.01)
kr_linear.fit(x, y)
y_pred_linear = kr_linear.predict(x)

# 2. 高斯核(RBF核)
kr_rbf = KernelRidge(kernel='rbf', gamma=0.5, alpha=0.01)
kr_rbf.fit(x, y)
y_pred_rbf = kr_rbf.predict(x)

# ==================== 可视化 ====================
plt.figure(figsize=(10, 6))
plt.scatter(x, y, label='观测数据', color='lightcoral', alpha=0.7)
plt.plot(x, y_true, label='真实模型', color='darkgreen', linewidth=2, linestyle='--')
plt.plot(x, y_pred_linear, label='线性核回归', color='orange', linewidth=2)
plt.plot(x, y_pred_rbf, label='高斯核(RBF)回归', color='royalblue', linewidth=2)

plt.xlabel('输入特征 x', fontsize=12)
plt.ylabel('输出标签 y', fontsize=12)
plt.title('核技巧:线性核 vs 高斯核 回归效果对比', fontsize=14)
plt.legend(fontsize=10)
plt.grid(True, alpha=0.3)
plt.show()
运行效果

高斯核回归的曲线完美贴合真实模型,而线性核回归只能拟合出直线,体现了核技巧的强大之处。

8.5 高斯过程回归

核心概念

高斯过程回归(GPR)是贝叶斯框架 + 核技巧的「终极形态」,可以理解为「对整个函数空间建模」------ 它不只是预测每个点的 y 值,而是给出整个函数的概率分布,不确定性估计更精准。

GPR 是计算机视觉中高端回归任务的首选(比如小样本的精细拟合),缺点是计算成本较高。

完整代码
复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, WhiteKernel

# ==================== Mac字体配置 ====================
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.family'] = 'Arial Unicode MS'
plt.rcParams['axes.facecolor'] = 'white'

# ==================== 生成数据 ====================
np.random.seed(42)
x = np.linspace(0, 10, 20).reshape(-1, 1)  # 小样本(20个点)
y_true = np.sin(x) + 0.2 * x
y = y_true + np.random.normal(0, 0.2, size=x.shape)

# ==================== 高斯过程回归 ====================
# 定义核函数:RBF核 + 白噪声核(处理数据噪声)
kernel = RBF(length_scale=1.0, length_scale_bounds=(1e-1, 10.0)) + WhiteKernel(noise_level=1e-2, noise_level_bounds=(1e-4, 1e-1))
gpr = GaussianProcessRegressor(kernel=kernel, random_state=42)
gpr.fit(x, y)

# 预测(含不确定性)
x_test = np.linspace(0, 10, 100).reshape(-1, 1)
y_pred, y_std = gpr.predict(x_test, return_std=True)

# ==================== 可视化 ====================
plt.figure(figsize=(10, 6))
plt.scatter(x, y, label='观测数据(小样本)', color='lightcoral', alpha=0.7)
plt.plot(x_test, np.sin(x_test) + 0.2 * x_test, label='真实模型', color='darkgreen', linewidth=2, linestyle='--')
plt.plot(x_test, y_pred, label='高斯过程回归预测', color='royalblue', linewidth=2)
# 95%置信区间
plt.fill_between(x_test.ravel(), y_pred - 2*y_std, y_pred + 2*y_std, color='skyblue', alpha=0.3, label='95%置信区间')

plt.xlabel('输入特征 x', fontsize=12)
plt.ylabel('输出标签 y', fontsize=12)
plt.title('高斯过程回归(小样本拟合)', fontsize=14)
plt.legend(fontsize=10)
plt.grid(True, alpha=0.3)
plt.show()

# 输出优化后的核参数
print(f"优化后的RBF长度尺度:{gpr.kernel_.k1.length_scale:.4f}")
print(f"优化后的噪声水平:{gpr.kernel_.k2.noise_level:.4f}")
运行效果

即使只有 20 个样本,GPR 也能精准拟合正弦曲线,且置信区间的宽度能反映预测的不确定性(数据密集处区间窄,稀疏处宽)。

8.6 稀疏线性回归

核心概念

稀疏线性回归的目标是「让大部分权重 w 为 0」,只保留少数重要特征,解决「维度灾难」问题。

比如在图像回归任务中,稀疏回归能自动筛选出对预测有用的像素,忽略无关像素,既减少计算量,又降低过拟合风险。最常用的方法是 Lasso 回归(L1 正则化)。

代码(稀疏回归 vs 普通回归)
复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression, Lasso

# ==================== Mac字体配置 ====================
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.family'] = 'Arial Unicode MS'
plt.rcParams['axes.facecolor'] = 'white'

# ==================== 生成高维稀疏数据 ====================
np.random.seed(42)
n_samples = 100
n_features = 20
# 真实权重:只有前5个特征有非零值(稀疏)
w_true = np.zeros(n_features)
w_true[:5] = [1, -0.8, 0.6, -0.4, 0.2]
# 生成特征和标签
X = np.random.normal(0, 1, (n_samples, n_features))
y = X @ w_true + np.random.normal(0, 0.1, n_samples)

# ==================== 拟合模型 ====================
# 1. 普通线性回归
lr = LinearRegression()
lr.fit(X, y)
w_lr = lr.coef_

# 2. Lasso稀疏回归
lasso = Lasso(alpha=0.05, random_state=42)
lasso.fit(X, y)
w_lasso = lasso.coef_

# ==================== 可视化权重对比 ====================
plt.figure(figsize=(12, 6))
x_axis = np.arange(n_features)
width = 0.25

plt.bar(x_axis - width, w_true, width, label='真实权重', color='darkgreen', alpha=0.7)
plt.bar(x_axis, w_lr, width, label='普通线性回归权重', color='orange', alpha=0.7)
plt.bar(x_axis + width, w_lasso, width, label='Lasso稀疏回归权重', color='royalblue', alpha=0.7)

plt.axhline(y=0, color='black', linestyle='-', alpha=0.3)
plt.xlabel('特征维度', fontsize=12)
plt.ylabel('权重值', fontsize=12)
plt.title('稀疏线性回归(Lasso)vs 普通线性回归 权重对比', fontsize=14)
plt.legend(fontsize=10)
plt.grid(True, alpha=0.3, axis='y')
plt.show()

# 输出稀疏性统计
print(f"普通回归非零权重数量:{np.sum(np.abs(w_lr) > 1e-4)}")
print(f"Lasso回归非零权重数量:{np.sum(np.abs(w_lasso) > 1e-4)}")
运行效果

Lasso 回归的权重大部分为 0,只保留了前 5 个重要特征的非零权重,和真实权重高度一致;而普通线性回归的权重全部非零,引入了大量无关特征的噪声。

8.7 二元线性回归

核心概念

二元线性回归是「用线性模型解决二分类问题」(比如判断图像中的像素是前景还是背景),核心是把回归输出映射到 0/1 标签(比如用 sigmoid 函数)。

代码(二元回归分类)
复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LogisticRegression

# ==================== Mac字体配置 ====================
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.family'] = 'Arial Unicode MS'
plt.rcParams['axes.facecolor'] = 'white'

# ==================== 生成二元分类数据 ====================
np.random.seed(42)
# 类别0:均值(0,0),类别1:均值(2,2)
X0 = np.random.normal(0, 1, (50, 2))
X1 = np.random.normal(2, 1, (50, 2))
X = np.vstack([X0, X1])
y = np.hstack([np.zeros(50), np.ones(50)])

# ==================== 二元线性回归(逻辑回归) ====================
lr = LogisticRegression(random_state=42)
lr.fit(X, y)

# 生成网格用于绘制决策边界
x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max, 100), np.linspace(x2_min, x2_max, 100))
Z = lr.predict_proba(np.c_[xx1.ravel(), xx2.ravel()])[:, 1]
Z = Z.reshape(xx1.shape)

# ==================== 可视化 ====================
plt.figure(figsize=(10, 8))
# 绘制决策边界(概率=0.5的等高线)
contour = plt.contourf(xx1, xx2, Z, alpha=0.3, cmap='coolwarm')
plt.contour(xx1, xx2, Z, levels=[0.5], colors='black', linewidths=2)
# 绘制样本点
plt.scatter(X0[:, 0], X0[:, 1], label='类别0', color='blue', alpha=0.7)
plt.scatter(X1[:, 0], X1[:, 1], label='类别1', color='red', alpha=0.7)

plt.xlabel('特征1', fontsize=12)
plt.ylabel('特征2', fontsize=12)
plt.title('二元线性回归(逻辑回归)决策边界', fontsize=14)
plt.legend(fontsize=10)
plt.colorbar(contour, label='类别1的概率')
plt.grid(True, alpha=0.3)
plt.show()
运行效果

黑色直线是决策边界(概率 = 0.5),红色区域是类别 1 的高概率区,蓝色区域是类别 0 的高概率区,直观展示了二元线性回归的分类效果。

8.8 相关向量回归

核心概念

相关向量回归(RVR)是「稀疏版的高斯过程回归」,它能自动选择少量「相关向量」(关键样本)来拟合数据,既保留了 GPR 的精准性,又大幅降低计算成本,适合大规模数据的回归任务。

8.9 多变量数据回归

核心概念

多变量回归就是「输入特征不止一个」的回归(比如用图像的 RGB 三个通道预测物体的深度),核心和单变量回归一致,只是权重 w 变成了向量,模型变成 y=w1​x1​+w2​x2​+...+wn​xn​+b。

代码(多变量回归:预测波士顿房价)
复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_california_housing
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

# ==================== Mac字体配置 ====================
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.family'] = 'Arial Unicode MS'
plt.rcParams['axes.facecolor'] = 'white'

# ==================== 加载多变量数据集(加州房价) ====================
data = fetch_california_housing()
X = data.data  # 8个特征:平均收入、房屋年龄、平均房间数等
y = data.target  # 房价(单位:10万美元)

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

# ==================== 多变量线性回归 ====================
lr = LinearRegression()
lr.fit(X_train, y_train)
y_pred = lr.predict(X_test)

# ==================== 可视化预测效果 ====================
plt.figure(figsize=(10, 6))
# 绘制真实值vs预测值
plt.scatter(y_test, y_pred, alpha=0.5, color='royalblue')
# 绘制完美预测线(y=x)
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--', linewidth=2)

plt.xlabel('真实房价(10万美元)', fontsize=12)
plt.ylabel('预测房价(10万美元)', fontsize=12)
plt.title('多变量线性回归:加州房价预测效果', fontsize=14)
plt.grid(True, alpha=0.3)
plt.show()

# 输出结果
print(f"测试集均方误差:{mean_squared_error(y_test, y_pred):.4f}")
print(f"各特征权重:{lr.coef_}")
print(f"偏置项:{lr.intercept_:.4f}")
运行效果

散点越靠近红色虚线,说明预测越准确,直观展示了多变量回归在真实场景中的应用效果。

8.10 应用

8.10.1 人体姿势估计

人体姿势估计是回归模型在计算机视觉中的经典应用:把图像中的关节点(比如手肘、膝盖)的坐标作为回归目标,用图像特征(比如关键点周围的像素)预测关节点的 (x,y) 坐标。

8.10.2 位移专家

位移专家(Displacement Expert)是目标跟踪中的核心技术:用回归模型预测目标在相邻帧中的位移(dx, dy),从而实现目标的持续跟踪。

简化示例代码(模拟位移预测)
python 复制代码
import numpy as np
import matplotlib.pyplot as plt
# 新增:导入需要的sklearn模块
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error

# ==================== Mac字体配置 ====================
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.family'] = 'Arial Unicode MS'
plt.rcParams['axes.facecolor'] = 'white'

# ==================== 模拟目标位移数据 ====================
np.random.seed(42)
# 输入特征:前一帧目标的位置、大小、纹理特征(简化为3个特征)
X = np.random.normal(0, 1, (200, 3))
# 真实位移:dx = 0.5*X0 + 0.2*X1 - 0.1*X2 + 噪声
#          dy = 0.3*X0 - 0.4*X1 + 0.2*X2 + 噪声
dx_true = 0.5 * X[:,0] + 0.2 * X[:,1] - 0.1 * X[:,2]
dy_true = 0.3 * X[:,0] - 0.4 * X[:,1] + 0.2 * X[:,2]
dx = dx_true + np.random.normal(0, 0.1, size=200)
dy = dy_true + np.random.normal(0, 0.1, size=200)

# ==================== 回归预测位移 ====================
# 预测dx
lr_dx = LinearRegression()
lr_dx.fit(X, dx)
dx_pred = lr_dx.predict(X)

# 预测dy
lr_dy = LinearRegression()
lr_dy.fit(X, dy)
dy_pred = lr_dy.predict(X)

# ==================== 可视化位移预测效果 ====================
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))

# 左图:dx预测
ax1.scatter(dx, dx_pred, alpha=0.5, color='royalblue')
ax1.plot([dx.min(), dx.max()], [dx.min(), dx.max()], 'r--', linewidth=2)
ax1.set_xlabel('真实dx', fontsize=12)
ax1.set_ylabel('预测dx', fontsize=12)
ax1.set_title('位移预测:dx', fontsize=14)
ax1.grid(True, alpha=0.3)

# 右图:dy预测
ax2.scatter(dy, dy_pred, alpha=0.5, color='lightcoral')
ax2.plot([dy.min(), dy.max()], [dy.min(), dy.max()], 'r--', linewidth=2)
ax2.set_xlabel('真实dy', fontsize=12)
ax2.set_ylabel('预测dy', fontsize=12)
ax2.set_title('位移预测:dy', fontsize=14)
ax2.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

# 输出预测误差
print(f"dx预测均方误差:{mean_squared_error(dx, dx_pred):.4f}")
print(f"dy预测均方误差:{mean_squared_error(dy, dy_pred):.4f}")
运行效果

两张子图分别展示 dx 和 dy 的预测效果,散点越靠近红色虚线,说明位移预测越准确,模拟了「位移专家」的核心逻辑。

讨论

1.回归模型的选择:小样本、需要不确定性估计选 GPR;大规模数据选稀疏回归 / RVR;简单线性关系选普通线性回归;

2.核技巧的 Trade-off:高斯核拟合能力强,但容易过拟合;线性核简单稳定,但只能处理线性关系;

3.计算机视觉中的回归注意事项:输入特征需要归一化,异常值要预处理,避免维度灾难。

备注

1.所有代码均基于 Python 3.8+,依赖库:numpy、matplotlib、scikit-learn;

2.安装依赖:pip install numpy matplotlib scikit-learn

3.Mac 系统若仍有中文显示问题,可检查是否安装了 Arial Unicode MS 字体(Mac 原生自带)。

习题

1.修改线性回归代码,加入 L2 正则化(Ridge 回归),对比普通线性回归和 Ridge 回归在有异常值时的拟合效果;

2.尝试用不同的核函数(多项式核、sigmoid 核)替换高斯核,对比非线性回归效果;

3.基于加州房价数据集,用 Lasso 回归筛选重要特征,再用筛选后的特征做回归,对比模型性能。

总结

1.核心逻辑 :回归模型的本质是「拟合输入特征和输出标签的映射关系」,线性回归是基础,非线性回归 / 核技巧 / GPR 是对线性回归的扩展,解决非线性问题;

2.关键差异:普通回归只给单一预测值,贝叶斯回归 / GPR 能给出不确定性(置信区间),稀疏回归能筛选重要特征;

3.工程应用 :计算机视觉中,回归模型常用于关键点检测、目标跟踪、房价预测等场景,选择模型时需平衡拟合能力和计算成本。

希望这篇文章能帮你吃透回归模型!所有代码都能直接运行,建议动手改改参数(比如正则化强度、核函数参数),直观感受不同参数对结果的影响~

相关推荐
小鸡吃米…1 小时前
TensorFlow 优化器
人工智能·python·tensorflow
凌云拓界1 小时前
TypeWell全攻略(四):AI键位分析,让数据开口说话
前端·人工智能·后端·python·ai·交互
heimeiyingwang1 小时前
企业 AI 预算规划:如何分配资源实现最大 ROI
大数据·人工智能
咚咚王者2 小时前
人工智能之视觉领域 计算机视觉 第十四章 人脸检测
人工智能·计算机视觉
码界筑梦坊2 小时前
220-基于Python的诺贝尔奖数据可视化分析系统
开发语言·python·信息可视化·数据分析·毕业设计·fastapi
风轻扬7772 小时前
SqlAlchemy异步IO
python·异步io
土拨鼠烧电路2 小时前
笔记06:市场部的战争:流量、心智与增长黑客
大数据·人工智能·笔记
知识分享小能手2 小时前
SQL Server 2019入门学习教程,从入门到精通,SQL Server 2019 开发企业人事管理系统 — 语法知识点及使用方法详解(21)
sql·学习·sqlserver
狙击主力投资工具2 小时前
2026年中信里昂证券风水指数
人工智能