机器学习打卡DAY18 | 回归问题全解析:模型对比、置信区间与Bootstrap实战

一、打卡内容概览

本次打卡正式进入回归问题核心篇章(核心目标:预测连续数值,如房价、气温、混凝土抗压强度),围绕四大核心展开:

  1. 回归模型与分类模型的本质区别
  2. 回归任务核心评估指标
  3. 多输出回归任务实现思路
  4. 置信区间的意义与Bootstrap实战
    实战数据集:UCI混凝土抗压强度数据集(8个特征→预测抗压强度)

二、核心知识点回顾

1. 回归器 vs 分类器:本质区别

维度 回归器(预测连续值) 分类器(预测离散类别)
核心目标 猜「多少」(如强度、销量) 猜「是谁」(如类别、标签)
切分依据 方差(数值样本聚集程度) 纯度(基尼系数/信息熵)
代表模型 LinearRegression、RandomForestRegressor LogisticRegression、RandomForestClassifier
关键提醒 逻辑回归是「分类模型」,非回归! 分类问题无法直接转化为回归任务

2. 回归任务核心评估指标

指标名称 计算公式(简化) 核心特点
平均绝对误差(MAE) $\frac{1}{n}\sum y_{true}-y_{pred}
均方误差(MSE) 1n∑(ytrue−ypred)2\frac{1}{n}\sum(y_{true}-y_{pred})^2n1∑(ytrue−ypred)2 对大误差惩罚重,放大异常值影响
均方根误差(RMSE) MSE\sqrt{MSE}MSE 量纲与原始数据一致,论文常用
决定系数(R2R^2R2) 1−∑(ytrue−ypred)2∑(ytrue−yˉ)21-\frac{\sum(y_{true}-y_{pred})^2}{\sum(y_{true}-\bar{y})^2}1−∑(ytrue−yˉ)2∑(ytrue−ypred)2 取值0~1,越接近1拟合效果越好

3. 多输出回归任务(预测多个连续值)

  • 适用场景:气象预测(温度+湿度+风速)、工业质检(多维度性能指标)
  • 实现思路:
    1. 原生支持:树模型(决策树/随机森林)、神经网络(原生支持多输出)
    2. 包装器扩展:用sklearn.multioutput.MultiOutputRegressor包装单输出模型
    3. 拆分单任务:为每个输出构建独立模型(缺点:丢失标签间关联信息)

4. 置信区间与Bootstrap思想

  • 置信区间:并非"确定预测值",而是"包含真实值的概率范围"(如95%置信区间表示"有95%概率真实值在此范围内"),解决点预测的"绝对化"问题。
  • Bootstrap(自助法)核心逻辑:
    1. 无总体数据时,将「手头样本视为总体」
    2. 通过「有放回重采样」生成多个平行训练集
    3. 用多个模型的预测结果统计分布,得到置信区间
    4. 优势:无需依赖复杂统计分布假设(如t分布、正态分布),工程实用性强

三、代码实战:混凝土抗压强度回归任务

1. 环境准备与数据加载

python 复制代码
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error

# 全局绘图设置(支持中文)
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
sns.set(style="whitegrid", font='SimHei')

# 加载数据集(GitHub稳定源)
url = "https://raw.githubusercontent.com/stedy/Machine-Learning-with-R-datasets/master/concrete.csv"
try:
    df = pd.read_csv(url)
    print("✅ 成功加载混凝土抗压强度数据集")
except Exception as e:
    print(f"❌ 数据加载失败:{e}")
    raise e

# 重命名列为中文(增强可读性)
df.columns = [
    'Cement (水泥)', 'BlastFurnaceSlag (矿渣)', 'FlyAsh (粉煤灰)', 
    'Water (水)', 'Superplasticizer (减水剂)', 'CoarseAggregate (粗骨料)', 
    'FineAggregate (细骨料)', 'Age (养护天数)', 'Strength (抗压强度)'
]

# 数据集概览
print("\n" + "="*50)
print("数据集基本信息")
print("="*50)
print(f"数据形状:{df.shape}")
print(f"前5行数据:\n{df.head()}")
数据集输出结果
复制代码
✅ 成功加载混凝土抗压强度数据集

==================================================
数据集基本信息
==================================================
数据形状:(1030, 9)
前5行数据:
   Cement (水泥)  BlastFurnaceSlag (矿渣)  FlyAsh (粉煤灰)  Water (水)  \
0        540.0                    0.0           0.0      162.0   
1        540.0                    0.0           0.0      162.0   
2        332.5                  142.5           0.0      228.0   
3        332.5                  142.5           0.0      228.0   
4        198.6                  132.4           0.0      192.0   

   Superplasticizer (减水剂)  CoarseAggregate (粗骨料)  FineAggregate (细骨料)  \
0                     2.5                 1040.0                676.0   
1                     2.5                 1055.0                676.0   
2                     0.0                  932.0                594.0   
3                     0.0                  932.0                594.0   
4                     0.0                  978.4                825.5   

   Age (养护天数)  Strength (抗压强度)  
0          28            79.99  
1          28            61.89  
2         270            40.27  
3         365            41.05  
4         360            44.30  

2. 数据切分与多模型训练

python 复制代码
# 特征与目标变量拆分
X = df.iloc[:, :-1]  # 前8列:特征
y = df.iloc[:, -1]   # 最后1列:目标(抗压强度)

# 80%训练集,20%测试集(固定随机种子保证可复现)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)

# 定义待对比的回归模型
regressors = {
    "Linear Regression (线性回归)": LinearRegression(),
    "Decision Tree (决策树)": DecisionTreeRegressor(random_state=42),
    "Random Forest (随机森林)": RandomForestRegressor(n_estimators=100, random_state=42),
    "Gradient Boosting (梯度提升)": GradientBoostingRegressor(n_estimators=100, random_state=42)
}

# 训练模型并记录结果
results = []
preds_dict = {}  # 存储各模型预测结果(用于后续可视化)

print("\n" + "="*50)
print("模型训练与评估")
print("="*50)

for name, model in regressors.items():
    # 训练模型
    model.fit(X_train, y_train)
    # 预测测试集
    y_pred = model.predict(X_test)
    preds_dict[name] = y_pred
    # 计算评估指标
    r2 = r2_score(y_test, y_pred)
    mse = mean_squared_error(y_test, y_pred)
    rmse = np.sqrt(mse)
    mae = mean_absolute_error(y_test, y_pred)
    # 记录结果
    results.append({
        "模型名称": name,
        "R²": round(r2, 4),
        "RMSE": round(rmse, 4),
        "MAE": round(mae, 4)
    })
    print(f"✅ {name} 训练完成 | R² = {r2:.4f} | RMSE = {rmse:.4f}")

# 整理结果为DataFrame(按R²降序排序)
results_df = pd.DataFrame(results).sort_values(by="R²", ascending=False)
print("\n" + "="*50)
print("模型性能排行榜")
print("="*50)
print(results_df)
模型训练输出结果
复制代码
==================================================
模型训练与评估
==================================================
✅ Linear Regression (线性回归) 训练完成 | R² = 0.6276 | RMSE = 9.7965
✅ Decision Tree (决策树) 训练完成 | R² = 0.8348 | RMSE = 6.5254
✅ Random Forest (随机森林) 训练完成 | R² = 0.8841 | RMSE = 5.4639
✅ Gradient Boosting (梯度提升) 训练完成 | R² = 0.8829 | RMSE = 5.4934

==================================================
模型性能排行榜
==================================================
                       模型名称     R²     RMSE     MAE
2      Random Forest (随机森林)  0.8841  5.4639  3.7363
3  Gradient Boosting (梯度提升)  0.8829  5.4934  4.1350
1       Decision Tree (决策树)  0.8348  6.5254  4.2938
0  Linear Regression (线性回归)  0.6276  9.7965  7.7456

3. 模型可视化:拟合效果与置信区间

python 复制代码
# 设置画布(2行2列子图)
fig, axes = plt.subplots(2, 2, figsize=(16, 14))
axes = axes.flatten()  # 展平为1维数组,方便遍历
colors = ["#1f77b4", "#ff7f0e", "#2ca02c", "#d62728"]  # 每个模型对应颜色

# 统一坐标轴范围(所有子图保持一致,增强对比性)
all_preds = [preds_dict[m] for m in regressors.keys()]
data_min = min(y_test.min(), np.min(all_preds)) - 5
data_max = max(y_test.max(), np.max(all_preds)) + 5

print("\n📊 正在绘制模型拟合效果与置信区间图...")

for i, (name, model) in enumerate(regressors.items()):
    ax = axes[i]
    y_pred = preds_dict[name]
    
    # 绘制带95%置信区间的散点图(sns.regplot自动计算置信区间)
    sns.regplot(
        x=y_test, y=y_pred, ax=ax,
        color=colors[i],
        ci=95,  # 关键参数:绘制95%置信区间
        scatter_kws={'s': 30, 'alpha': 0.5, 'edgecolor': 'white'},  # 散点样式
        line_kws={'color': '#333333', 'linewidth': 2, 'label': '拟合趋势线'}  # 拟合线样式
    )
    
    # 绘制完美预测线(y=x,即预测值=真实值)
    ax.plot(
        [data_min, data_max], [data_min, data_max],
        'r--', linewidth=3, label='完美预测线 (y=x)'
    )
    
    # 计算当前模型指标(用于图中显示)
    r2 = r2_score(y_test, y_pred)
    rmse = np.sqrt(mean_squared_error(y_test, y_pred))
    
    # 在图中添加指标文本框
    text_str = f'$R^2$ = {r2:.3f}\nRMSE = {rmse:.3f}'
    ax.text(
        0.05, 0.95, text_str, transform=ax.transAxes, fontsize=14,
        verticalalignment='top', bbox=dict(boxstyle='round', facecolor='white', alpha=0.9)
    )
    
    # 子图装饰
    ax.set_title(name, fontsize=16, fontweight='bold')
    ax.set_xlabel('真实强度 (Actual Strength)', fontsize=12)
    ax.set_ylabel('预测强度 (Predicted Strength)', fontsize=12)
    ax.set_xlim(data_min, data_max)
    ax.set_ylim(data_min, data_max)
    ax.legend(loc='lower right')
    ax.grid(True, linestyle='--', alpha=0.5)

# 总标题与布局调整
plt.suptitle('各回归模型拟合效果与95%置信区间分析', fontsize=20, y=0.98)
plt.tight_layout()
plt.subplots_adjust(top=0.92)
plt.savefig('模型拟合与置信区间.png', dpi=300, bbox_inches='tight')
plt.show()

今天的学习,是连接模型与现实世界的关键桥梁。感谢 @浙大疏锦行 老师带来的精彩一课,让我对数据科学的理解又深入了一层!

相关推荐
闻缺陷则喜何志丹2 小时前
【超音速专利 CN116777899A】基于回归模型的工业图像关键点检测方法、系统及平台
人工智能·数据挖掘·回归·专利·超音速
Eloudy2 小时前
jacobi solver 迭代算法
人工智能·算法·机器学习
不断学习加努力2 小时前
几种自动驾驶框架简要梳理
人工智能·机器学习·自动驾驶
有为少年2 小时前
神经网络 | 从线性结构到可学习非线性
人工智能·深度学习·神经网络·学习·算法·机器学习·信号处理
秋刀鱼 ..3 小时前
第二届机器学习、计算智能与模式识别国际学术会议(MLCIPR 2025)
运维·人工智能·python·科技·机器学习·自动化
高洁013 小时前
循环神经网络讲解(2)
人工智能·python·深度学习·神经网络·机器学习
飞Link3 小时前
【算法与模型】One-Class SVM 异常检测全解析:原理、实例、项目实战与工程经验
人工智能·python·算法·机器学习·支持向量机
玦尘、17 小时前
《统计学习方法》第6章——逻辑斯谛回归与最大熵模型(上)【学习笔记】
机器学习·回归·学习方法