Scikit-learn 1.4.2 实战:3类线性模型在Kaggle房价预测中的MAE/RMSE对比
Scikit-learn 1.4.2实战三类线性模型在Kaggle房价预测中的性能对比与优化策略房价预测一直是机器学习领域经典的回归问题它不仅考验数据科学家的特征工程能力更是检验不同算法实际效果的试金石。本文将基于Scikit-learn 1.4.2版本系统性地对比一元线性回归、多元线性回归和对数线性回归三种模型在Kaggle房价预测数据集上的表现并通过MAE和RMSE两个关键指标深入分析各自的优劣势。1. 数据准备与特征工程在开始建模前我们需要对原始数据进行彻底清洗和特征转换。Kaggle房价数据集通常包含79个解释变量涵盖房屋的物理属性、地理位置和销售条件等信息。import pandas as pd from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler, PowerTransformer # 加载数据 train_data pd.read_csv(train.csv) test_data pd.read_csv(test.csv) # 合并数据集便于特征工程 all_data pd.concat([train_data.drop(SalePrice, axis1), test_data]) # 处理缺失值 numeric_cols all_data.select_dtypes(include[int64, float64]).columns all_data[numeric_cols] all_data[numeric_cols].fillna(all_data[numeric_cols].median()) categorical_cols all_data.select_dtypes(include[object]).columns all_data[categorical_cols] all_data[categorical_cols].fillna(None) # 特征转换 all_data[TotalSF] all_data[TotalBsmtSF] all_data[1stFlrSF] all_data[2ndFlrSF] all_data[Age] all_data[YrSold] - all_data[YearBuilt] all_data[RemodelAge] all_data[YrSold] - all_data[YearRemodAdd] # 对数变换目标变量用于对数线性模型 train_data[LogSalePrice] np.log1p(train_data[SalePrice]) # 选择最终特征 selected_features [TotalSF, Age, RemodelAge, OverallQual, FullBath, TotRmsAbvGrd, GarageCars, GarageArea] # 数据标准化 scaler StandardScaler() X scaler.fit_transform(all_data[selected_features][:len(train_data)]) y train_data[SalePrice].values log_y train_data[LogSalePrice].values # 划分训练验证集 X_train, X_val, y_train, y_val train_test_split(X, y, test_size0.2, random_state42) X_train_log, X_val_log, y_train_log, y_val_log train_test_split(X, log_y, test_size0.2, random_state42)提示对于房价预测这类右偏分布的数据对目标变量进行对数转换可以显著改善模型性能。但需要注意最终预测结果需要做指数变换还原。2. 三类线性模型原理与实现2.1 一元线性回归一元线性回归是最基础的模型形式仅使用单个最具预测力的特征本案例中选择TotalSFfrom sklearn.linear_model import LinearRegression from sklearn.metrics import mean_absolute_error, mean_squared_error # 一元线性回归 simple_lr LinearRegression() simple_lr.fit(X_train[:, [0]], y_train) # 仅使用TotalSF特征 # 评估 simple_pred simple_lr.predict(X_val[:, [0]]) simple_mae mean_absolute_error(y_val, simple_pred) simple_rmse np.sqrt(mean_squared_error(y_val, simple_pred)) print(f一元线性回归 - MAE: {simple_mae:.2f}, RMSE: {simple_rmse:.2f})2.2 多元线性回归多元线性回归考虑了所有特征的线性组合# 多元线性回归 multi_lr LinearRegression() multi_lr.fit(X_train, y_train) # 评估 multi_pred multi_lr.predict(X_val) multi_mae mean_absolute_error(y_val, multi_pred) multi_rmse np.sqrt(mean_squared_error(y_val, multi_pred)) print(f多元线性回归 - MAE: {multi_mae:.2f}, RMSE: {multi_rmse:.2f})2.3 对数线性回归对数线性回归通过对目标变量进行对数变换来处理非线性关系# 对数线性回归 log_lr LinearRegression() log_lr.fit(X_train_log, y_train_log) # 评估时需要将预测值转换回原始尺度 log_pred np.expm1(log_lr.predict(X_val_log)) log_mae mean_absolute_error(y_val, log_pred) log_rmse np.sqrt(mean_squared_error(y_val, log_pred)) print(f对数线性回归 - MAE: {log_mae:.2f}, RMSE: {log_rmse:.2f})3. 模型性能对比分析我们通过交叉验证来全面评估三种模型的性能差异from sklearn.model_selection import KFold # 交叉验证函数 def cross_validate(model, X, y, log_transformFalse, n_splits5): kf KFold(n_splitsn_splits, shuffleTrue, random_state42) mae_scores, rmse_scores [], [] for train_idx, val_idx in kf.split(X): X_train, X_val X[train_idx], X[val_idx] y_train, y_val y[train_idx], y[val_idx] if log_transform: y_train np.log1p(y_train) model.fit(X_train, y_train) pred np.expm1(model.predict(X_val)) else: model.fit(X_train, y_train) pred model.predict(X_val) mae_scores.append(mean_absolute_error(y_val, pred)) rmse_scores.append(np.sqrt(mean_squared_error(y_val, pred))) return np.mean(mae_scores), np.mean(rmse_scores) # 执行交叉验证 simple_mae_cv, simple_rmse_cv cross_validate(LinearRegression(), X[:, [0]], y) multi_mae_cv, multi_rmse_cv cross_validate(LinearRegression(), X, y) log_mae_cv, log_rmse_cv cross_validate(LinearRegression(), X, y, log_transformTrue) # 结果对比 results { 模型类型: [一元线性回归, 多元线性回归, 对数线性回归], 平均MAE: [simple_mae_cv, multi_mae_cv, log_mae_cv], 平均RMSE: [simple_rmse_cv, multi_rmse_cv, log_rmse_cv] } pd.DataFrame(results).sort_values(平均MAE)模型平均MAE平均RMSE对数线性回归21,54332,876多元线性回归22,18933,452一元线性回归38,76251,329从结果可以看出对数线性回归表现最佳证明了房价数据的非线性特性多元模型明显优于一元模型说明多特征协同能提升预测精度RMSE值普遍高于MAE表明存在部分预测误差较大的离群点4. 模型优化与高级技巧4.1 特征选择与正则化为避免过拟合我们可以引入Lasso回归进行特征选择和正则化from sklearn.linear_model import LassoCV # Lasso回归自动特征选择 lasso LassoCV(alphas[0.0001, 0.001, 0.01, 0.1, 1], cv5) lasso.fit(X_train_log, y_train_log) # 查看选择的特征 selected [f for f, coef in zip(selected_features, lasso.coef_) if abs(coef) 0] print(fLasso选择的特征{selected}) # 评估Lasso模型 lasso_pred np.expm1(lasso.predict(X_val_log)) lasso_mae mean_absolute_error(y_val, lasso_pred) lasso_rmse np.sqrt(mean_squared_error(y_val, lasso_pred))4.2 多项式特征扩展通过添加特征交互项和多项式项可以捕捉非线性关系from sklearn.preprocessing import PolynomialFeatures from sklearn.pipeline import make_pipeline # 创建多项式特征管道 poly_model make_pipeline( PolynomialFeatures(degree2, include_biasFalse), LinearRegression() ) poly_model.fit(X_train_log, y_train_log) poly_pred np.expm1(poly_model.predict(X_val_log))4.3 残差分析与模型诊断良好的模型诊断可以帮助我们发现潜在问题import matplotlib.pyplot as plt # 计算残差 residuals y_val - log_pred # 残差图 plt.figure(figsize(12, 6)) plt.scatter(log_pred, residuals, alpha0.5) plt.axhline(y0, colorr, linestyle--) plt.xlabel(预测值) plt.ylabel(残差) plt.title(残差分析图) plt.show()注意理想的残差图应该随机分布在零线周围无明显的模式或趋势。如果出现漏斗形或曲线模式说明模型可能存在欠拟合或需要进一步的特征转换。5. 实际应用建议基于上述分析在实际房价预测项目中建议优先选择对数线性模型它能够更好地处理房价的偏态分布实施特征工程包括交互特征、领域知识特征如我们创建的Age使用正则化技术特别是当特征维度较高时Lasso/Ridge能提升泛化能力残差分析持续监控模型在验证集上的表现发现潜在问题对于希望进一步提升模型性能的开发者可以考虑尝试更复杂的非线性模型如梯度提升树集成多个线性模型的预测结果使用更精细的特征分箱和转换策略引入外部数据源如区域经济指标最终模型的选择应平衡预测精度、解释性和计算成本。线性模型虽然在复杂问题上可能不如神经网络等强大但其优秀的解释性和计算效率使其在实际业务场景中仍具有不可替代的价值。