ML-线性回归(Linear Regression)

第一课:线性回归(Linear Regression)

核心思想一句话: 在所有点中间画一条"最中庸"的直线------不让任何一个点太委屈,也不特别讨好某个点。

python 复制代码
# ========== 1. 导入必要的库 ==========
import pandas as pd              # 数据处理
import numpy as np               # 数值计算
from sklearn.datasets import fetch_california_housing  # 加载数据集
from sklearn.model_selection import train_test_split   # 划分训练/测试集
from sklearn.linear_model import LinearRegression      # 线性回归模型
from sklearn.metrics import mean_squared_error, r2_score # 评估指标
import matplotlib.pyplot as plt  # 数据可视化
# 1. 加载数据
housing = fetch_california_housing()
#pd.DataFrame()	将 numpy 数组转换为 pandas 表格
X = pd.DataFrame(housing.data, columns=housing.feature_names)
y = housing.target  # 房价中位数(十万美金)

print("特征名称:", housing.feature_names)
print("\n数据集大小:", X.shape)
print("\n前3行数据:\n", X.head(3))

2.📐 核心概念:线性回归在算什么?

复制代码
房价 = w₀ + w₁×收入 + w₂×房龄 + w₃×卧室数 + ... + w₈×经度
        ↑              ↑                ↑
      截距(bias)    各特征的权重(weights)

模型目标:找到一组w,让预测值和真实房价的差距最小

这个"差距"叫损失函数(Loss),通常用均方误差MSE:

MSE = 平均( (真实房价 - 预测房价)² )

2.1📝 数学公式详解

MSE=1n∑i=1n(yi−y^i)2 \text{MSE} = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2 MSE=n1i=1∑n(yi−y^i)2

符号 含义 示例
nnn 样本数量 1000 套房子
yiy_iyi 第 iii 个真实值 实际房价 50万
y^i\hat{y}_iy^i 第 iii 个预测值 模型预测 55万
(yi−y^i)(y_i - \hat{y}_i)(yi−y^i) 残差/误差 -5万
∑\sum∑ 求和 所有样本误差平方相加
1n\frac{1}{n}n1 取平均 除以样本数

2.2🔄 相关变体

指标 公式 特点 适用场景
RMSE MSE\sqrt{\text{MSE}}MSE 开根号,单位与原始数据一致 更直观的误差度量
MAE 1n∑∣yi−y^i∣\frac{1}{n}\sum|y_i - \hat{y}_i|n1∑∣yi−y^i∣ 绝对值,不放大误差 异常值较多时更稳健
1−MSE方差1 - \frac{\text{MSE}}{\text{方差}}1−方差MSE 标准化到 0~1 衡量模型解释力

3.继续代码:训练与评估

变量 含义 类比
X_train 训练用特征(80%房子的8个属性) 学生的练习题
y_train 训练用答案(80%房子的真实房价) 练习题的标准答案
X_test 测试用特征(20%房子的8个属性) 期末考试卷
y_test 测试用答案(20%房子的真实房价) 考试卷的正确答案(考后才看)

原始数据 X, y

2 数据拆分 ──→ X_train, y_train (80%) 用于学习

└──→ X_test, y_test (20%) 用于考试

3 创建模型 → 训练(fit) → 预测(predict)

4 评估模型表现(R², RMSE)

5 解释模型(哪个特征最重要)

python 复制代码
# 2. 拆分数据:80%训练,20%测试
#random_state=42 = 随机数种子,让每次"抽签"结果相同,保证实验可重复
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)  # 训练:自动找最优的w₀, w₁, w₂...
y_pred = model.predict(X_test)  # 预测

# 4. 评估
print(f"R²得分: {r2_score(y_test, y_pred):.3f}")  # 解释度,1.0满分
print(f"RMSE: {np.sqrt(mean_squared_error(y_test, y_pred)):.3f}")  # 平均误差(十万美金)

# 5. 看模型学到了什么权重
importance = pd.DataFrame({
    '特征': housing.feature_names,
    '权重': model.coef_
}).sort_values('权重', key=abs, ascending=False)

print("\n特征权重(影响力):\n", importance)

4.从线性回归到多项式回归

核心思想: 如果直线不够弯,那就允许曲线!

把原始特征平方、立方,让模型能拟合弯曲的趋势:

复制代码
线性:    房价 = w₀ + w₁×收入
二次:    房价 = w₀ + w₁×收入 + w₂×收入²
三次:    房价 = w₀ + w₁×收入 + w₂×收入² + w₃×收入³

4.1曲线拟合非线性数据

python 复制代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import PolynomialFeatures #自动将低次特征转换成高次特征,让线性模型能拟合非线性关系
from sklearn.linear_model import LinearRegression
from sklearn.pipeline import Pipeline  #把多个处理步骤串联成"生产线",一键完成数据转换 → 模型训练 → 预测
from sklearn.metrics import r2_score

# 1. 生成模拟数据(非线性关系:y = x² + 噪声)
np.random.seed(42)
#np.linspace(-3, 3, 100).reshape(-1, 1)
#    └─────┬─────┘   └──┬──┘
#       生成数据      改变形状
#   .reshape(行数, 列数)
#   -1: 自动计算(根据总数推断)
#    1: 固定1列
X = np.linspace(-3, 3, 100).reshape(-1, 1)  # 特征:-3到3之间100个点
y = X.ravel()**2 + np.random.randn(100) * 0.5  # 真实关系:y = x² + 噪声

# 2. 普通线性回归(直线)
linear_model = LinearRegression()
linear_model.fit(X, y)
y_linear_pred = linear_model.predict(X)

# 3. 多项式回归(二次曲线)
# Pipeline = 先把X变成[X, X²],再线性回归
poly_model = Pipeline([
    ('poly', PolynomialFeatures(degree=2, include_bias=False)),  # 生成X²
    ('linear', LinearRegression())
])
poly_model.fit(X, y)
y_poly_pred = poly_model.predict(X)

# 4. 对比可视化
plt.figure(figsize=(10, 6))
plt.scatter(X, y, alpha=0.5, label='真实数据')
plt.plot(X, y_linear_pred, 'r-', label=f'线性回归 (R²={r2_score(y, y_linear_pred):.3f})')
plt.plot(X, y_poly_pred, 'g-', linewidth=2, label=f'二次多项式 (R²={r2_score(y, y_poly_pred):.3f})')
plt.xlabel('X')
plt.ylabel('y')
plt.title('线性 vs 多项式回归对比')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

print(f"线性回归R²: {r2_score(y, y_linear_pred):.3f}")
print(f"多项式回归R²: {r2_score(y, y_poly_pred):.3f}")
相关推荐
huohaiyu13 小时前
深入解析Java垃圾回收机制
java·开发语言·算法·gc
浮芷.13 小时前
鸿蒙PC端 TTS 并发调用问题详解:资源竞争与队列管理
算法·华为·开源·harmonyos·鸿蒙·鸿蒙系统
装不满的克莱因瓶13 小时前
掌握感知器的学习原理
人工智能·python·神经网络·算法·ai·卷积神经网络
Lsk_Smion13 小时前
力扣实训 _ [994].腐烂的橘子/图论
算法·leetcode·图论
轻微的风格艾丝凡14 小时前
两电平三相VSC整流模式从不控整流平滑切换至有源整流调试记录
算法·dsp·c2000
dongf201914 小时前
R语言KNN算法
算法·数据分析·r语言
小O的算法实验室14 小时前
2025年IEEE TASE,基于双层耦合平均场博弈的大规模智能体集成任务分配与轨迹规划
人工智能·算法·机器学习
8Qi814 小时前
LeetCode 337:打家劫舍 III(House Robber III)—— 题解 ✅
算法·leetcode·二叉树·动态规划
地平线开发者14 小时前
从 INT64 Div 算子约束到 Cast 修复全流程
算法
AI科技星14 小时前
基于奇合数边界的离散解析数论与双螺旋宇宙本体大统一体系论文全部数学公式汇总表
人工智能·算法·机器学习·架构·学习方法