终于有空了,打打趣味赛提升一下编码能力,这一篇先不做特征工程,只选择不同模型进行初步测试

赛题简介

这次比赛的主题是:根据给定的数据集,预测交通事故的发生率,结果要求是0到1之间的概率值。

比赛传送门: Predicting Road Accident Risk

这是一个典型的回归(Regression)问题,评估指标是RMSE(均方根误差),分数越低越好。

数据维度很低,训练集大概几十万行,包含13个特征和一个目标变量(accident_risk)。

数据分析及基线确定(EDA & baseline)

1.初步探索

df.head()查看一下数据前五行,了解一下特征和目标变量的分布。

id road_type num_lanes curvature speed_limit lighting weather road_signs_present public_road time_of_day holiday school_season num_reported_accidents accident_risk
0 urban 2 0.06 35 daylight rainy False True afternoon False True 1 0.13
1 urban 4 0.99 35 daylight clear True False evening True True 0 0.35
2 rural 4 0.63 70 dim clear False True morning True False 2 0.30
3 highway 4 0.07 35 dim rainy True True morning False False 1 0.21
4 rural 1 0.58 60 daylight foggy False False evening True False 1 0.56

初步可以分为两大类:

  1. 数值特征:num_lanes, curvature, speed_limit, num_reported_accidents
  2. 分类特征:road_type, lighting, weather, road_signs_present, public_road, time_of_day, holiday, school_season

2.基线确定

不用带脑子,直接用平均值作为基线模型。

1
2
# 计算训练集中 accident_risk 的平均值
average_risk = train_data['accident_risk'].mean()

提交后的分数为0.16603,后续任何模型的分数都必须显著低于这个值才有意义

机器学习模型选取

数据集为典型的表格型数据,故选取树模型进行测试。

1.数据预处理

机器学习模型一般都需要以数值形式输入,因而要对类别特征进行特殊处理。

对于LightGBM新版XGBoost,最方便的是直接用df[cat_cols].astype('category')转换类型。如果是Random Forest旧XGBoost,则需要LabelEncoder

Random Forest

先使用Random Forest探探路,虽然效果肯定是不如Gradient Boost的,但可以作为一个新的baseline。

1
2
3
4
from sklearn.ensemble import RandomForestRegressor
rf_model = RandomForestRegressor(n_estimators=100, random_state=42, n_jobs=-1)
rf_model.fit(x_train_encoded, y_train)
predictions_rf = rf_model.predict(x_test_encoded)

提交后分数迅速来到0.05913,效果显著,但和排行榜普遍低于0.057的分数还是有一些差距。

LightGBM

LightGBM是处理表格数据的利器,以速度快和原生支持类别特征著称,可以直接使用category类型的特征进行训练。

1
2
3
4
5
6
7
8
9
10
11
import lightgbm as lgb
lgb_model = lgb.LGBMRegressor(
random_state = 42,
n_jobs = -1,
n_estimators = 750 #随机设一个值
)
lgb_model.fit(
x_train, y_train,
categorical_feature=all_categorical_cols
)
predictions = lgb_model.predict(x_test)

分数为0.05562

XGBoost

1
2
3
4
5
6
7
8
9
10
11
import xgboost as xgb
xgb_model = xgb.XGBRegressor(
random_state=42,
n_jobs=-1,
n_estimators=750,
enable_categorical=True
)
xgb_model.fit(
x_train, y_train
)
predictions_xgb = xgb_model.predict(x_test)

分数为0.05564,居然比LightGBM要低,不过由于没有调参,所以该结果不能作为最终的判断。

总结(上)

通过以上步骤,我们完成了:

1.对赛题和数据的基本理解。

2.建立了一个平均值基线(0.16603)。

3.使用Random Forest得到了第一个显著提升(0.05913)。

4.初步尝试了LightGBM和XGBoost,并将分数提升至0.056x的水平,验证了Gradient Boosting的潜力。

目前为止,我们仅仅使用了最基础的数据预处理和模型默认/简单参数,分数离最优还有距离。

下一篇(下),我将重点介绍如何通过特征工程来挖掘数据潜力,同时引入K-fold和Early Stopping等方法进一步调优。