机器学习模型选择实战:从OLS到正则化的进阶之路

刚接触机器学习时,我们往往从最简单的线性回归开始。但当你真正把模型应用到实际业务数据时,很快就会发现:为什么测试集表现这么差?为什么有些特征明显没用却影响了预测结果?这时,你需要了解比普通最小二乘法(OLS)更强大的工具——岭回归(Ridge Regression)和Lasso回归。

1. 为什么需要超越OLS?

在理想情况下,当数据满足高斯-马尔可夫假设时,OLS确实是最佳线性无偏估计。但现实数据往往充满挑战:

  • 多重共线性 :当特征高度相关时,OLS估计的方差会急剧增大
  • 高维数据 :特征数量超过样本量时,OLS无法得到唯一解
  • 噪声特征 :数据中包含大量无关特征时,OLS会过拟合
from sklearn.datasets import make_regression
import numpy as np

# 生成模拟数据
X, y = make_regression(n_samples=100, n_features=10, noise=0.1, random_state=42)

# 人为添加共线性
X[:, 5] = X[:, 3] * 1.5 + np.random.normal(0, 0.1, 100)

# 添加无关特征
X = np.hstack([X, np.random.randn(100, 5)])

提示:在实际项目中,数据质量问题远比理论假设复杂。建议在建模前先进行全面的EDA分析。

2. 正则化技术的核心原理

正则化通过在损失函数中添加惩罚项来控制模型复杂度:

技术 惩罚项 数学表达式 主要特点
OLS $\min \sum(y_i-\hat{y}_i)^2$ 无偏但高方差
岭回归 L2范数 $\min \sum(y_i-\hat{y}_i)^2 + \alpha\sum w_j^2$ 收缩系数但不为零
Lasso L1范数 $\min \sum(y_i-\hat{y}_i)^2 + \alpha\sum w_j

关键参数α的选择

  • α=0:退化为普通OLS
  • α→∞:所有系数趋近于0
  • 最佳α需要通过交叉验证确定

3. 实战对比:波士顿房价数据集

让我们用sklearn内置数据集进行完整演示:

from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.datasets import load_boston
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

# 加载数据
boston = load_boston()
X, y = boston.data, boston.target
X = StandardScaler().fit_transform(X)  # 标准化很重要!

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

# 初始化模型
models = {
    "OLS": LinearRegression(),
    "Ridge (α=1)": Ridge(alpha=1),
    "Lasso (α=0.1)": Lasso(alpha=0.1)
}

# 训练并评估
results = {}
for name, model in models.items():
    model.fit(X_train, y_train)
    results[name] = {
        "train_score": model.score(X_train, y_train),
        "test_score": model.score(X_test, y_test),
        "coef": model.coef_
    }

系数对比可视化

plt.figure(figsize=(12, 6))
for i, (name, result) in enumerate(results.items()):
    plt.subplot(1, 3, i+1)
    plt.bar(range(X.shape[1]), result["coef"])
    plt.title(f"{name}\nTest Score: {result['test_score']:.3f}")
    plt.ylim(-5, 5)
plt.tight_layout()
plt.show()

从结果中可以观察到:

  • OLS在训练集表现最好但测试集容易过拟合
  • 岭回归系数普遍缩小但保持非零
  • Lasso将部分系数压缩为零,实现了特征选择

4. 如何根据数据特征选择模型?

决策流程图

  1. 检查特征数量

    • 特征数 >> 样本数:优先考虑Lasso
    • 特征数适中:尝试所有三种方法
  2. 分析特征相关性

    • 高共线性:岭回归表现更好
    • 独立特征:OLS可能足够
  3. 评估特征重要性

    • 预期少量关键特征:Lasso
    • 预期多数特征都有贡献:岭回归
  4. 业务需求考量

    • 需要可解释性:Lasso的稀疏性有帮助
    • 需要稳定预测:岭回归更鲁棒

实用技巧

  • 使用 sklearn.linear_model.RidgeCV LassoCV 自动选择最佳α
  • 对Lasso,可以逐步增加α直到获得理想的稀疏度
  • 考虑ElasticNet结合L1和L2惩罚
from sklearn.linear_model import LassoCV

# 自动选择最佳alpha
lasso_cv = LassoCV(alphas=np.logspace(-4, 0, 50), cv=5)
lasso_cv.fit(X_train, y_train)

print(f"最佳alpha: {lasso_cv.alpha_:.4f}")
print(f"非零系数数量: {np.sum(lasso_cv.coef_ != 0)}")

5. 高级应用与陷阱规避

特征标准化至关重要

  • 正则化对特征尺度敏感
  • 必须在使用前标准化(StandardScaler)

处理极端值

  • 正则化对异常值敏感
  • 考虑使用RobustScaler或处理异常值

分类特征处理

  • 需要适当编码(OneHot等)
  • 高基数类别可能需要特殊处理

样本量不足时的策略

  • 使用留一法交叉验证
  • 考虑贝叶斯回归方法
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import RobustScaler

# 完整处理流程
pipeline = make_pipeline(
    RobustScaler(),
    LassoCV(alphas=np.logspace(-4, 0, 50), cv=5)
)
pipeline.fit(X_train, y_train)

6. 行业应用实例

电商价格预测

  • 特征:商品属性、历史价格、竞品数据
  • 挑战:高度相关的价格影响因素
  • 方案:Ridge回归处理共线性

医疗风险评分

  • 特征:数百项体检指标
  • 需求:识别关键风险因素
  • 方案:Lasso进行特征选择

金融信用评估

  • 数据:高维稀疏交易特征
  • 目标:稳定可靠的评分
  • 采用:ElasticNet平衡选择与稳定

在实际项目中,我经常发现数据科学家过早转向复杂算法,而忽视了线性模型的潜力。特别是在以下场景中,正则化线性模型往往能带来惊喜:

  • 中等规模结构化数据(数千到数万样本)
  • 需要快速迭代和解释的MVP阶段
  • 作为更复杂模型的基准参考

更多推荐