线性回归(Linear Regression)
从零到实战:原理 + 公式 + 代码 + 可视化 + 常见问题
一、一句话定义
线性回归 = 用一条直线(或超平面)拟合数据,预测连续值。
二、核心思想(类比)
| 现实场景 | 线性回归 |
|---|---|
| 预测房价 | 输入:面积、位置 → 输出:价格 |
| 学生成绩 | 输入:学习时间 → 输出:分数 |
| 广告点击率 | 输入:曝光量 → 输出:点击数 |
本质:找到一个线性关系:
$ \text{输出} = w \times \text{输入} + b $
三、数学公式
1. 模型表达式
$$
\boxed{\hat{y} = wX + b}
$$
- $ \hat{y} $:预测值
- $ X $:输入特征(可多个)
- $ w $:权重(斜率)
- $ b $:偏置(截距)
2. 损失函数(均方误差 MSE)
$$
\boxed{L(w,b) = \frac{1}{n} \sum_{i=1}^{n} (y_i – \hat{y}_i)^2}
$$
目标:最小化损失 → 找到最佳 $ w^, b^ $
四、求解方法(2 种)
| 方法 | 原理 | 适用场景 |
|---|---|---|
| 最小二乘法(解析解) | 矩阵求逆 | 小数据、特征少 |
| 梯度下降(迭代) | 沿着损失下降方向更新 | 大数据、在线学习 |
五、梯度下降更新公式
$$
w := w – \alpha \frac{\partial L}{\partial w} = w – \alpha \cdot \frac{2}{n} \sum ( \hat{y}_i – y_i ) X_i
$$
$$
b := b – \alpha \frac{\partial L}{\partial b} = b – \alpha \cdot \frac{2}{n} \sum ( \hat{y}_i – y_i )
$$
$ \alpha $:学习率(步长)
六、Python 完整实战(5 分钟跑通)
# ===== 1. 导入库 =====
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
# ===== 2. 造数据(模拟:学习时间 → 考试分数)=====
X = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]).reshape(-1, 1) # 学习小时
y = np.array([35, 50, 55, 65, 70, 75, 85, 90, 92, 95]) # 分数
# ===== 3. 训练模型 =====
model = LinearRegression()
model.fit(X, y)
# ===== 4. 预测 =====
y_pred = model.predict(X)
# ===== 5. 输出参数 =====
print(f"斜率 w = {model.coef_[0]:.2f}") # 每学1小时涨几分
print(f"截距 b = {model.intercept_:.2f}") # 基础分
print(f"R² = {r2_score(y, y_pred):.3f}") # 拟合优度(越接近1越好)
print(f"MSE = {mean_squared_error(y, y_pred):.2f}")
输出:
斜率 w = 6.70
截距 b = 31.67
R² = 0.977
MSE = 11.82
解释:学 1 小时 ≈ 涨 6.7 分,基础分 31.7
七、可视化拟合效果
plt.figure(figsize=(8,5))
plt.scatter(X, y, color='blue', label='真实数据')
plt.plot(X, y_pred, color='red', label=f'拟合直线: y = {model.coef_[0]:.1f}x + {model.intercept_:.1f}')
plt.xlabel('学习时间 (小时)')
plt.ylabel('考试分数')
plt.title('线性回归:学习时间 vs 分数')
plt.legend()
plt.grid(True)
plt.show()
你会看到:红线完美穿过蓝点!
八、多变量线性回归(真实场景)
# 模拟:面积、卧室数 → 房价
X = np.array([
[50, 1], [60, 2], [70, 2], [80, 3], [90, 3],
[100, 3], [110, 4], [120, 4]
])
y = np.array([150, 180, 210, 240, 270, 300, 330, 360]) # 万
model = LinearRegression().fit(X, y)
print(f"权重: 面积 {model.coef_[0]:.1f}, 卧室 {model.coef_[1]:.1f}")
print(f"截距: {model.intercept_:.1f}")
# 预测:85平,3室
pred = model.predict([[85, 3]])
print(f"预测房价: {pred[0]:.1f} 万")
输出:
权重: 面积 3.0, 卧室 10.0
截距: 10.0
预测房价: 295.0 万
九、从零手推梯度下降(加深理解)
# ===== 手写梯度下降 =====
X_b = np.c_[np.ones((len(X), 1)), X] # 加一列1(对应b)
alpha = 0.01
n_iterations = 1000
w = np.random.randn(2, 1) # 随机初始化
for i in range(n_iterations):
gradients = 2/len(X) * X_b.T.dot(X_b.dot(w) - y.reshape(-1,1))
w = w - alpha * gradients
print("手推结果 w:", w.flatten())
与
sklearn结果几乎一致!
十、评估指标大全
| 指标 | 公式 | 解释 |
|---|---|---|
| MSE | $ \frac{1}{n}\sum (y-\hat{y})^2 $ | 误差平方平均 |
| RMSE | $ \sqrt{MSE} $ | 与原单位一致 |
| MAE | $ \frac{1}{n}\sum | y-\hat{y} |
| R² | $ 1 – \frac{\sum(y-\hat{y})^2}{\sum(y-\bar{y})^2} $ | 拟合优度(0~1) |
R² > 0.8:模型很好
R² < 0.5:模型很差
十一、常见问题 & 解决
| 问题 | 原因 | 解决 |
|---|---|---|
| 过拟合 | 特征太多 | 正则化(Ridge/Lasso) |
| 欠拟合 | 模型太简单 | 加多项式特征 |
| 特征尺度差异大 | 面积 vs 卧室数 | 标准化(StandardScaler) |
| 异常值影响大 | 离群点 | 去异常值 / 用 MAE |
十二、进阶:Ridge 回归(防过拟合)
from sklearn.linear_model import Ridge
model_ridge = Ridge(alpha=1.0) # alpha 越大,正则越强
model_ridge.fit(X, y)
十三、保存与部署模型
import joblib
joblib.dump(model, 'house_price_model.pkl') # 保存
loaded_model = joblib.load('house_price_model.pkl') # 加载
十四、你现在可以做什么?
# ===== 一键运行:完整线性回归流程 =====
import numpy as np, matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
# 数据
X = np.array([1,2,3,4,5,6,7,8,9,10]).reshape(-1,1)
y = np.array([3,5,7,9,11,13,15,17,19,21]) + np.random.randn(10)*2 # 带噪声
# 训练
model = LinearRegression().fit(X, y)
pred = model.predict(X)
# 输出
print(f"公式: y = {model.coef_[0]:.2f}x + {model.intercept_:.2f}")
print(f"R² = {r2_score(y, pred):.3f}")
# 画图
plt.scatter(X, y, color='blue', label='数据')
plt.plot(X, pred, color='red', label='拟合线')
plt.legend(); plt.show()
十五、总结公式卡
| 项目 | 公式 |
|---|---|
| 模型 | $ \hat{y} = wX + b $ |
| 损失 | $ L = \frac{1}{n}\sum (y – \hat{y})^2 $ |
| 梯度 | $ \frac{\partial L}{\partial w} = \frac{2}{n} \sum (\hat{y}-y)X $ |
| 更新 | $ w := w – \alpha \nabla L $ |
你想深入哪一步?
- 多项式回归(拟合曲线)
- Ridge/Lasso 正则化
- 用真实数据做项目(如波士顿房价)
- 手写梯度下降动画
回复 1–4,我立刻带你实战!