机器学习中的线性回归——培训课件
课程导入:从天气温度预测说起
想象这样一个场景:你是一名气象数据分析师,手里有一组历史数据——每天的温度和对应的冰淇淋销量。你想知道:温度越高,冰淇淋是不是卖得越多? 更进一步,如果明天预报温度是30°C,你能预估大概能卖出多少支冰淇淋吗?
这个问题,就可以用线性回归来解决。
线性回归要做的,就是找到一条“最好的直线”,用它来描述输入(温度) 和输出(销量) 之间的关系。有了这条直线,输入一个温度,就能预测出对应的销量。
一句话定义线性回归:利用回归方程(函数),对一个或多个自变量(特征)和因变量(目标)之间的关系进行建模的一种分析方法。
两个核心概念:
- 一元线性回归:只有一个自变量,比如只用“温度”预测“销量”。
- 多元线性回归:有多个自变量,比如用“温度”、“湿度”、“是否是节假日”等多个因素预测“销量”。
第一部分:数学知识复习
在深入线性回归之前,我们先快速复习几个必备的数学知识点。
1.1 指数函数、对数函数与求导
指数函数:形如 y=axy = a^xy=ax(a>0,a≠1a>0, a \neq 1a>0,a=1)的函数。
- 当 a=ea = ea=e(e≈2.718e \approx 2.718e≈2.718)时,就是自然指数函数 y=exy = e^xy=ex。
对数函数:指数函数的反函数,形如 y=logaxy = \log_a xy=logax。
- 当 a=ea = ea=e 时,称为自然对数 y=lnxy = \ln xy=lnx。
为什么机器学习需要这些? 在训练模型时,我们经常需要计算损失函数的最小值,而求导是找到最小值的核心工具。
最常用的求导公式(务必记住):
| 函数 | 导数 |
|---|---|
| y=xny = x^ny=xn | y′=n⋅xn−1y' = n \cdot x^{n-1}y′=n⋅xn−1 |
| y=axy = a^xy=ax | y′=ax⋅lnay' = a^x \cdot \ln ay′=ax⋅lna |
| y=exy = e^xy=ex | y′=exy' = e^xy′=ex |
| y=logaxy = \log_a xy=logax | y′=1x⋅lnay' = \frac{1}{x \cdot \ln a}y′=x⋅lna1 |
| y=lnxy = \ln xy=lnx | y′=1xy' = \frac{1}{x}y′=x1 |
链式法则:如果 y=f(u)y = f(u)y=f(u),u=g(x)u = g(x)u=g(x),则 dydx=dydu⋅dudx\frac{dy}{dx} = \frac{dy}{du} \cdot \frac{du}{dx}dxdy=dudy⋅dxdu。
1.2 矩阵基础
线性回归处理多元问题时,用矩阵表示会非常简洁高效。
向量:一维数组。例如 θ=(θ0θ1θ2)\theta = \begin{pmatrix} \theta_0 \\ \theta_1 \\ \theta_2 \end{pmatrix}θ=θ0θ1θ2
矩阵:二维数组。例如 X=(1x11x121x21x221x31x32)X = \begin{pmatrix} 1 & x_{11} & x_{12} \\ 1 & x_{21} & x_{22} \\ 1 & x_{31} & x_{32} \end{pmatrix}X=111x11x21x31x12x22x32
矩阵乘法:X⋅θX \cdot \thetaX⋅θ,要求 XXX 的列数等于 θ\thetaθ 的行数。
矩阵转置:XTX^TXT,行变列、列变行。
矩阵求逆:X−1X^{-1}X−1,只有方阵且行列式不为0时才可逆。
为什么需要矩阵? 多元线性回归中,如果有 mmm 个样本、nnn 个特征,用矩阵可以把所有计算统一成一个公式,极大简化表达。
第二部分:线性回归的核心概念
2.1 线性回归的数学公式
一元线性回归:
y=w⋅x+by = w \cdot x + by=w⋅x+b
其中 www 是斜率(权重),bbb 是截距(偏置)。
多元线性回归:
y=w1x1+w2x2+⋯+wnxn+by = w_1x_1 + w_2x_2 + \cdots + w_nx_n + by=w1x1+w2x2+⋯+wnxn+b
用矩阵表示为:
Y=X⋅WY = X \cdot WY=X⋅W
其中 XXX 是 m×nm \times nm×n 的矩阵(mmm 个样本,nnn 个特征),WWW 是 n×1n \times 1n×1 的权重向量。
2.2 损失函数(Loss Function)
问题来了:怎么判断一条直线“好不好”?
答案:用损失函数来衡量预测值与真实值之间的差距。差距越小,模型越好。
均方误差(MSE, Mean Squared Error) 是最常用的损失函数:
J(w,b)=12m∑i=1m(ypred(i)−ytrue(i))2J(w,b) = \frac{1}{2m} \sum_{i=1}^{m} (y_{pred}^{(i)} - y_{true}^{(i)})^2J(w,b)=2m1i=1∑m(ypred(i)−ytrue(i))2
其中 mmm 是样本数量,ypred(i)y_{pred}^{(i)}ypred(i) 是第 iii 个样本的预测值,ytrue(i)y_{true}^{(i)}ytrue(i) 是真实值。
为什么用平方? 因为我们要让正负误差不互相抵消,同时放大较大误差的惩罚——这就是最小二乘法的思想:最小化误差的平方和。
2.3 求解方法一:正规方程(Normal Equation)
正规方程是一种一步到位求解最优参数的方法。
公式:
W=(XTX)−1XTYW = (X^T X)^{-1} X^T YW=(XTX)−1XTY
推导思路:对损失函数求导,令导数等于0,直接解出 WWW。
优点:
- 不需要选择学习率
- 不需要迭代,一次计算完成
缺点:
- 当特征数量很大时(n>10000n > 10000n>10000),计算 (XTX)−1(X^T X)^{-1}(XTX)−1 非常慢
- 要求 XTXX^T XXTX 可逆(即矩阵满秩)
2.4 求解方法二:梯度下降法(Gradient Descent)
梯度下降是一种迭代式的优化方法。
核心思想:从某个随机的 WWW 开始,每次沿着梯度下降最快的方向走一小步,直到走到最低点。
更新公式:
W=W−α⋅∂J∂WW = W - \alpha \cdot \frac{\partial J}{\partial W}W=W−α⋅∂W∂J
其中 α\alphaα 是学习率(步长)。
学习率的选择:
- 太大:可能跳过最优点,无法收敛
- 太小:收敛太慢,耗费大量时间
梯度下降的四种变体
(1)全梯度下降(FG / Batch Gradient Descent)
每次更新参数时,使用所有样本计算梯度。
W=W−α⋅1m∑i=1m(ypred(i)−ytrue(i))⋅x(i)W = W - \alpha \cdot \frac{1}{m} \sum_{i=1}^{m} (y_{pred}^{(i)} - y_{true}^{(i)}) \cdot x^{(i)}W=W−α⋅m1i=1∑m(ypred(i)−ytrue(i))⋅x(i)
- 优点:收敛稳定,梯度方向准确
- 缺点:数据量大时计算极慢,无法处理超出内存的数据集
(2)随机梯度下降(SG / Stochastic Gradient Descent)
每次更新参数时,只使用1个随机样本计算梯度。
W=W−α⋅(ypred(i)−ytrue(i))⋅x(i)W = W - \alpha \cdot (y_{pred}^{(i)} - y_{true}^{(i)}) \cdot x^{(i)}W=W−α⋅(ypred(i)−ytrue(i))⋅x(i)
- 优点:计算快,能处理大数据,容易跳出局部最优
- 缺点:梯度方向波动大,收敛不稳定
(3)小批量梯度下降(Mini-batch Gradient Descent)
全梯度和随机梯度的折中方案:每次使用一个小批量样本(如32、64、128个)。
- 优点:兼顾了计算效率和收敛稳定性
- 实践中最常用的方法
- batch_size=1batch\_size = 1batch_size=1 时退化为随机梯度,batch_size=mbatch\_size = mbatch_size=m 时退化为全梯度
(4)随机平均梯度下降(SAG / Stochastic Average Gradient Descent)
为每个样本维护一个“旧梯度”,每次随机选一个样本更新它的梯度,其他样本的梯度保持不变,然后取所有梯度的平均值来更新参数。
- 优点:计算成本等同于随机梯度,但收敛速度更快
- 缺点:需要额外内存存储每个样本的梯度
四种方法对比总结:
| 方法 | 每次用多少样本 | 速度 | 稳定性 | 适用场景 |
|---|---|---|---|---|
| 全梯度 | 全部 | 慢 | 最稳定 | 小数据集 |
| 随机梯度 | 1个 | 最快 | 不稳定 | 大数据、在线学习 |
| 小批量 | 一批(如32) | 较快 | 较稳定 | 最常用 |
| 随机平均梯度 | 1个(但用历史平均) | 快 | 较稳定 | 大数据、追求收敛速度 |
2.5 正则化(Regularization)
问题:如果模型太复杂(特征太多),可能会过拟合——在训练集上表现很好,但在新数据上表现很差。
解决方案:在损失函数中添加惩罚项,限制参数的大小。
岭回归(Ridge Regression / L2正则化)
在损失函数中加入权重的平方和作为惩罚项:
J(θ)=12m∑i=1m(h(x(i))−y(i))2+λ∑j=1nθj2J(\theta) = \frac{1}{2m} \sum_{i=1}^{m} (h(x^{(i)}) - y^{(i)})^2 + \lambda \sum_{j=1}^{n} \theta_j^2J(θ)=2m1i=1∑m(h(x(i))−y(i))2+λj=1∑nθj2
- 特点:让所有参数都变小,但不会变成0
- 适用:特征较多但都可能有贡献的场景
Lasso回归(Lasso Regression / L1正则化)
在损失函数中加入权重的绝对值之和作为惩罚项:
J(θ)=12m∑i=1m(h(x(i))−y(i))2+λ∑j=1n∣θj∣J(\theta) = \frac{1}{2m} \sum_{i=1}^{m} (h(x^{(i)}) - y^{(i)})^2 + \lambda \sum_{j=1}^{n} |\theta_j|J(θ)=2m1i=1∑m(h(x(i))−y(i))2+λj=1∑n∣θj∣
- 特点:可以让某些参数变为0,实现特征选择
- 适用:特征很多,怀疑只有少数特征真正有用
λ\lambdaλ 的作用:λ\lambdaλ 越大,惩罚越重,模型越简单(欠拟合风险);λ\lambdaλ 越小,惩罚越轻,模型越复杂(过拟合风险)。
第三部分:案例实战——手工演算
案例:温度与冰淇淋销量
数据:
| 温度 (°C) | 销量 (支) |
|---|---|
| 20 | 50 |
| 25 | 60 |
| 30 | 70 |
| 35 | 80 |
问:当温度为28°C时,预计销量是多少?
步骤一:建立模型
假设 y=wx+by = wx + by=wx+b,其中 xxx 是温度,yyy 是销量。
步骤二:计算均方误差损失函数
J(w,b)=12×4∑i=14(wxi+b−yi)2J(w,b) = \frac{1}{2 \times 4} \sum_{i=1}^{4} (wx_i + b - y_i)^2J(w,b)=2×41i=1∑4(wxi+b−yi)2
步骤三:用最小二乘法求解
对于一元线性回归,可以用公式直接计算:
xˉ=20+25+30+354=27.5\bar{x} = \frac{20+25+30+35}{4} = 27.5xˉ=420+25+30+35=27.5
yˉ=50+60+70+804=65\bar{y} = \frac{50+60+70+80}{4} = 65yˉ=450+60+70+80=65
w=∑i=14(xi−xˉ)(yi−yˉ)∑i=14(xi−xˉ)2w = \frac{\sum_{i=1}^{4} (x_i - \bar{x})(y_i - \bar{y})}{\sum_{i=1}^{4} (x_i - \bar{x})^2}w=∑i=14(xi−xˉ)2∑i=14(xi−xˉ)(yi−yˉ)
w=(−7.5)(−15)+(−2.5)(−5)+(2.5)(5)+(7.5)(15)(−7.5)2+(−2.5)2+(2.5)2+(7.5)2w = \frac{(-7.5)(-15) + (-2.5)(-5) + (2.5)(5) + (7.5)(15)}{(-7.5)^2 + (-2.5)^2 + (2.5)^2 + (7.5)^2}w=(−7.5)2+(−2.5)2+(2.5)2+(7.5)2(−7.5)(−15)+(−2.5)(−5)+(2.5)(5)+(7.5)(15)
w=112.5+12.5+12.5+112.556.25+6.25+6.25+56.25=250125=2w = \frac{112.5 + 12.5 + 12.5 + 112.5}{56.25 + 6.25 + 6.25 + 56.25} = \frac{250}{125} = 2w=56.25+6.25+6.25+56.25112.5+12.5+12.5+112.5=125250=2
b=yˉ−w⋅xˉ=65−2×27.5=10b = \bar{y} - w \cdot \bar{x} = 65 - 2 \times 27.5 = 10b=yˉ−w⋅xˉ=65−2×27.5=10
得到模型:y=2x+10y = 2x + 10y=2x+10
步骤四:预测
当 x=28x = 28x=28 时:
y=2×28+10=66y = 2 \times 28 + 10 = 66y=2×28+10=66
结论:温度28°C时,预计销量为66支冰淇淋。
第四部分:Python代码实现
4.1 从零实现(手动计算验证)
import numpy as np
import matplotlib.pyplot as plt
# ============ 1. 准备数据 ============
# 温度数据(特征)
X = np.array([20, 25, 30, 35])
# 销量数据(目标)
y = np.array([50, 60, 70, 80])
# ============ 2. 计算模型参数(最小二乘法) ============
# 计算均值
x_mean = np.mean(X) # 27.5
y_mean = np.mean(y) # 65.0
# 计算分子:Σ(xi - x̄)(yi - ȳ)
numerator = np.sum((X - x_mean) * (y - y_mean))
# 计算分母:Σ(xi - x̄)²
denominator = np.sum((X - x_mean) ** 2)
# 计算斜率 w 和截距 b
w = numerator / denominator # 2.0
b = y_mean - w * x_mean # 10.0
print(f"模型:y = {w:.2f}x + {b:.2f}")
# ============ 3. 预测 ============
x_new = 28
y_pred = w * x_new + b
print(f"温度 {x_new}°C 时,预测销量:{y_pred:.0f} 支")
# ============ 4. 可视化 ============
plt.scatter(X, y, color='red', label='实际数据') # 绘制数据点
x_line = np.linspace(15, 40, 100)
y_line = w * x_line + b
plt.plot(x_line, y_line, color='blue', label='回归直线') # 绘制拟合直线
plt.xlabel('温度 (°C)')
plt.ylabel('销量 (支)')
plt.legend()
plt.title('温度与冰淇淋销量线性回归')
plt.show()
4.2 使用sklearn实现(生产级代码)
import numpy as np
import joblib # 用于模型的保存和加载
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
# ============ 1. 准备数据 ============
# 注意:sklearn要求X是二维数组(样本数, 特征数)
X = np.array([20, 25, 30, 35]).reshape(-1, 1) # 4行1列
y = np.array([50, 60, 70, 80])
# ============ 2. 创建并训练模型 ============
model = LinearRegression()
model.fit(X, y) # 用fit方法训练
# 查看参数
print(f"斜率 w = {model.coef_[0]:.2f}") # 2.0
print(f"截距 b = {model.intercept_:.2f}") # 10.0
# ============ 3. 预测 ============
x_new = np.array([[28]]) # 注意:也是二维
y_pred = model.predict(x_new)
print(f"温度 28°C 时,预测销量:{y_pred[0]:.0f} 支")
# ============ 4. 模型评估 ============
y_train_pred = model.predict(X)
mse = mean_squared_error(y, y_train_pred) # 均方误差
r2 = r2_score(y, y_train_pred) # R²决定系数
print(f"均方误差 MSE = {mse:.2f}")
print(f"R² = {r2:.4f}") # 越接近1越好
# ============ 5. 模型的保存与加载 ============
# 保存模型到文件
joblib.dump(model, 'icecream_model.pkl')
print("模型已保存为 icecream_model.pkl")
# 加载模型
loaded_model = joblib.load('icecream_model.pkl')
# 用加载的模型预测
y_pred_loaded = loaded_model.predict([[28]])
print(f"加载模型预测:{y_pred_loaded[0]:.0f} 支")
4.3 代码执行流程图解
┌─────────────────┐
│ 1. 准备数据 │ X = [20,25,30,35], y = [50,60,70,80]
└────────┬────────┘
▼
┌─────────────────┐
│ 2. 创建模型 │ model = LinearRegression()
└────────┬────────┘
▼
┌─────────────────┐
│ 3. 训练模型 │ model.fit(X, y) → 找到最优的w和b
└────────┬────────┘
▼
┌─────────────────┐
│ 4. 模型预测 │ model.predict([[28]]) → 返回66
└────────┬────────┘
▼
┌─────────────────┐
│ 5. 模型评估 │ 计算MSE、R²等指标
└────────┬────────┘
▼
┌─────────────────┐
│ 6. 保存/加载 │ joblib.dump() / joblib.load()
└─────────────────┘
第五部分:常见生产应用场景
线性回归在实际生产中应用非常广泛:
- 房价预测:根据面积、房间数、地段等预测房价
- 销售额预测:根据广告投入、季节等因素预测销量
- 金融风控:根据收入、负债等预测贷款额度
- 医学领域:根据年龄、体重等预测血压或血糖
- 电力负荷预测:根据温度、湿度等预测用电量
- 交通流量预测:根据时间、天气等预测车流量
第六部分:优缺点
优点
- 简单直观:模型易于理解和解释,结果一目了然
- 计算高效:训练和预测速度快,尤其适合大规模数据
- 可解释性强:每个特征的权重直接反映了该特征对结果的影响程度
- 不需要大量调参:相比神经网络等复杂模型,超参数很少
缺点
- 对非线性关系处理差:只能捕捉线性关系,真实世界往往是非线性的
- 对异常值敏感:一个极端值可能严重影响拟合结果
- 假设数据独立:如果特征之间高度相关(多重共线性),模型不稳定
- 容易过拟合:特征太多时容易过拟合(可通过正则化缓解)
- 对输入数据的尺度敏感:特征尺度差异大时,梯度下降收敛慢(需要归一化)
第七部分:常见面试题
Q1:什么是线性回归?它的假设是什么?
答:线性回归是一种用线性方程描述自变量和因变量关系的监督学习算法。基本假设包括:①自变量和因变量存在线性关系;②误差项独立同分布;③误差项服从正态分布;④特征之间不存在完全的多重共线性。
Q2:最小二乘法和梯度下降法有什么区别?
答:
- 最小二乘法(正规方程) :直接求导令导数为0,一步得到最优解。适合特征数较少(<10000)的场景。
- 梯度下降法:通过迭代逐步逼近最优解。适合特征数多、数据量大的场景。
Q3:什么是过拟合?如何防止线性回归过拟合?
答:过拟合是指模型在训练集上表现很好,但在新数据上表现差。防止方法:
- 正则化:L1正则化(Lasso)、L2正则化(Ridge)
- 减少特征数量:通过特征选择
- 增加训练数据
- 交叉验证
Q4:L1正则化和L2正则化有什么区别?
答:
- L2(岭回归) :惩罚项是权重的平方和,让所有权重都变小但不为0,适合特征都可能有贡献的场景
- L1(Lasso回归) :惩罚项是权重的绝对值之和,可以让某些权重变为0,实现特征选择
Q5:如何评估线性回归模型的好坏?
答:
- 均方误差(MSE) :越小越好
- R²决定系数:取值范围[0,1],越接近1说明拟合越好
- 均方根误差(RMSE) :MSE开平方,与目标值同量纲
Q6:线性回归和逻辑回归的区别?
答:线性回归用于回归问题(预测连续值),逻辑回归用于分类问题(预测离散类别)。线性回归的损失函数是均方误差,逻辑回归的损失函数是对数损失(交叉熵)。
第八部分:总结
今天我们系统地学习了线性回归的完整知识体系:
| 模块 | 核心内容 |
|---|---|
| 数学基础 | 指数/对数/求导、矩阵运算 |
| 核心概念 | 线性模型、损失函数(MSE)、最小二乘法 |
| 求解方法 | 正规方程(一步到位)、梯度下降(四种变体) |
| 正则化 | 岭回归(L2)、Lasso回归(L1) |
| 工程实践 | sklearn实现、模型保存与加载(joblib) |
一句话记住线性回归:找到一条“最好”的直线(或超平面),让所有数据点到它的垂直距离的平方和最小——这就是线性回归的全部秘密。
第九部分:课后作业
作业1:手工计算(必做)
给定数据:x=[1,2,3,4,5]x = [1, 2, 3, 4, 5]x=[1,2,3,4,5],y=[2.1,4.0,5.9,8.1,10.2]y = [2.1, 4.0, 5.9, 8.1, 10.2]y=[2.1,4.0,5.9,8.1,10.2]
- 用最小二乘法手工计算 www 和 bbb
- 写出回归方程
- 预测 x=6x=6x=6 时的 yyy 值
作业2:代码实践(必做)
使用Python和sklearn完成以下任务:
- 用
make_regression生成100个样本、2个特征的回归数据集 - 划分训练集和测试集(8:2)
- 训练线性回归模型
- 计算并输出:MSE、RMSE、R²
- 保存模型为
model.pkl,再加载并用测试集预测
作业3:思考题(选做)
- 如果数据中存在明显的异常值(如 yyy 突然变成100),对线性回归的结果会有什么影响?为什么?
- 当特征数量远大于样本数量时(如 n=1000,m=50n=1000, m=50n=1000,m=50),正规方程还能用吗?应该用什么方法?
- 查阅资料,了解什么是多项式回归,它和线性回归是什么关系?

被折叠的 条评论
为什么被折叠?



