当前位置: 首页 > news >正文

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', axis=1), 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_size=0.2, random_state=42) X_train_log, X_val_log, y_train_log, y_val_log = train_test_split(X, log_y, test_size=0.2, random_state=42)

提示:对于房价预测这类右偏分布的数据,对目标变量进行对数转换可以显著改善模型性能。但需要注意最终预测结果需要做指数变换还原。

2. 三类线性模型原理与实现

2.1 一元线性回归

一元线性回归是最基础的模型形式,仅使用单个最具预测力的特征(本案例中选择'TotalSF'):

from 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_transform=False, n_splits=5): kf = KFold(n_splits=n_splits, shuffle=True, random_state=42) 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_transform=True) # 结果对比 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], cv=5) lasso.fit(X_train_log, y_train_log) # 查看选择的特征 selected = [f for f, coef in zip(selected_features, lasso.coef_) if abs(coef) > 0] print(f"Lasso选择的特征:{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(degree=2, include_bias=False), 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, alpha=0.5) plt.axhline(y=0, color='r', linestyle='--') plt.xlabel('预测值') plt.ylabel('残差') plt.title('残差分析图') plt.show()

注意:理想的残差图应该随机分布在零线周围,无明显的模式或趋势。如果出现漏斗形或曲线模式,说明模型可能存在欠拟合或需要进一步的特征转换。

5. 实际应用建议

基于上述分析,在实际房价预测项目中建议:

  1. 优先选择对数线性模型:它能够更好地处理房价的偏态分布
  2. 实施特征工程:包括交互特征、领域知识特征(如我们创建的'Age')
  3. 使用正则化技术:特别是当特征维度较高时,Lasso/Ridge能提升泛化能力
  4. 残差分析:持续监控模型在验证集上的表现,发现潜在问题

对于希望进一步提升模型性能的开发者,可以考虑:

  • 尝试更复杂的非线性模型(如梯度提升树)
  • 集成多个线性模型的预测结果
  • 使用更精细的特征分箱和转换策略
  • 引入外部数据源(如区域经济指标)

最终模型的选择应平衡预测精度、解释性和计算成本。线性模型虽然在复杂问题上可能不如神经网络等强大,但其优秀的解释性和计算效率使其在实际业务场景中仍具有不可替代的价值。

http://www.jsqmd.com/news/1137735/

相关文章:

  • GA事件100%采集方案:IndexedDB+Cloudflare Worker四层防御架构
  • Linux 文件描述符泄漏排查:从 /proc/<pid>/fd 分析到 lsof 命令的 5 步定位法
  • Control Rig vs Additive动画:3个维度对比UE5角色受击方案性能与灵活性
  • Windows 10 蓝屏分析实战:WinDbg 定位 condrv.sys 空指针访问(附完整 POC)
  • 微信取证 v8.0.47:3种账号标识(wxid_/微信号/昵称)的数据库定位与解析
  • AWS Well-Architected自评估:架构健康体检而非KPI考核
  • 移动硬盘 Ubuntu 22.04 即插即用:3步配置实现跨电脑启动引导
  • LlamaIndex 0.10.12 构建《The World House》知识库:5步实现语义检索与主题分析
  • 一文讲透 Agent Skill 的原理与实践
  • 3分钟GPU显存稳定性检测:你的显卡真的健康吗?
  • Alpine Linux 3.19 部署 Xfce 4.18:3步配置中文环境与字体,解决乱码问题
  • Halcon 深度学习目标检测:3种常见报错(CUDA OOM/标注不匹配/推理异常)排查指南
  • 竞品分析软件哪个性价比高?2026年实战问答与工具对比
  • 5分钟上手pytest:Python单元测试快速入门与实战技巧
  • Avo 4 正式发布!聚焦信息密度与操作效率,新增功能多但订阅制引争议
  • 揭秘4.4万条高质量AI提示词库:从原理到实战的工程化指南
  • Ubuntu 22.04 闲置笔记本变服务器:SSH + Apache 2.4 部署与内网穿透 3 步配置
  • Julia高性能计算入门:从语法陷阱到生产级优化
  • Linux 内核 I/O 子系统实战:从 write() 调用到磁盘中断的 5 层追踪
  • 3种Unity雷达图方案对比:UGUI Mesh、Shader与Asset Store插件性能实测
  • GPT-4o 文本分析实战:从《Two Kinds》看3种情感冲突的NLP识别与可视化
  • 从向量数据库到统一 AI API:为什么我现在更倾向用“向量引擎”做应用接入层?
  • AI Agent虚拟社会构建:从多智能体系统到自主交互小镇的实现
  • Android证书移动全攻略:从手动安装到自动化脚本部署
  • MySQL 8.0 多字段排序实战:3种场景解析与性能影响分析
  • SaltStack核心原理:ZeroMQ架构与声明式状态管理
  • Unity C# 层次状态机HSM实战:3层状态嵌套实现角色复杂行为逻辑
  • kmpi未来展望:消息传递技术在HPC领域的发展趋势
  • Monaspace字体革命:从等宽束缚到智能排版的艺术突破
  • AI安全靶场实战指南:从零构建大模型攻防演练环境