1. 项目概述
Kaggle房价预测竞赛是数据科学领域最经典的入门项目之一。这个项目要求参赛者根据房屋的各种特征(如面积、房龄、地理位置等)来预测最终的销售价格。作为机器学习实践者,我最近完整走了一遍这个项目的流程,从最基础的线性回归模型到更复杂的树模型都进行了尝试。下面我将详细分享整个过程中的技术细节和实战经验。
房价预测本质上是一个回归问题,但不同于简单的教学案例,真实数据集往往存在缺失值、异常值、非数值特征等问题,需要经过仔细的数据清洗和特征工程才能获得好的预测效果。Kaggle提供的这个数据集包含79个解释变量,涵盖了房屋的各个方面,非常适合练习完整的数据科学工作流程。
2. 数据准备与预处理
2.1 数据获取与初步探索
首先从Kaggle比赛页面下载数据集,通常包含:
- train.csv:训练数据,包含特征列和目标变量(SalePrice)
- test.csv:测试数据,只有特征列
- data_description.txt:对每个变量的详细说明
提示:仔细阅读data_description.txt非常重要,它能帮助你理解每个特征的实际含义,避免错误解读。
2.2 数据清洗关键步骤
2.2.1 缺失值处理
真实数据中缺失值很常见,需要根据特征类型采用不同策略:
- 数值特征:用该列均值填充
- 分类特征:单独创建一个"缺失"类别
python复制# 数值特征标准化并填充缺失值
numeric_features = all_features.dtypes[all_features.dtypes != 'object'].index
all_features[numeric_features] = all_features[numeric_features].apply(
lambda x: (x - x.mean()) / (x.std()))
all_features[numeric_features] = all_features[numeric_features].fillna(0)
# 分类特征独热编码
all_features = pd.get_dummies(all_features, dummy_na=True)
2.2.2 特征工程技巧
- 对偏态分布的数值变量取对数
- 创建有意义的组合特征(如总面积=地下室面积+地上面积)
- 对分类变量进行频次编码(将类别替换为该类别在训练集中的平均房价)
3. 模型构建与评估
3.1 基础线性回归模型
3.1.1 模型定义
python复制def get_net():
net = nn.Sequential(nn.Linear(in_features, 1))
return net
3.1.2 特殊损失函数设计
由于房价跨度很大,使用对数RMSE作为评估指标更合理:
python复制def log_rmse(net, features, labels):
clipped_preds = torch.clamp(net(features), 1, float('inf'))
rmse = torch.sqrt(loss(torch.log(clipped_preds),
torch.log(labels)))
return rmse.item()
注意:这里使用torch.clamp将预测值限制在1以上,避免取对数时出现负无穷。
3.2 高级树模型实现
3.2.1 XGBoost模型配置
python复制model_xgb = xgb.XGBRegressor(
learning_rate=0.05,
n_estimators=2000,
max_depth=3,
subsample=0.8,
colsample_bytree=0.8,
objective='reg:squarederror',
random_state=42
)
3.2.2 LightGBM模型配置
python复制model_lgb = lgb.LGBMRegressor(
objective='regression',
learning_rate=0.05,
n_estimators=2000,
max_depth=3,
num_leaves=15,
feature_fraction=0.8,
bagging_fraction=0.8,
bagging_freq=5,
verbose=-1,
random_state=42
)
3.3 模型融合策略
将多个模型的预测结果加权平均,可以进一步提升效果:
python复制# 两个模型各50%权重
blended_preds_log = 0.5 * preds_xgb + 0.5 * preds_lgb
final_preds = np.expm1(blended_preds_log) # 将对数价格转换回原始尺度
4. 完整实现流程
4.1 数据预处理流水线
- 合并训练集和测试集特征
- 处理缺失值
- 标准化数值特征
- 对分类变量进行独热编码
- 重新拆分为训练集和测试集
4.2 模型训练与验证
使用5折交叉验证评估模型表现:
python复制kf = KFold(n_splits=5, shuffle=True, random_state=42)
score_xgb = cv_rmse(model_xgb, train_features, train_labels)
print(f"XGBoost 平均 Log RMSE: {score_xgb.mean():.4f}")
4.3 结果提交
将最终预测结果格式化为Kaggle要求的提交格式:
python复制submission = pd.concat([test_data['Id'], test_data['SalePrice']], axis=1)
submission.to_csv('submission.csv', index=False)
5. 实战经验与技巧
5.1 特征工程中的常见陷阱
- 避免数据泄露:所有特征处理必须在拆分训练集和测试集之前完成
- 分类变量编码时注意:测试集中可能出现训练集未出现的类别
- 对数值特征进行标准化时,要保存训练集的均值和标准差,用于测试集的转换
5.2 模型调参建议
- 先设置较大的学习率(如0.1)快速找到合适的树数量,再减小学习率精细调参
- 使用早停(early stopping)防止过拟合
- 网格搜索结合交叉验证寻找最优参数组合
5.3 性能优化技巧
- 对于大数据集,使用LightGBM比XGBoost训练速度更快
- 将类别变量转换为category类型可以节省内存
- 使用GPU加速XGBoost训练(需安装支持GPU的版本)
6. 进阶方向
完成基础版本后,可以尝试以下改进:
- 更精细的特征工程:
- 创建邻里特征的平均房价
- 提取年份特征中的年代信息
- 尝试深度学习模型:
- 使用TabNet等专门处理表格数据的神经网络
- 构建宽深(Wide & Deep)模型结合记忆和泛化能力
- 集成更多模型:
- 加入CatBoost形成三重集成
- 使用堆叠(Stacking)策略进行模型融合
这个项目虽然看似简单,但涵盖了数据科学项目的完整流程,从数据清洗、特征工程到模型构建和评估,每一步都需要仔细思考和反复迭代。我在实践中发现,特征工程的质量往往比模型选择对最终结果的影响更大。