📈 《数据挖掘》学习笔记(四):回归分析

系列文章目录

章节 内容 状态
第一章 绪论
第二章 数据描述与统计指标
第三章 相关分析
第四章 回归分析
第五章 降维 待更新
第六章 关联规则挖掘 待更新
第七章 分类 待更新
第八章 聚类 待更新
第九章 异常检测 待更新
第十章 集成学习 待更新

🔍 第四章 回归分析

4.1 线性回归概

回归分析是一种统计分析方法,用于研究变量之间的依赖关系,特别是因变量与一个或多个自变量之间的定量关系。

回归分析基本流程:

数据收集与准备

探索性数据分析
EDA

选择回归模型

模型训练与参数估计

模型评估与诊断

模型是否满意?

模型应用与预测

模型优化/调整

回归分析是一种统计分析方法,用于研究变量之间的依赖关系,特别是因变量与一个或多个自变量之间的定量关系。

4.2 一元线性回归

基本原理: 建立一个因变量 Y 与单个自变量 X 之间的线性关系模型。

import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
import matplotlib.pyplot as plt

# 准备数据
df = pd.read_csv('salary_data.csv')
X = df[['YearsExperience']].values  # 自变量:工作年限
y = df['Salary'].values  # 因变量:薪资

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建并训练模型
model = LinearRegression()
model.fit(X_train, y_train)

# 预测
y_pred = model.predict(X_test)

# 评估模型
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

print(f"回归系数(斜率): {model.coef_[0]:.2f}")
print(f"截距: {model.intercept_:.2f}")
print(f"均方误差(MSE): {mse:.2f}")
print(f"决定系数(R²): {r2:.4f}")

# 可视化
plt.figure(figsize=(10, 6))
plt.scatter(X, y, color='blue', label='实际数据')
plt.plot(X, model.predict(X), color='red', label='回归线')
plt.xlabel('工作年限')
plt.ylabel('薪资')
plt.title('工作年限与薪资关系 - 一元线性回归')
plt.legend()
plt.show()

4.3 多元线性回归

基本原理: 建立一个因变量 Y 与多个自变量 X₁, X₂, …, Xₙ 之间的线性关系模型。

# 多变量回归
X = df[['YearsExperience', 'Education', 'Age']].values  # 多个自变量
y = df['Salary'].values  # 因变量

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

model = LinearRegression()
model.fit(X_train, y_train)

print("各变量回归系数:")
print(f"工作年限系数: {model.coef_[0]:.2f}")
print(f"教育程度系数: {model.coef_[1]:.2f}")
print(f"年龄系数: {model.coef_[2]:.2f}")
print(f"截距: {model.intercept_:.2f}")
print(f"R²: {r2_score(y_test, model.predict(X_test)):.4f}")

4.4 多重共线性

问题定义: 当回归模型中的自变量之间存在高度线性相关时,就称存在多重共线性问题。

影响:

  • 回归系数估计不稳定,方差增大
  • 变量的显著性检验不可靠
  • 模型解释困难

方差膨胀因子(VIF):

from statsmodels.stats.outliers_influence import variance_inflation_factor

# 准备数据
X = df[['YearsExperience', 'Education', 'Age']].values

# 计算VIF
vif_data = pd.DataFrame()
vif_data["feature"] = ['YearsExperience', 'Education', 'Age']
vif_data["VIF"] = [variance_inflation_factor(X, i) for i in range(X.shape[1])]

print("方差膨胀因子(VIF):")
print(vif_data)

# VIF判断标准
# VIF = 1: 无共线性
# 1 < VIF < 5: 轻度共线性
# 5 ≤ VIF < 10: 中度共线性
# VIF ≥ 10: 严重共线性,需要处理

4.5 岭回归(Ridge Regression)

基本原理: 在最小二乘法的基础上添加L2正则化项,通过惩罚大的系数来减少多重共线性的影响。

from sklearn.linear_model import Ridge
from sklearn.model_selection import GridSearchCV

# 使用交叉验证选择最优alpha
ridge = Ridge()
param_grid = {'alpha': [0.001, 0.01, 0.1, 1, 10, 100, 1000]}
grid = GridSearchCV(ridge, param_grid, cv=5, scoring='r2')
grid.fit(X_train, y_train)

print(f"最优alpha: {grid.best_params_['alpha']}")
print(f"最优R²: {grid.best_score_:.4f}")

best_ridge = grid.best_estimator_
y_pred = best_ridge.predict(X_test)

print(f"测试集R²: {r2_score(y_test, y_pred):.4f}")
print(f"回归系数: {best_ridge.coef_}")

4.6 LASSO回归

基本原理: 使用L1正则化,可以将不重要的系数压缩为零,实现特征选择的效果。

from sklearn.linear_model import Lasso

# LASSO回归(L1正则化,可实现特征选择)
lasso = Lasso(alpha=1.0, max_iter=10000)
lasso.fit(X_train, y_train)

y_pred = lasso.predict(X_test)

print(f"LASSO回归R²: {r2_score(y_test, y_pred):.4f}")
print(f"非零系数数量: {np.sum(lasso.coef_ != 0)}")
print(f"系数:\n{lasso.coef_}")

# 特征选择结果
feature_names = ['YearsExperience', 'Education', 'Age']
for name, coef in zip(feature_names, lasso.coef_):
    if coef != 0:
        print(f"  {name}: {coef:.4f}")

4.7 非线性回归

多项式回归:

from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import Pipeline

# 多项式回归(二次多项式)
poly = PolynomialFeatures(degree=2)
X_poly = poly.fit_transform(X_train)

model = LinearRegression()
model.fit(X_poly, y_train)

X_test_poly = poly.transform(X_test)
y_pred = model.predict(X_test_poly)

print(f"多项式回归(degree=2) R²: {r2_score(y_test, y_pred):.4f}")

# 不同次数多项式的比较
for degree in [1, 2, 3]:
    poly = PolynomialFeatures(degree=degree)
    X_poly_train = poly.fit_transform(X_train)
    X_poly_test = poly.transform(X_test)
    
    model = LinearRegression()
    model.fit(X_poly_train, y_train)
    
    train_r2 = model.score(X_poly_train, y_train)
    test_r2 = model.score(X_poly_test, y_test)
    
    print(f"degree={degree}: 训练R²={train_r2:.4f}, 测试R²={test_r2:.4f}")

4.8 模型评估与选

from sklearn.metrics import mean_absolute_error, mean_squared_error

# 评估指标
y_pred = model.predict(X_test)

print("模型评估指标:")
print(f"MAE (平均绝对误差): {mean_absolute_error(y_test, y_pred):.2f}")
print(f"MSE (均方误差): {mean_squared_error(y_test, y_pred):.2f}")
print(f"RMSE (均方根误差): {np.sqrt(mean_squared_error(y_test, y_pred)):.2f}")
print(f"R² (决定系数): {r2_score(y_test, y_pred):.4f}")

# 模型选择可视化
plt.figure(figsize=(12, 5))

plt.subplot(1, 2, 1)
plt.scatter(y_test, y_pred, alpha=0.6)
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--', lw=2)
plt.xlabel('实际值')
plt.ylabel('预测值')
plt.title('预测值 vs 实际值')

plt.subplot(1, 2, 2)
residuals = y_test - y_pred
plt.scatter(y_pred, residuals, alpha=0.6)
plt.axhline(y=0, color='r', linestyle='--')
plt.xlabel('预测值')
plt.ylabel('残差')
plt.title('残差图')

plt.tight_layout()
plt.show()

回归模型选择决策树:

线性关系

单个自变量

多个自变量

严重

轻微或无

非线性关系

多项式

其他非线性

开始: 回归问题

数据特征?

自变量数量?

一元线性回归

多重共线性?

岭回归
Ridge Regression

需要特征选择?

LASSO回归

多元线性回归

关系类型?

多项式回归

非线性回归
如指数、对数等

模型评估

评估结果满意?

模型应用

调整参数/换模型

from sklearn.metrics import mean_absolute_error, mean_squared_error

# 评估指标
y_pred = model.predict(X_test)

print("模型评估指标:")
print(f"MAE (平均绝对误差): {mean_absolute_error(y_test, y_pred):.2f}")
print(f"MSE (均方误差): {mean_squared_error(y_test, y_pred):.2f}")
print(f"RMSE (均方根误差): {np.sqrt(mean_squared_error(y_test, y_pred)):.2f}")
print(f"R² (决定系数): {r2_score(y_test, y_pred):.4f}")

# 模型选择可视化
plt.figure(figsize=(12, 5))

plt.subplot(1, 2, 1)
plt.scatter(y_test, y_pred, alpha=0.6)
plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--', lw=2)
plt.xlabel('实际值')
plt.ylabel('预测值')
plt.title('预测值 vs 实际值')

plt.subplot(1, 2, 2)
residuals = y_test - y_pred
plt.scatter(y_pred, residuals, alpha=0.6)
plt.axhline(y=0, color='r', linestyle='--')
plt.xlabel('预测值')
plt.ylabel('残差')
plt.title('残差图')

plt.tight_layout()
plt.show()

💡 回归分析实战案例

汽车燃油效率预测:

# 使用汽车数据集进行燃油效率预测
import seaborn as sns

# 加载数据
car_data = sns.load_dataset('mpg')

# 数据预处理
car_data = car_data.dropna()
X = car_data[['cylinders', 'displacement', 'horsepower', 'weight', 'acceleration']]
y = car_data['mpg']

# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 训练多个模型进行比较
from sklearn.linear_model import LinearRegression, Ridge, Lasso, ElasticNet

models = {
    'Linear': LinearRegression(),
    'Ridge': Ridge(alpha=1.0),
    'Lasso': Lasso(alpha=1.0),
    'ElasticNet': ElasticNet(alpha=1.0, l1_ratio=0.5)
}

print("汽车燃油效率预测 - 模型比较:")
print("-" * 50)

for name, model in models.items():
    model.fit(X_train, y_train)
    y_pred = model.predict(X_test)
    r2 = r2_score(y_test, y_pred)
    rmse = np.sqrt(mean_squared_error(y_test, y_pred))
    print(f"{name:12s} R²: {r2:.4f}  RMSE: {rmse:.4f}")

💡 本章小结

本章介绍了回归分析的主要方法:

  • 一元线性回归:最简单的回归模型
  • 多元线性回归:处理多个自变量
  • 多重共线性:诊断和处理自变量间的高相关性
  • 岭回归:通过L2正则化处理共线性
  • LASSO回归:通过L1正则化实现特征选择
  • 非线性回归:处理非线性关系

🔗 参考资料


系列文章预告: 下一篇将介绍第五章「降维」,包括PCA、因子分析、t-SNE等方法。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐