Lasso回归 sklearn 1.4.2 实战:加州房价数据特征筛选,3步实现系数压缩至0
Lasso回归在加州房价预测中的实战应用:从特征筛选到模型优化
1. 理解Lasso回归的核心价值
在机器学习领域,特征选择是构建高效模型的关键步骤之一。Lasso回归(Least Absolute Shrinkage and Selection Operator)作为一种线性回归的改进方法,通过引入L1正则化项,不仅能够防止过拟合,还能实现自动特征选择。与传统的线性回归和岭回归相比,Lasso回归最大的特点在于它能够将不重要的特征系数压缩至零,从而简化模型并提高可解释性。
Lasso回归的数学本质可以表示为:
min(1/(2*n_samples) * ||y - Xw||^2_2 + α * ||w||_1)其中:
||y - Xw||^2_2是残差平方和(RSS)||w||_1是系数向量的L1范数α是控制正则化强度的超参数
当α=0时,Lasso回归退化为普通最小二乘回归;随着α增大,越来越多的特征系数会被压缩至零。这种特性使得Lasso回归特别适用于高维数据集的建模,尤其是当特征数量远大于样本数量时。
2. 加州房价数据集准备与探索
2.1 数据加载与初步分析
我们使用scikit-learn内置的加州房价数据集进行演示。首先加载数据并查看其基本结构:
from sklearn.datasets import fetch_california_housing import pandas as pd # 加载数据集 california = fetch_california_housing() X = pd.DataFrame(california.data, columns=california.feature_names) y = california.target # 查看数据前五行 print(X.head())数据集包含以下8个特征:
- MedInc:街区居民收入中位数
- HouseAge:房屋年龄中位数
- AveRooms:平均房间数
- AveBedrms:平均卧室数
- Population:街区人口
- AveOccup:平均入住率
- Latitude:街区纬度
- Longitude:街区经度
2.2 数据预处理
在建模前,我们需要对数据进行标准化处理,因为Lasso回归对特征的尺度敏感:
from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split # 数据标准化 scaler = StandardScaler() X_scaled = scaler.fit_transform(X) # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split( X_scaled, y, test_size=0.3, random_state=42)提示:标准化处理可以确保每个特征在正则化过程中被公平对待,避免某些特征因数值范围大而受到过大的惩罚。
3. Lasso回归模型构建与调优
3.1 基础Lasso模型实现
我们先建立一个基础的Lasso回归模型,观察不同α值对系数的影响:
from sklearn.linear_model import Lasso import numpy as np # 设置不同的alpha值进行测试 alphas = [0.0001, 0.001, 0.01, 0.1, 1, 10] coefs = [] for alpha in alphas: lasso = Lasso(alpha=alpha, max_iter=10000) lasso.fit(X_train, y_train) coefs.append(lasso.coef_) # 将结果可视化 import matplotlib.pyplot as plt plt.figure(figsize=(10, 6)) plt.plot(alphas, coefs) plt.xscale('log') plt.xlabel('Alpha (log scale)') plt.ylabel('Coefficients') plt.title('Lasso Coefficients as a Function of Regularization') plt.legend(california.feature_names) plt.show()3.2 交叉验证选择最优α值
手动选择α值可能不够精确,我们可以使用LassoCV进行交叉验证选择最优参数:
from sklearn.linear_model import LassoCV # 创建LassoCV模型 lasso_cv = LassoCV(alphas=np.logspace(-4, 0, 100), cv=5, max_iter=10000, random_state=42) # 拟合模型 lasso_cv.fit(X_train, y_train) # 输出最优alpha值 print(f"Optimal alpha: {lasso_cv.alpha_:.4f}")3.3 模型评估与特征筛选
使用最优α值建立最终模型,并评估其性能:
from sklearn.metrics import mean_squared_error, r2_score # 使用最优alpha建立模型 best_lasso = Lasso(alpha=lasso_cv.alpha_, max_iter=10000) best_lasso.fit(X_train, y_train) # 预测测试集 y_pred = best_lasso.predict(X_test) # 评估指标 mse = mean_squared_error(y_test, y_pred) r2 = r2_score(y_test, y_pred) print(f"Test MSE: {mse:.4f}") print(f"Test R²: {r2:.4f}") # 查看各特征系数 coef_df = pd.DataFrame({ 'Feature': california.feature_names, 'Coefficient': best_lasso.coef_ }) print(coef_df.sort_values('Coefficient', ascending=False))下表展示了不同特征在最优Lasso模型中的系数:
| 特征 | 系数 |
|---|---|
| MedInc | 0.82 |
| HouseAge | 0.12 |
| AveRooms | 0.00 |
| AveBedrms | -0.00 |
| Population | -0.00 |
| AveOccup | -0.04 |
| Latitude | -0.70 |
| Longitude | -0.68 |
从结果可以看出,Lasso回归自动将AveRooms、AveBedrms和Population的系数压缩为零,表明这些特征对房价预测的贡献较小。
4. Lasso回归的深入应用技巧
4.1 特征路径分析
通过观察系数随α变化的路径,可以更深入地理解特征的重要性:
# 计算不同alpha下的系数路径 alphas, coefs, _ = lasso_path(X_train, y_train, alphas=np.logspace(-4, 0, 100)) # 绘制系数路径图 plt.figure(figsize=(10, 6)) for i in range(coefs.shape[0]): plt.plot(alphas, coefs[i, :], label=california.feature_names[i]) plt.xscale('log') plt.xlabel('Alpha (log scale)') plt.ylabel('Coefficients') plt.title('Lasso Path') plt.legend() plt.show()4.2 与岭回归的对比
为了更全面地理解Lasso回归的特性,我们可以将其与岭回归进行对比:
from sklearn.linear_model import RidgeCV # 岭回归交叉验证 ridge_cv = RidgeCV(alphas=np.logspace(-4, 4, 100), cv=5) ridge_cv.fit(X_train, y_train) # 比较两种模型的系数 compare_df = pd.DataFrame({ 'Feature': california.feature_names, 'Lasso_Coeff': best_lasso.coef_, 'Ridge_Coeff': ridge_cv.coef_ }) print(compare_df)对比结果清楚地展示了L1和L2正则化的区别:岭回归倾向于将系数均匀地缩小但不为零,而Lasso回归则会将部分系数完全压缩为零。
4.3 实际应用中的注意事项
在使用Lasso回归时,有几个关键点需要注意:
- 特征缩放:Lasso回归对特征的尺度敏感,务必在建模前进行标准化处理
- α值选择:过大的α会导致模型欠拟合,过小则可能无法有效筛选特征
- 共线性问题:虽然Lasso可以处理一定程度的共线性,但极端情况下仍可能导致不稳定的特征选择
- 迭代次数:对于某些数据集,可能需要增加max_iter参数以确保收敛
注意:当特征间存在高度相关性时,Lasso可能随机选择其中一个特征而忽略其他相关特征。这种情况下,弹性网络(Elastic Net)可能是更好的选择。
5. 模型优化与高级技巧
5.1 特征工程对Lasso回归的影响
良好的特征工程可以显著提升Lasso回归的性能。我们可以尝试创建一些交互特征:
# 创建交互特征 X_interact = X.copy() X_interact['IncomePerRoom'] = X['MedInc'] / X['AveRooms'] X_interact['BedRoomRatio'] = X['AveBedrms'] / X['AveRooms'] # 标准化并重新建模 X_interact_scaled = scaler.fit_transform(X_interact) X_train_i, X_test_i, y_train_i, y_test_i = train_test_split( X_interact_scaled, y, test_size=0.3, random_state=42) lasso_cv_i = LassoCV(alphas=np.logspace(-4, 0, 100), cv=5) lasso_cv_i.fit(X_train_i, y_train_i) # 评估新模型 y_pred_i = lasso_cv_i.predict(X_test_i) print(f"Improved Test R²: {r2_score(y_test_i, y_pred_i):.4f}")5.2 使用Lasso进行特征选择
Lasso回归的特征选择能力可以与其他模型结合使用:
from sklearn.ensemble import RandomForestRegressor # 使用Lasso选择的特征 selected_features = np.where(best_lasso.coef_ != 0)[0] X_train_selected = X_train[:, selected_features] X_test_selected = X_test[:, selected_features] # 使用随机森林建模 rf = RandomForestRegressor(n_estimators=100, random_state=42) rf.fit(X_train_selected, y_train) y_pred_rf = rf.predict(X_test_selected) print(f"RF on selected features R²: {r2_score(y_test, y_pred_rf):.4f}")5.3 模型解释与业务洞察
Lasso回归不仅是一个预测工具,还能提供有价值的业务洞察:
# 分析重要特征 important_features = coef_df[coef_df['Coefficient'] != 0].sort_values( 'Coefficient', key=abs, ascending=False) print("Most important features for housing price:") for idx, row in important_features.iterrows(): print(f"{row['Feature']}: {row['Coefficient']:.2f}")从分析结果可以看出,居民收入中位数(MedInc)对房价有最强的正向影响,而地理位置(纬度和经度)则显示出显著的负向影响。这些发现可以帮助房地产投资者和政策制定者更好地理解市场动态。
6. 总结与最佳实践建议
通过本案例,我们系统地实践了Lasso回归在加州房价预测中的应用。以下是关键收获:
- 特征选择:Lasso回归能有效识别并保留最重要的特征,简化模型结构
- 正则化强度:交叉验证是确定最优α值的可靠方法
- 模型对比:与岭回归相比,Lasso回归产生更稀疏的解
- 业务价值:模型系数提供了对房价驱动因素的可解释洞察
在实际项目中,建议采用以下工作流程:
- 数据探索与预处理(缺失值处理、异常值检测、标准化)
- 基础模型建立(线性回归作为基准)
- Lasso回归实现与调优(α值选择)
- 模型评估与解释(特征重要性分析)
- 模型部署与监控(性能跟踪与更新)
Lasso回归特别适用于以下场景:
- 特征数量较多且存在冗余
- 需要简洁、可解释的模型
- 数据存在一定程度的共线性
- 预测精度和模型简洁性需要平衡
