机器学习入门:线性回归详解及Scikit-learn API使用指南

发布于:2025-07-08 ⋅ 阅读:(24) ⋅ 点赞:(0)

一、线性回归概述

线性回归是统计学和机器学习领域中最基础、最广泛应用的预测建模技术之一。自19世纪初由弗朗西斯·高尔顿(Francis Galton)首次提出以来,线性回归已成为数据分析的核心工具,在经济学、社会科学、生物统计学、工程学等众多领域发挥着重要作用。

1.1 线性回归的本质与价值

线性回归的核心思想是通过建立自变量(解释变量)与因变量(响应变量)之间的线性关系模型,来理解和预测数据的变化规律。这种方法的强大之处在于:

  1. 解释性强:模型参数具有直观的统计意义,便于理解变量间的关系

  2. 计算高效:相比复杂模型,线性回归的计算成本低,适合大规模数据集

  3. 基础性强:是理解更复杂机器学习算法的基础

  4. 可扩展性:可以通过各种扩展处理非线性关系

在实际应用中,线性回归常用于:

  • 销售预测(根据历史数据预测未来销售额)

  • 房价评估(基于房屋特征预测市场价格)

  • 经济分析(研究GDP与失业率的关系)

  • 医学研究(分析药物剂量与疗效的关系)

1.2 线性回归的数学本质

从数学角度看,线性回归解决的是一个优化问题:寻找一组参数(系数),使得模型预测值与实际观测值之间的差异(通常用平方误差表示)最小化。这种方法称为普通最小二乘法(OLS)

对于简单线性回归(单变量),数学表达式为:

 

 对于多元线性回归(多变量),表达式扩展为:

 

其中:

  • y:因变量(我们想要预测的值)

  • x/x₁,x₂,...xₙ:自变量(用于预测的特征)

  • β₀:截距项(当所有自变量为0时y的值)

  • β₁,β₂,...βₙ:回归系数(每个自变量对y的影响程度)

  • ε:误差项(模型无法解释的随机波动)

1.3 线性关系的深入理解

线性回归中的"线性"有两层含义:

  1. 变量线性:因变量与自变量呈直线关系

  2. 参数线性:因变量与回归系数呈线性关系

值得注意的是,线性回归可以处理非线性关系,只要这种非线性关系可以通过变量转换变为参数线性形式。例如:

  • 多项式关系:y = β₀ + β₁x + β₂x²

  • 对数关系:ln(y) = β₀ + β₁x

  • 交互作用:y = β₀ + β₁x₁ + β₂x₂ + β₃x₁x₂

1.4 线性回归的统计假设

为了保证线性回归模型的有效性和推断的可靠性,经典线性回归模型基于以下统计假设:

  1. 线性关系假设:因变量与自变量之间存在真实的线性关系

  2. 独立性假设:观测值之间相互独立(特别针对时间序列数据)

  3. 同方差性:误差项的方差应保持恒定(不随预测值变化而变化)

  4. 正态性假设:误差项服从正态分布(对于大样本相对宽松)

  5. 无多重共线性:自变量之间不应存在高度相关性

  6. 无自相关:误差项之间不应存在相关性(针对时间序列)

当这些假设被违反时,可能导致:

  • 系数估计不准确

  • 标准误差计算错误

  • 统计检验失效

  • 预测结果不可靠

1.5 线性回归的变体与扩展

根据不同的数据特性和问题需求,线性回归有多种扩展形式:

  1. 加权最小二乘法(WLS):处理异方差性问题

  2. 广义最小二乘法(GLS):处理自相关问题

  3. 岭回归(Ridge Regression):通过L2正则化处理多重共线性

  4. Lasso回归:通过L1正则化实现特征选择

  5. 弹性网络(Elastic Net):结合L1和L2正则化的优势

  6. 稳健回归(Robust Regression):降低异常值影响

  7. 分位数回归(Quantile Regression):研究条件分位数关系

1.6 线性回归的工作流程

一个完整的线性回归分析通常包括以下步骤:

  1. 问题定义:明确分析目标和变量选择

  2. 数据收集:获取相关变量的观测数据

  3. 数据探索:检查数据质量、分布和关系

  4. 数据预处理:处理缺失值、异常值、特征工程

  5. 模型拟合:计算回归系数

  6. 模型诊断:检验回归假设、评估模型拟合度

  7. 模型优化:变量选择、处理非线性

  8. 结果解释:解释系数含义、评估预测能力

  9. 模型部署:应用模型进行预测

1.7 线性回归的局限性

尽管线性回归应用广泛,但也有其局限性:

  1. 对非线性关系捕捉能力有限(需通过特征工程解决)

  2. 对异常值敏感(可考虑使用稳健回归)

  3. 当特征数量大于样本数量时表现不佳(需正则化)

  4. 假设自变量是精确测量的(测量误差会影响估计)

  5. 容易受到无关变量的干扰(需进行变量选择)

二、Scikit-learn中的线性回归实现

Scikit-learn是Python中最流行的机器学习库之一,提供了简单高效的工具用于数据挖掘和数据分析。

2.1 导入必要的库

# NumPy - Python科学计算的基础库,提供高性能的多维数组对象和数组计算工具
# 主要用于:数值计算、矩阵运算、线性代数、随机数生成等
import numpy as np

# Matplotlib - Python最流行的2D绘图库,提供类似MATLAB的绘图接口
# pyplot模块提供MATLAB风格的绘图API,用于数据可视化
import matplotlib.pyplot as plt

# scikit-learn中的线性回归模型实现
# LinearRegression类实现了普通最小二乘线性回归算法
from sklearn.linear_model import LinearRegression

# scikit-learn中的模型选择工具
# train_test_split函数用于将数据集随机划分为训练集和测试集
from sklearn.model_selection import train_test_split

# scikit-learn中的模型评估指标
# mean_squared_error - 计算均方误差(MSE)回归损失
# r2_score - 计算R²分数(决定系数),回归模型的评估指标
from sklearn.metrics import mean_squared_error, r2_score

# scikit-learn中的数据集生成工具
# make_regression函数用于生成适合回归分析的模拟数据集
from sklearn.datasets import make_regression

2.2 线性回归API详解

Scikit-learn中的LinearRegression类实现了普通最小二乘线性回归。

主要参数:
  1. fit_intercept (bool, default=True)

    • 是否计算截距(β₀)

    • 如果设置为False,则模型不会计算截距(即数据已经中心化)

  2. normalize (bool, default=False)

    • 在拟合前是否对回归变量X进行归一化

    • 当fit_intercept=False时,此参数被忽略

    • 注意:从1.0版本开始,此参数将被弃用,建议使用StandardScaler进行预处理

  3. copy_X (bool, default=True)

    • 是否复制X。如果为False,X可能会被覆盖

  4. n_jobs (int, default=None)

    • 用于计算的作业数

    • 主要用于多目标回归问题(n_targets > 1)

主要属性:
  1. coef_ (array of shape (n_features, ) or (n_targets, n_features))

    • 回归系数(斜率,β₁, β₂,...βₙ)

  2. intercept_ (float or array of shape (n_targets,))

    • 截距(β₀)

  3. rank_ (int)

    • 矩阵X的秩

  4. singular_ (array of shape (min(X, y),))

    • X的奇异值

主要方法:
  1. fit(X, y[, sample_weight])

    • 拟合线性模型

    • X: 训练数据,形状为(n_samples, n_features)

    • y: 目标值,形状为(n_samples,)或(n_samples, n_targets)

    • sample_weight: 样本权重,形状为(n_samples,)

  2. predict(X)

    • 使用线性模型进行预测

    • 返回预测值

  3. score(X, y[, sample_weight])

    • 返回预测的确定系数R²

    • R² = 1 - (SS_res / SS_tot)

    • 最佳得分为1.0,可能为负值(模型表现比随机猜测还差)

2.3 简单线性回归示例

# 生成示例数据
np.random.seed(42)
X = 2 * np.random.rand(100, 1)  # 生成100个0-2之间的随机数
y = 4 + 3 * X + np.random.randn(100, 1)  # y = 4 + 3x + 噪声

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

# 创建线性回归模型实例
lin_reg = LinearRegression()

# 训练模型
lin_reg.fit(X_train, y_train)

# 查看模型参数
print("截距(intercept):", lin_reg.intercept_)  # 输出截距β₀
print("系数(coef):", lin_reg.coef_)  # 输出系数β₁

# 进行预测
y_pred = lin_reg.predict(X_test)

# 评估模型
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print("均方误差(MSE):", mse)
print("R²分数:", r2)

# 可视化结果
plt.scatter(X, y, color='blue', label='原始数据')
plt.plot(X_test, y_pred, color='red', linewidth=3, label='预测线')
plt.xlabel('X')
plt.ylabel('y')
plt.title('简单线性回归')
plt.legend()
plt.show()

2.4 多元线性回归示例 

# 生成具有多个特征的示例数据
X, y = make_regression(n_samples=100, n_features=5, noise=0.1, random_state=42)

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

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

# 查看模型参数
print("截距:", multi_lin_reg.intercept_)
print("系数:", multi_lin_reg.coef_)

# 进行预测和评估
y_pred = multi_lin_reg.predict(X_test)
print("MSE:", mean_squared_error(y_test, y_pred))
print("R²:", r2_score(y_test, y_pred))

三、线性回归的扩展

3.1 多项式回归

当数据关系不是简单的线性关系时,可以通过添加多项式特征来拟合更复杂的关系。

from sklearn.preprocessing import PolynomialFeatures

# 生成非线性数据
np.random.seed(42)
m = 100
X = 6 * np.random.rand(m, 1) - 3
y = 0.5 * X**2 + X + 2 + np.random.randn(m, 1)

# 添加多项式特征
poly_features = PolynomialFeatures(degree=2, include_bias=False)
X_poly = poly_features.fit_transform(X)

# 训练模型
lin_reg_poly = LinearRegression()
lin_reg_poly.fit(X_poly, y)

# 查看参数
print("截距:", lin_reg_poly.intercept_)
print("系数:", lin_reg_poly.coef_)

# 可视化
X_new = np.linspace(-3, 3, 100).reshape(100, 1)
X_new_poly = poly_features.transform(X_new)
y_new = lin_reg_poly.predict(X_new_poly)

plt.scatter(X, y, color='blue')
plt.plot(X_new, y_new, color='red', linewidth=2, label="多项式回归")
plt.xlabel('X')
plt.ylabel('y')
plt.legend()
plt.show()

3.2 正则化线性回归

        在标准线性回归中,当特征数量较多或特征间存在高度相关性时,模型容易出现过拟合(overfitting)问题——即在训练集上表现很好,但在测试集上表现较差。正则化(Regularization) 是一种用于防止过拟合的技术,通过在损失函数中添加惩罚项来约束模型参数的大小,从而降低模型复杂度。以下是三种常见的正则化线性回归方法:

1.岭回归(Ridge Regression)  

原理

  • 在普通最小二乘法的损失函数中增加 L2正则化项(即系数平方和的惩罚项),优化目标为:

    其中:

    • α 是正则化强度(超参数),控制惩罚力度(α≥0)。

    • 惩罚项 会压缩系数,但不会完全消除任何特征。

特点

  • 适用场景:特征数量多、特征间存在共线性(相关性高)时。

  • 效果:所有系数都会缩小,但不会变为零(保留所有特征)。

  • 参数

    • alpha:正则化强度,越大则系数收缩越明显(默认=1)。

    • solver:优化算法(如 "cholesky""sag" 等)。

示例代码

from sklearn.linear_model import Ridge
ridge_reg = Ridge(alpha=1.0, solver="cholesky")  # 使用解析解求解
ridge_reg.fit(X_train, y_train)
2.Lasso回归     

原理

  • 在损失函数中增加 L1正则化项(即系数绝对值的惩罚项),优化目标为:

    L1正则化会使得部分系数恰好为零,从而实现特征选择。

特点

  • 适用场景:特征数量非常多,且希望自动进行特征选择时。

  • 效果:稀疏性(某些系数归零),适合高维数据。

  • 参数

    • alpha:正则化强度(默认=1)。

    • max_iter:最大迭代次数(因L1优化问题可能需迭代求解)。

示例代码

from sklearn.linear_model import Lasso
lasso_reg = Lasso(alpha=0.1, max_iter=10000)  # 设置较大的max_iter保证收敛
lasso_reg.fit(X_train, y_train)
print("被压缩为零的系数数量:", sum(lasso_reg.coef_ == 0))  # 查看多少特征被剔除
3.弹性网络(Elastic Net) 

原理

  • 结合 L1和L2正则化,平衡岭回归和Lasso的优点,优化目标为:

    其中:

    • αα 控制整体正则化强度。

    • ρ(l1_ratio)控制L1和L2的混合比例(0=纯岭回归,1=纯Lasso)。

特点

  • 适用场景:特征数量远大于样本数,或特征间存在强相关性时。

  • 效果:既能选择特征(L1部分),又能保留相关特征组的稳定性(L2部分)。

  • 参数

    • alpha:总体正则化强度。

    • l1_ratio:L1正则化的比例(默认=0.5,即L1和L2各占一半)。

示例代码

from sklearn.linear_model import ElasticNet
elastic_net = ElasticNet(alpha=0.1, l1_ratio=0.5)  # alpha=0.1, L1和L2各占50%
elastic_net.fit(X_train, y_train)

如何选择正则化方法?

方法 适用场景 优点 缺点
岭回归 特征相关性高,需保留所有特征 稳定,适合共线性数据 不进行特征选择
Lasso 特征数量多,且只有少数特征重要 自动特征选择,模型更简单 可能随机选择一个特征丢弃相关特征组
弹性网络 特征数量极多(如基因数据),且存在特征组相关性 兼顾特征选择和稳定性 需调两个超参数(alphal1_ratio

实际建议

  1. 优先尝试岭回归,若效果不佳再测试Lasso。

  2. 若特征数远大于样本数(如文本分类),使用弹性网络。

  3. 使用交叉验证(如GridSearchCV)优化超参数(如alpha)。

 

四、线性回归的评估指标

        在建立线性回归模型后,我们需要使用评估指标来衡量模型的性能。不同的指标从不同角度反映模型的预测能力,以下是常用的线性回归评估指标及其解释: 

4.1.均方误差(MSE)

数学公式

解释

  • 计算方式:所有样本的预测值(y^i)与实际值(yi)的平方误差的平均值

  • 特点

    • 大误差敏感(因为平方放大了较大误差的影响)。

    • 值域为 [0,+∞),越小越好。

    • 单位是目标变量的平方(如预测房价时单位为“万元²”),不易直接解释。

使用场景

  • 需要惩罚较大预测错误时(如安全关键领域)。

  • 适用于比较不同模型的性能。

示例代码

from sklearn.metrics import mean_squared_error
mse = mean_squared_error(y_true, y_pred)
print("均方误差(MSE):", mse)

4.2.均方根误差(RMSE) 

数学公式

解释

  • 计算方式:MSE的平方根,将误差单位还原到原始尺度。

  • 特点

    • 与MSE一样对大误差敏感。

    • 值域为 [0,+∞),越小越好。

    • 单位与目标变量一致(如“万元”),更易解释。

使用场景

  • 需要直观理解误差大小时(如RMSE=5万元,表示平均预测偏差约5万元)。

  • 比MSE更常用在实际报告中。

示例代码

rmse = np.sqrt(mean_squared_error(y_true, y_pred))
print("均方根误差(RMSE):", rmse)

4.3.平均绝对误差(MAE) 

数学公式

解释

  • 计算方式:所有样本的预测值与实际值的绝对误差的平均值

  • 特点

    • 异常值不敏感(因为未平方)。

    • 值域为 [0,+∞),越小越好。

    • 单位与目标变量一致,解释直观(如“平均偏差3万元”)。

使用场景

  • 数据中存在异常值时。

  • 需要直接了解平均预测误差幅度时。

与RMSE的区别

  • RMSE强调较大误差,MAE对所有误差一视同仁。

  • 若误差分布存在长尾,RMSE > MAE。

示例代码

from sklearn.metrics import mean_absolute_error
mae = mean_absolute_error(y_true, y_pred)
print("平均绝对误差(MAE):", mae)

4.4.R²分数(决定系数) 

数学公式

  • 特点

    • 值域为 (−∞,1],越接近1越好。

    • 无量纲,可用于不同数据集间的模型比较。

使用场景

  • 需要评估模型的整体解释力时。

  • 注意: 随特征数量增加而增大(即使无关特征),因此调整后的 (Adjusted R²)更适用于多特征模型。

示例代码

from sklearn.metrics import r2_score
r2 = r2_score(y_true, y_pred)
print("R²分数:", r2)

如何选择评估指标?

指标 敏感度 单位一致性 异常值鲁棒性 适用场景
MSE 需要强调大误差的场景
RMSE 最常用的误差指标
MAE 存在异常值或需直观理解误差时
- 无量纲 - 评估模型解释变异的能力

实际建议

  1. 报告多个指标:例如同时给出RMSE和R²,兼顾误差大小和解释力。

  2. 业务对齐:选择与业务目标相关的指标(如金融领域更关注MAE)。

  3. 交叉验证:使用交叉验证计算指标的稳定性(如cross_val_score)。

五、实际应用案例:波士顿房价预测 

from sklearn.datasets import load_boston

# 加载数据集
boston = load_boston()
X = boston.data
y = boston.target

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

# 特征缩放(标准化)
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

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

# 评估模型
y_pred = boston_reg.predict(X_test_scaled)
print("MSE:", mean_squared_error(y_test, y_pred))
print("RMSE:", np.sqrt(mean_squared_error(y_test, y_pred)))
print("R²:", r2_score(y_test, y_pred))

# 查看特征重要性
feature_importance = pd.DataFrame({
    'Feature': boston.feature_names,
    'Coefficient': boston_reg.coef_
}).sort_values(by='Coefficient', key=abs, ascending=False)

print(feature_importance)

六、总结与最佳实践

  1. 数据预处理

    • 处理缺失值

    • 特征缩放(标准化或归一化)

    • 处理分类变量(独热编码等)

  2. 模型训练

    • 总是划分训练集和测试集

    • 考虑使用交叉验证

    • 对于小数据集,使用留一法交叉验证

  3. 模型评估

    • 不要仅依赖R²分数

    • 查看残差图检查模型假设

    • 考虑使用多个评估指标

  4. 改进模型

    • 尝试添加多项式特征

    • 使用正则化防止过拟合

    • 考虑特征选择或降维

  5. 注意事项

    • 线性回归对异常值敏感

    • 多重共线性会影响系数解释

    • 非线性关系需要转换特征

通过本教程,你应该对线性回归的理论基础和Scikit-learn中的实现有了全面的了解。线性回归虽然简单,但在许多实际问题中仍然非常有效,是机器学习工程师和数据科学家的必备工具。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


网站公告

今日签到

点亮在社区的每一天
去签到