You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用LightGBM进行房价回归时RMSE过高的问题排查及优化

房价预测模型误差异常过高问题排查

问题背景

使用比利时房产数据集,目标是通过房屋面积、房间数、邮政编码等特征预测price列,但训练LightGBM模型后得到的误差值(6053845952.2186775)异常偏高,需排查原因并解决。

我的操作步骤

  1. 加载数据
workspace = Workspace(subscription_id, resource_group, workspace_name)

dataset = Dataset.get_by_name(workspace, name='BelgiumRealEstate')
data  = dataset.to_pandas_dataframe()

data.sample(5)

数据样例:

Column1postal_codecity_nametype_of_propertypricenumber_of_roomshouse_areafully_equipped_kitchenopen_fireterracegardensurface_of_the_landnumber_of_facadesswimming_poolstate_of_the_buildinglattitudelongitudeprovinceregion
335809850Landegem138000031271010000as new3.58880951.054637Flandre-OrientaleFlandre
115769000Gent13190002891010020as new3.71415551.039713Flandre-OrientaleFlandre
128303300Bost01700003140101116020to renovate4.93392450.784632Brabant flamandFlandre
207366880Cugnon027000042180000300040unknown5.20330849.802043LuxembourgWallonie
114169000Gent087500062321001020good3.71415551.039713Flandre-OrientaleFlandre
  1. 类别特征独热编码
one_hot_state_of_the_building = pd.get_dummies(data.state_of_the_building) 
one_hot_city = pd.get_dummies(data.city_name, prefix='city')
one_hot_province = pd.get_dummies(data.province, prefix='province')
one_hot_region = pd.get_dummies(data.region, prefix="region")
  1. 合并编码特征
# 移除原类别特征
data.drop(['city_name','state_of_the_building','province','region'], axis=1, inplace=True) 

# 合并编码后特征
data = pd.concat([data, one_hot_city, one_hot_state_of_the_building, one_hot_province, one_hot_region], axis=1) 
  1. 划分特征与标签
x = data.drop('price', axis=1) 
y = data.price
  1. 划分训练集与测试集
from sklearn.model_selection import train_test_split 
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=.3)
  1. 训练LightGBM模型
x_df = DataFrame(x, columns= data.columns)
x_train, x_test, y_train, y_test = train_test_split(x_df, y, test_size=0.15)

# 转换为LightGBM数据集格式
d_train = lgb.Dataset(x_train, label=y_train)

# 模型参数
params = {
    'task': 'train', 
    'boosting': 'gbdt',
    'objective': 'regression',
    'num_leaves': 10,
    'learnnig_rate': 0.05,
    'metric': {'l2','l1'},
    'verbose': -1
}

# 训练模型
clf = lgb.train(params, d_train, 10000)

# 预测
y_pred = clf.predict(x_test)

# 计算误差
mean_squared_error(y_pred, y_test)

问题分析与解决建议

1. 误差计算混淆:MSE vs RMSE

你当前计算的是均方误差(MSE),而非预期的均方根误差(RMSE)。房价本身是几十万级别的数值,MSE是误差的平方,因此数值会异常大。正确的RMSE计算需要对MSE开根号:

import numpy as np
rmse = np.sqrt(mean_squared_error(y_pred, y_test))

2. 训练集/测试集重复划分+特征构造错误

  • 步骤5已经完成训练集与测试集的划分,但步骤6又重新执行train_test_split,打乱了原有划分逻辑。
  • x_df = DataFrame(x, columns= data.columns)存在严重错误:x是去掉price后的特征集,而data.columns包含price列,导致x_df新增一列全为NaN的price无效特征,直接干扰模型训练。

修正方案:直接使用步骤5划分好的数据集,无需重新构造x_df:

# 替换步骤6的代码
d_train = lgb.Dataset(x_train, label=y_train)

params = {
    'task': 'train', 
    'boosting': 'gbdt',
    'objective': 'regression',
    'num_leaves': 10,
    'learning_rate': 0.05,  # 修正拼写错误
    'metric': {'l2','l1'},
    'verbose': 1  # 打开日志监控训练过程
}

# 添加早停机制防止过拟合
clf = lgb.train(params, d_train, 10000, valid_sets=[lgb.Dataset(x_test, label=y_test)], early_stopping_rounds=50)

y_pred = clf.predict(x_test, num_iteration=clf.best_iteration)
rmse = np.sqrt(mean_squared_error(y_pred, y_test))

3. 参数拼写错误

learnnig_rate应为learning_rate,少了字母r导致该参数未生效,模型使用默认学习率(0.1),可能引发训练不稳定。

4. 冗余与无效特征处理

  • Column1是重复的行索引,无预测价值,数据加载后应删除:
data.drop('Column1', axis=1, inplace=True)
  • postal_code被当作连续特征处理,但本质是类别特征,建议用目标编码或嵌入编码替代,避免独热编码的维度爆炸问题。

5. 高基数类别特征编码优化

city_name属于高基数类别(城市数量多),独热编码会导致特征维度急剧增加,引发维度灾难。建议改用LightGBM原生类别特征支持:

# 恢复原类别列,设为类别类型
data['city_name'] = data['city_name'].astype('category')
data['province'] = data['province'].astype('category')
data['region'] = data['region'].astype('category')
data['state_of_the_building'] = data['state_of_the_building'].astype('category')

# 训练时指定类别特征参数
params['categorical_feature'] = ['city_name', 'province', 'region', 'state_of_the_building']

6. 数据异常值过滤

检查price、house_area等特征的极端值,用四分位数法过滤:

# 过滤房价极端值
q1 = data['price'].quantile(0.01)
q3 = data['price'].quantile(0.99)
data = data[(data['price'] >= q1) & (data['price'] <= q3)]

内容的提问来源于stack exchange,提问作者Luis Valencia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 12:15:42