从线性回归到随机森林:手把手教你用Sklearn优化波士顿房价预测模型(附完整对比代码)

张开发
2026/4/5 20:41:29 15 分钟阅读

分享文章

从线性回归到随机森林:手把手教你用Sklearn优化波士顿房价预测模型(附完整对比代码)
从线性回归到随机森林手把手教你用Sklearn优化波士顿房价预测模型附完整对比代码当你第一次用线性回归模型预测波士顿房价时可能会发现R²分数徘徊在0.6-0.7之间——这意味着模型只能解释60%-70%的价格波动。作为数据科学实践者我们永远在问如何在不增加数据的情况下让模型表现提升20%甚至更多本文将带你完成一次完整的模型升级之旅从基础的线性回归出发通过随机森林实现预测性能的质的飞跃。1. 环境准备与数据探索在开始建模前我们需要确保环境配置正确并充分理解数据特性。波士顿房价数据集包含506个样本每个样本有13个特征变量和1个目标变量房价中位数。这些特征包括CRIM城镇人均犯罪率RM住宅平均房间数LSTAT低收入人群百分比PTRATIO城镇师生比例安装必要库并加载数据# 基础环境配置 import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns from sklearn.datasets import fetch_openml from sklearn.model_selection import train_test_split # 加载数据集 boston fetch_openml(nameboston, version1, as_frameTrue) df pd.DataFrame(boston.data, columnsboston.feature_names) df[PRICE] boston.target数据探索是建模前的关键步骤。通过以下代码快速了解数据分布# 数据概览 print(f数据集形状: {df.shape}) print(\n描述性统计:) print(df.describe().T[[mean, std, min, 50%, max]]) # 缺失值检查 print(\n缺失值统计:) print(df.isnull().sum())特征相关性分析能帮助我们识别重要特征# 特征相关性热力图 plt.figure(figsize(12, 8)) corr_matrix df.corr() sns.heatmap(corr_matrix, annotTrue, fmt.2f, cmapcoolwarm, masknp.triu(np.ones_like(corr_matrix, dtypebool))) plt.title(特征相关性矩阵, pad20) plt.show()注意热力图中与PRICE相关性绝对值大于0.5的特征应重点关注。RM房间数通常显示最强正相关而LSTAT低收入比例则呈现显著负相关。2. 建立基线线性回归模型线性回归作为基准模型能快速建立性能参照点。以下是完整实现流程from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LinearRegression from sklearn.metrics import mean_squared_error, r2_score # 数据预处理 X df.drop(PRICE, axis1) y df[PRICE] X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.2, random_state42) # 特征标准化 scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test) # 建模与评估 lr LinearRegression() lr.fit(X_train_scaled, y_train) y_pred lr.predict(X_test_scaled) # 性能指标 mse mean_squared_error(y_test, y_pred) rmse np.sqrt(mse) r2 r2_score(y_test, y_pred) print(f线性回归性能:\nMSE: {mse:.2f}\nRMSE: {rmse:.2f}\nR²: {r2:.4f})典型输出结果线性回归性能: MSE: 24.29 RMSE: 4.93 R²: 0.6688线性回归的特征重要性可通过系数绝对值体现# 特征重要性可视化 lr_feature_importance pd.DataFrame({ Feature: X.columns, Importance: np.abs(lr.coef_) }).sort_values(Importance, ascendingFalse) plt.figure(figsize(10, 6)) sns.barplot(xImportance, yFeature, datalr_feature_importance) plt.title(线性回归特征重要性系数绝对值) plt.show()3. 升级模型随机森林回归当线性回归表现不佳时随机森林往往能带来显著提升。以下是实现步骤3.1 基础随机森林实现from sklearn.ensemble import RandomForestRegressor # 初始化模型 rf RandomForestRegressor(n_estimators100, random_state42) rf.fit(X_train, y_train) # 注意随机森林不需要特征缩放 # 评估 y_pred_rf rf.predict(X_test) rf_mse mean_squared_error(y_test, y_pred_rf) rf_r2 r2_score(y_test, y_pred_rf) print(f随机森林性能:\nMSE: {rf_mse:.2f}\nR²: {rf_r2:.4f})性能对比指标线性回归基础随机森林MSE24.297.91R²0.66880.89213.2 特征重要性分析随机森林提供了更可靠的特征重要性评估# 随机森林特征重要性 rf_feature_importance pd.DataFrame({ Feature: X.columns, Importance: rf.feature_importances_ }).sort_values(Importance, ascendingFalse) plt.figure(figsize(10, 6)) sns.barplot(xImportance, yFeature, datarf_feature_importance) plt.title(随机森林特征重要性) plt.show()与线性回归对比发现LSTAT在两种模型中都是最重要特征RM的重要性在随机森林中更加突出DIS到就业中心距离的重要性显著提升3.3 可视化预测效果# 预测结果对比 plt.figure(figsize(10, 6)) plt.scatter(y_test, y_pred, alpha0.5, label线性回归) plt.scatter(y_test, y_pred_rf, alpha0.5, label随机森林, colororange) plt.plot([y.min(), y.max()], [y.min(), y.max()], r--) plt.legend() plt.xlabel(实际价格) plt.ylabel(预测价格) plt.title(模型预测效果对比) plt.show()4. 高级优化超参数调优通过网格搜索可以进一步提升模型性能from sklearn.model_selection import GridSearchCV # 参数网格 param_grid { n_estimators: [50, 100, 200], max_depth: [None, 10, 20], min_samples_split: [2, 5], min_samples_leaf: [1, 2] } # 网格搜索 grid_search GridSearchCV( RandomForestRegressor(random_state42), param_grid, cv5, scoringneg_mean_squared_error, n_jobs-1 ) grid_search.fit(X_train, y_train) # 最佳模型 best_rf grid_search.best_estimator_ y_pred_best best_rf.predict(X_test) best_mse mean_squared_error(y_test, y_pred_best) best_r2 r2_score(y_test, y_pred_best) print(f优化后性能:\nMSE: {best_mse:.2f}\nR²: {best_r2:.4f}) print(\n最佳参数组合:) print(grid_search.best_params_)典型优化结果优化后性能: MSE: 7.23 R²: 0.9014 最佳参数组合: {max_depth: 20, min_samples_leaf: 1, min_samples_split: 2, n_estimators: 200}5. 模型部署与使用建议将训练好的模型保存以便后续使用import joblib # 保存模型 joblib.dump(best_rf, boston_rf_model.pkl) # 加载模型 loaded_model joblib.load(boston_rf_model.pkl) # 示例预测 sample X_test.iloc[0:1] prediction loaded_model.predict(sample)[0] print(f\n样本预测:\n输入特征:\n{sample}\n预测价格: ${prediction*1000:.0f})实际应用中的建议数据更新定期用新数据重新训练模型监控建立预测误差监控机制解释性使用SHAP值增强模型可解释性A/B测试新旧模型并行运行对比实际效果# SHAP值计算示例 import shap explainer shap.TreeExplainer(best_rf) shap_values explainer.shap_values(X_test) # 单个预测解释 shap.force_plot(explainer.expected_value, shap_values[0,:], X_test.iloc[0,:])通过这次完整的模型优化旅程我们从R²0.67的线性回归出发最终得到了R²0.90的优化随机森林模型。这种性能提升在实际业务中可能意味着数百万美元的估值差异。

更多文章