从过拟合到精简模型:手把手教你用Lasso回归做特征筛选(Python实战)
从过拟合到精简模型手把手教你用Lasso回归做特征筛选Python实战在机器学习项目中我们常常面临一个棘手的问题当数据集包含大量特征时如何识别哪些特征真正对预测目标有用过多的特征不仅会增加计算成本还容易导致模型过拟合——即在训练集上表现优异但在新数据上泛化能力差。这就是为什么特征选择成为建模流程中不可或缺的一环。Lasso回归Least Absolute Shrinkage and Selection Operator为我们提供了一种优雅的解决方案。与常规线性回归不同Lasso通过在损失函数中添加L1正则化项能够自动将不重要特征的系数压缩至零从而实现特征选择。这种方法特别适合高维数据集比如基因表达数据、金融指标分析或用户行为特征工程。本文将带你深入理解Lasso回归的工作原理并通过Python实战演示如何对比Lasso与普通线性回归、岭回归的特征选择差异可视化正则化路径观察系数变化使用交叉验证确定最佳正则化强度解释筛选后的特征集合1. 理解Lasso回归的核心机制1.1 从线性回归到正则化普通最小二乘线性回归通过最小化残差平方和来估计参数# 普通线性回归的损失函数 def ordinary_least_squares(X, y, theta): return np.sum((y - X.dot(theta))**2)然而当特征之间存在高度相关性或特征数量很多时这种方法的系数估计会变得不稳定。正则化通过在损失函数中添加惩罚项来解决这个问题回归类型正则化项特点岭回归L2 (∑θ²)系数趋近于零但不等于零Lasso回归L1 (∑θ弹性网络L1 L2结合两者优势1.2 L1正则化的数学魅力Lasso的损失函数可以表示为J(θ) ||y - Xθ||² α||θ||₁其中α是控制正则化强度的超参数。L1范数的特殊性质使得优化过程中某些系数会精确变为零这源于其在坐标轴处的尖角特性。相比之下L2正则化的圆形等高线很少会让系数真正为零。注意当α0时Lasso退化为普通线性回归当α→∞时所有系数都被压缩至零2. 准备Python实战环境2.1 工具库配置我们需要以下Python库来实现Lasso回归分析import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.linear_model import Lasso, LassoCV, Ridge from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split from sklearn.metrics import mean_squared_error2.2 构建模拟数据集为了更好地理解Lasso的特性我们首先生成一个模拟数据集np.random.seed(42) n_samples, n_features 100, 20 X np.random.randn(n_samples, n_features) # 只让5个特征真正有影响 true_coef np.zeros(n_features) true_coef[[1, 5, 10, 15, 18]] [4, -3, 2, -1, 0.5] y X.dot(true_coef) np.random.normal(0, 1, n_samples) X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.3)这个数据集中虽然总共有20个特征但实际上只有5个对目标变量有真实影响这为我们验证Lasso的特征选择能力提供了理想场景。3. 实施Lasso回归分析3.1 正则化路径可视化观察不同α值下系数变化是理解Lasso行为的关键alphas np.logspace(-4, 1, 100) coefs [] for a in alphas: lasso Lasso(alphaa, max_iter10000) lasso.fit(X_train, y_train) coefs.append(lasso.coef_) plt.figure(figsize(10, 6)) ax plt.gca() ax.plot(alphas, coefs) ax.set_xscale(log) plt.xlabel(Alpha (log scale)) plt.ylabel(Coefficients) plt.title(Lasso Regularization Path) plt.show()这张图展示了随着α增大各个特征系数如何逐渐被压缩至零。理想情况下无关特征的系数会率先归零。3.2 交叉验证选择最优α使用LassoCV可以自动寻找最佳的正则化强度lasso_cv LassoCV(alphasalphas, cv5, max_iter10000) lasso_cv.fit(X_train, y_train) print(fOptimal alpha: {lasso_cv.alpha_:.4f})交叉验证过程会评估不同α值下模型的性能选择在验证集上表现最好的那个。我们可以查看最终选中的α值对应的模型表现y_pred lasso_cv.predict(X_test) mse mean_squared_error(y_test, y_pred) print(fTest MSE: {mse:.4f})3.3 特征选择结果分析让我们看看Lasso筛选出的特征集合selected_features np.where(lasso_cv.coef_ ! 0)[0] print(Selected feature indices:, selected_features) print(True influential features:, np.where(true_coef ! 0)[0])在理想情况下Lasso应该能准确识别出我们预设的5个重要特征。实践中可能会有些偏差但通常会非常接近真实情况。4. Lasso与岭回归的实战对比4.1 系数收缩模式比较为了直观展示Lasso和岭回归的区别我们可以对比两者的系数ridge Ridge(alphalasso_cv.alpha_) ridge.fit(X_train, y_train) plt.figure(figsize(10, 5)) plt.subplot(121) plt.stem(lasso_cv.coef_) plt.title(Lasso Coefficients) plt.subplot(122) plt.stem(ridge.coef_) plt.title(Ridge Coefficients) plt.tight_layout() plt.show()这个对比图清晰地展示了Lasso产生了稀疏解许多系数精确为零岭回归虽然缩小了系数但很少完全归零4.2 预测性能比较虽然Lasso的主要优势在于特征选择但我们也应该评估其预测性能ridge_pred ridge.predict(X_test) ridge_mse mean_squared_error(y_test, ridge_pred) print(fLasso Test MSE: {mse:.4f}) print(fRidge Test MSE: {ridge_mse:.4f})在高维稀疏场景下Lasso通常会优于岭回归而当大多数特征都相关时岭回归可能表现更好。5. 高级技巧与最佳实践5.1 标准化的重要性由于L1正则化对系数大小敏感特征标准化至关重要scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test) lasso Lasso(alphalasso_cv.alpha_) lasso.fit(X_train_scaled, y_train)5.2 处理高度相关特征当特征高度相关时Lasso倾向于随机选择其中一个。弹性网络Elastic Net可以缓解这个问题from sklearn.linear_model import ElasticNetCV en ElasticNetCV(l1_ratio0.5) # 混合L1和L2 en.fit(X_train_scaled, y_train)5.3 实际案例波士顿房价预测让我们用经典数据集验证Lasso的实际效果from sklearn.datasets import load_boston boston load_boston() X, y boston.data, boston.target lasso_boston LassoCV(alphasnp.logspace(-3, 1, 100)) lasso_boston.fit(X, y) print(Selected features:, np.where(lasso_boston.coef_ ! 0)[0]) print(Feature names:, np.array(boston.feature_names)[lasso_boston.coef_ ! 0])这个案例展示了Lasso如何帮助我们识别对房价预测真正重要的房屋特征。