本文目录导读:

我来详细讲解如何使用Scikit-learn进行Lasso回归,包括完整的案例代码和解释。
基础Lasso回归案例
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import Lasso
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error, r2_score
# 生成示例数据
np.random.seed(42)
n_samples = 200
n_features = 20
# 创建真实系数(只有前5个特征有用)
true_coef = np.zeros(n_features)
true_coef[:5] = [2, -3, 1, 4, -2]
# 生成数据和噪声
X = np.random.randn(n_samples, n_features)
y = X @ true_coef + np.random.randn(n_samples) * 0.5
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# 标准化特征
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 创建Lasso回归模型
lasso = Lasso(alpha=0.1) # alpha是正则化强度
lasso.fit(X_train_scaled, y_train)
# 预测
y_pred = lasso.predict(X_test_scaled)
# 评估模型
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print("模型评估结果:")
print(f"均方误差 (MSE): {mse:.4f}")
print(f"R² 分数: {r2:.4f}")
print(f"\n特征系数:")
for i, coef in enumerate(lasso.coef_):
if abs(coef) > 0.01:
print(f"特征 {i+1}: {coef:.4f}")
使用交叉验证选择最优Alpha
from sklearn.linear_model import LassoCV
from sklearn.model_selection import cross_val_score
# 使用交叉验证选择最佳alpha
lasso_cv = LassoCV(cv=5, random_state=42)
lasso_cv.fit(X_train_scaled, y_train)
print(f"最优alpha值: {lasso_cv.alpha_:.4f}")
print(f"最优模型R²分数: {lasso_cv.score(X_test_scaled, y_test):.4f}")
# 查看特征选择结果
coef_df = pd.DataFrame({
'feature': [f'Feature_{i}' for i in range(n_features)],
'coefficient': lasso_cv.coef_
})
print("\n非零系数特征:")
print(coef_df[coef_df['coefficient'] != 0])
可视化Lasso回归效果
# 可视化不同alpha值的效果
alphas = np.logspace(-3, 2, 50)
coefs = []
for alpha in alphas:
lasso = Lasso(alpha=alpha, max_iter=10000)
lasso.fit(X_train_scaled, y_train)
coefs.append(lasso.coef_)
# 绘制系数路径图
plt.figure(figsize=(12, 6))
# 子图1:系数路径
plt.subplot(1, 2, 1)
for i in range(n_features):
plt.plot(alphas, [coef[i] for coef in coefs], label=f'Feature {i+1}')
plt.xscale('log')
plt.xlabel('Alpha')
plt.ylabel('Coefficient Value')'Lasso Coefficient Paths')
plt.legend(loc='upper right', ncol=2, fontsize=8)
plt.grid(True, alpha=0.3)
# 子图2:MSE和R²随alpha变化
plt.subplot(1, 2, 2)
mse_scores = []
r2_scores = []
for alpha in alphas:
lasso = Lasso(alpha=alpha, max_iter=10000)
lasso.fit(X_train_scaled, y_train)
y_pred = lasso.predict(X_test_scaled)
mse_scores.append(mean_squared_error(y_test, y_pred))
r2_scores.append(r2_score(y_test, y_pred))
plt.plot(alphas, mse_scores, 'b-', label='MSE')
plt.plot(alphas, r2_scores, 'r-', label='R²')
plt.xscale('log')
plt.xlabel('Alpha')
plt.ylabel('Score')'Model Performance vs Alpha')
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
真实数据案例:波士顿房价预测
# 加载波士顿房价数据集(sklearn 1.2+版本使用fetch_openml)
from sklearn.datasets import fetch_openml
# 加载数据
boston = fetch_openml(name='boston', version=1, as_frame=True)
X_boston = boston.data
y_boston = boston.target
print("波士顿房价数据集信息:")
print(f"样本数: {X_boston.shape[0]}")
print(f"特征数: {X_boston.shape[1]}")
print(f"特征名称: {list(X_boston.columns)}")
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(
X_boston, y_boston, test_size=0.2, random_state=42
)
# 标准化
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# Lasso回归(带交叉验证)
lasso_boston = LassoCV(cv=10, max_iter=10000, random_state=42)
lasso_boston.fit(X_train_scaled, y_train)
print(f"\n最优alpha: {lasso_boston.alpha_:.4f}")
# 评估
y_pred_boston = lasso_boston.predict(X_test_scaled)
print(f"测试集R²分数: {r2_score(y_test, y_pred_boston):.4f}")
print(f"测试集MSE: {mean_squared_error(y_test, y_pred_boston):.4f}")
# 特征重要性
feature_importance = pd.DataFrame({
'feature': list(X_boston.columns),
'coefficient': lasso_boston.coef_
}).sort_values('coefficient', key=abs, ascending=False)
print("\n特征重要性排名:")
print(feature_importance)
Lasso回归参数调优
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import Lasso
# 定义参数网格
param_grid = {
'alpha': np.logspace(-3, 1, 50),
'max_iter': [1000, 5000, 10000],
'tol': [1e-4, 1e-3, 1e-2]
}
# 网格搜索
grid_search = GridSearchCV(
Lasso(random_state=42),
param_grid=param_grid,
cv=5,
scoring='r2',
n_jobs=-1,
verbose=1
)
grid_search.fit(X_train_scaled, y_train)
print("最佳参数组合:")
print(f"alpha: {grid_search.best_params_['alpha']:.4f}")
print(f"max_iter: {grid_search.best_params_['max_iter']}")
print(f"tol: {grid_search.best_params_['tol']}")
print(f"最佳交叉验证分数: {grid_search.best_score_:.4f}")
# 使用最佳模型预测
best_lasso = grid_search.best_estimator_
y_pred_best = best_lasso.predict(X_test_scaled)
print(f"测试集R²分数: {r2_score(y_test, y_pred_best):.4f}")
完整的工作流程示例
def lasso_regression_pipeline(X, y, test_size=0.2, random_state=42):
"""
完整的Lasso回归工作流程
"""
# 1. 数据分割
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=test_size, random_state=random_state
)
# 2. 标准化
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# 3. 模型训练与交叉验证
lasso_cv = LassoCV(cv=5, random_state=random_state, max_iter=10000)
lasso_cv.fit(X_train_scaled, y_train)
# 4. 预测与评估
y_pred_train = lasso_cv.predict(X_train_scaled)
y_pred_test = lasso_cv.predict(X_test_scaled)
results = {
'model': lasso_cv,
'scaler': scaler,
'optimal_alpha': lasso_cv.alpha_,
'train_r2': r2_score(y_train, y_pred_train),
'test_r2': r2_score(y_test, y_pred_test),
'train_mse': mean_squared_error(y_train, y_pred_train),
'test_mse': mean_squared_error(y_test, y_pred_test),
'coefficients': lasso_cv.coef_,
'non_zero_features': np.sum(lasso_cv.coef_ != 0),
'y_pred_train': y_pred_train,
'y_pred_test': y_pred_test,
'y_train': y_train,
'y_test': y_test
}
return results
# 使用完整工作流程
results = lasso_regression_pipeline(X, y)
print("Lasso回归结果摘要:")
print(f"最优Alpha: {results['optimal_alpha']:.4f}")
print(f"训练集R²: {results['train_r2']:.4f}")
print(f"测试集R²: {results['test_r2']:.4f}")
print(f"训练集MSE: {results['train_mse']:.4f}")
print(f"测试集MSE: {results['test_mse']:.4f}")
print(f"非零系数数量: {results['non_zero_features']}/{len(results['coefficients'])}")
关键参数说明
- alpha: L1正则化强度,值越大正则化越强
- max_iter: 最大迭代次数
- tol: 优化算法的容差
- fit_intercept: 是否计算截距
- normalize: 是否在拟合前标准化特征(已弃用,建议使用StandardScaler)
- selection: 坐标下降算法的选择方式('cyclic'或'random')
注意事项
- 特征标准化:Lasso回归对特征尺度敏感,建议先进行标准化
- Alpha选择:使用交叉验证(LassoCV)自动选择最优alpha
- 特征选择:Lasso可以自动进行特征选择,系数为零的特征被忽略
- 多重共线性:当特征高度相关时,Lasso可能随机选择一个
- 大数据集:对于大规模数据,考虑使用Saga或SAG求解器
这个案例涵盖了Lasso回归的主要应用场景和最佳实践,你可以根据具体需求进行调整。