第29课 - 线性回归原理与实现
学习目标
通过本课学习,你将能够:
- 理解线性回归模型的核心思想与数学原理
- 使用Python和Scikit-learn库实现线性回归
- 评估线性回归模型的性能
- 应用线性回归解决实际问题
核心概念
什么是线性回归?
想象一下,你正在观察一个身高和体重的数据集。你发现,身高较高的人通常体重也较重,两者之间似乎存在一种线性关系。线性回归的目标,就是找到一条最佳拟合直线,来描述这种关系。
数学上,这条直线可以表示为: $$ y = wx + b $$ 其中:
- $x$ 是自变量(如身高)
- $y$ 是因变量(如体重)
- $w$ 是斜率(权重),表示 $x$ 每增加1个单位,$y$ 的平均变化量
- $b$ 是截距(偏置),表示当 $x=0$ 时 $y$ 的预测值
如何找到“最佳”直线?
我们使用损失函数来衡量直线的“好坏”。最常用的是均方误差: $$ MSE = \frac{1}{n}\sum_{i=1}^{n}(y_i - \hat{y}_i)^2 $$ 其中 $\hat{y}_i$ 是我们的预测值。
线性回归的目标就是找到参数 $w$ 和 $b$,使得这个MSE最小化。这个过程称为最小二乘法。
直观理解
想象你在打靶:
- 每个数据点是靶子上的弹孔
- 我们的拟合直线是瞄准的中心
- MSE衡量了所有弹孔到中心点的平均距离平方
- 我们调整瞄准点(直线),使得这个平均距离最小
代码示例
下面是一个完整的线性回归实现示例:
# 导入必要的库
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
# 1. 生成示例数据
np.random.seed(42) # 设置随机种子,保证结果可复现
# 生成100个数据点,X是特征,y是目标值
# 真实关系是:y = 2.5*X + 5 + 噪声
X = 2 * np.random.rand(100, 1) # 100个样本,1个特征
y = 5 + 2.5 * X + np.random.randn(100, 1) # 添加随机噪声
# 2. 数据划分
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# 3. 创建并训练模型
model = LinearRegression()
model.fit(X_train, y_train)
# 4. 模型参数
print("模型训练结果:")
print(f"斜率 (w): {model.coef_[0][0]:.4f}")
print(f"截距 (b): {model.intercept_[0]:.4f}")
print(f"真实关系: y = 2.5*X + 5")
print(f"模型学到: y = {model.coef_[0][0]:.4f}*X + {model.intercept_[0]:.4f}")
# 5. 模型评估
y_pred = model.predict(X_test)
# 计算评估指标
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print("\n模型评估指标:")
print(f"均方误差 (MSE): {mse:.4f}")
print(f"R² 分数: {r2:.4f}")
print(f"解释: R²越接近1,模型拟合效果越好")
# 6. 可视化结果
plt.figure(figsize=(10, 6))
# 绘制训练数据和测试数据
plt.scatter(X_train, y_train, color='blue', alpha=0.5, label='训练数据')
plt.scatter(X_test, y_test, color='red', alpha=0.7, label='测试数据')
# 绘制拟合直线
X_line = np.linspace(0, 2, 100).reshape(-1, 1)
y_line = model.predict(X_line)
plt.plot(X_line, y_line, color='green', linewidth=2, label='拟合直线')
# 真实关系线
y_true = 5 + 2.5 * X_line
plt.plot(X_line, y_true, color='orange', linewidth=2,
linestyle='--', label='真实关系')
plt.xlabel('X')
plt.ylabel('y')
plt.title('线性回归结果可视化')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
输出示例:
模型训练结果:
斜率 (w): 2.4489
截距 (b): 5.1105
真实关系: y = 2.5*X + 5
模型学到: y = 2.4489*X + 5.1105
模型评估指标:
均方误差 (MSE): 0.8574
R² 分数: 0.9231
解释: R²越接近1,模型拟合效果越好
实践练习
练习1:基础实现
要求:
- 创建一个新数据集,关系为
y = 3*X + 2 - 使用线性回归拟合数据
- 打印学到的斜率和截距
预期输出:
学到的参数:
斜率: 约3.0
截距: 约2.0
练习2:模型评估
要求:
- 基于练习1的模型,计算并打印MSE和R²分数
- 判断模型拟合效果(R² > 0.9为好)
预期输出:
评估结果:
MSE: 接近0(因为数据无噪声)
R²: 接近1.0
拟合效果:非常好
练习3:实际应用
要求:
- 使用以下房价数据(面积vs房价):
# 面积(平方米) area = [50, 60, 70, 80, 90, 100, 110, 120] # 房价(万元) price = [200, 240, 280, 320, 360, 400, 440, 480] - 训练线性回归模型
- 预测面积为85平方米时的房价
- 绘制数据点和拟合直线
预期输出:
预测结果:
面积85平方米,预测房价:340万元
常见错误
1. 混淆相关性与因果性
- 错误:认为线性回归能证明因果关系
- 正确:线性回归只能发现相关性,不能证明因果
- 例子:冰淇淋销量与溺水人数相关,但并非因果
2. 忽视数据假设
线性回归有几个重要假设:
- 线性关系
- 误差项独立同分布
- 误差项方差恒定(同方差性)
- 误差项正态分布
检查方法:
# 残差分析
residuals = y_test - y_pred.flatten()
plt.scatter(y_pred, residuals)
plt.axhline(y=0, color='r', linestyle='--')
plt.xlabel('预测值')
plt.ylabel('残差')
plt.title('残差图检查')
plt.show()
# 残差应随机分布在0线附近
3. 忽略数据预处理
- 问题:特征量纲差异大,影响模型训练
- 解决:标准化或归一化数据
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
4. 过度依赖单一评估指标
- 错误:只看R²分数
- 正确:结合MSE、MAE等多个指标
from sklearn.metrics import mean_absolute_error
mae = mean_absolute_error(y_test, y_pred)
print(f"平均绝对误差: {mae:.4f}")
小结
本课我们学习了线性回归的核心知识:
关键要点回顾:
- 核心思想:找到最佳拟合直线来描述变量间的线性关系
- 数学原理:通过最小化均方误差(MSE)来优化参数
- 实现方法:使用Scikit-learn的
LinearRegression类 - 评估指标:
- MSE:衡量预测误差的大小
- R²:衡量模型解释数据变异的能力
- 重要假设:数据需要满足线性、独立性、同方差等假设
学习建议:
- 动手实践所有代码示例
- 尝试修改数据生成参数,观察模型变化
- 理解每个输出的含义,而不仅仅是运行代码
下一课预告:
下一课我们将学习多元线性回归,当数据有多个特征时如何建立模型。例如,房价不仅取决于面积,还可能与楼层、房龄等多个因素相关。多元线性回归将帮助我们处理这种更复杂的情况。
# 下一课预告代码预览
# 多元线性回归示例框架
# features = [面积, 楼层, 房龄]
# price = 200*面积 + 10*楼层 - 5*房龄 + 50
练习编辑器
rust
Loading...