kaggle项目:基于 LightGBM 的播客收听时长预测建模实践
标签:数据分析、回归建模、LightGBM、特征工程、缺失值处理
一、项目背景
本项目基于 Kaggle Playground Series S5E4 比赛任务,目标是基于播客剧集相关特征,预测其在实际播放中被听众收听的时长(单位:分钟)。
任务为典型的 回归预测问题,具有以下特点:
- 输入特征为结构化数据,包含内容属性(如节目类型、嘉宾热度、剧集长度等等);
- 输出变量为连续型目标值:
Listening_Time_minutes
; - 评价指标为 Root Mean Square Error(RMSE)。
二、数据集概况
数据集包括以下字段(部分):
字段名称 | 含义 |
---|---|
Genre | 节目类型(类别型) |
Episode_Length_minutes | 剧集总时长 |
Guest_Popularity_percentage | 嘉宾受欢迎程度 |
Publication_Day | 播出时间 |
Listening_Time_minutes | 实际收听时长(目标变量) |
Host_Popularity_percentage | 主持人受欢迎程度 |
Number_of_Ads | 广告数量 |
Publication_Day | 播客在周几发布 |
Publication_Time | 播客在什么时间段发布 |
数据规模为:
- 训练集:约 750,000 条记录;
- 测试集:约 250,000 条记录。
三、数据预处理与缺失值处理
1. 缺失值检查
df_train.isnull().sum()
- Episode_Length_minutes 和 Guest_Popularity_percentage 均存在缺失;
- 缺失比例在不同子群体中存在差异,需结合分组策略填补。
2. 缺失值填补策略
- Episode_Length_minutes:采用分组中位数填补,分组依据为 Genre + Publication_Day:
df_train['Episode_Length_minutes'] = (
df_train.groupby(['Genre', 'Publication_Day'])['Episode_Length_minutes']
.transform(lambda x: x.fillna(x.median()))
)
- Guest_Popularity_percentage:这个字段的填充比较复杂,首先我们判断了缺失值表示的是没有嘉宾,还是确实是数据缺失。然后我们对比了缺失组合非缺失组的平均收听时长,发现差别并不大。最后我们分别尝试了按主持人流行度、播客发布在周几以及节目类型来分箱填充,并且用基线模型来对比效果。最终确定按节目类型分箱填充。
genre_guest_mean = df_train.groupby("Genre")["Guest_Popularity_percentage"].mean().sort_values(ascending=False)
3.异常值处理
- Number_of_Ads:通过箱线图观察广告数量的分布,发现确实有一些极端的异常值,最高的一期播客节目广告数量有103个,这显然不太合理。我们把这部分极端值替换为箱线图的上界值。
Q1 = df_train['Number_of_Ads'].quantile(0.25)
Q3 = df_train['Number_of_Ads'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
outliers = df_train[(df_train['Number_of_Ads'] > upper_bound)]
df_train['Number_of_Ads'] = df_train['Number_of_Ads'].apply(lambda x: upper_bound if (x > upper_bound) else x)
四、特征工程
1. 特征编码
- 类别变量使用 OnehotEncoder 编码;
- 时间变量如 Publication_Day 按顺序映射为整数。
2. 特征构造
构造若干组合特征与变换特征,包括但不限于:
- Guest_Popularity × Episode_Length:反映“嘉宾热度 × 内容体量”的消费吸引力;
- 是否周末播放:从 Publication_Day 衍生布尔变量;
- 嘉宾热度是否缺失:用于捕捉缺失值可能带来的分布偏差。
五、建模与参数设置
采用 LightGBMRegressor 进行建模,参数设置如下:
lgb_params = {
'n_estimators': 1000,
'learning_rate': 0.02,
'max_depth': 7,
'num_leaves': 31,
'random_state': 42
}
训练中使用 early stopping 机制以防过拟合:
model.fit(X_train, y_train,
eval_set=[(X_val, y_val)],
early_stopping_rounds=50,
verbose=100)
六、模型评估
预测结果为连续值,但需考虑实际播放逻辑:
- 对预测值做裁剪处理,限定在 [0, Episode_Length_minutes] 区间;
- 评估指标为 RMSE:
from sklearn.metrics import mean_squared_error
rmse = mean_squared_error(y_val, preds, squared=False)
使用残差图和QQ图对误差分布进行可视化:
七、结果分析与模型解释
提取特征重要性并可视化:
八、项目反思与优化方向
挑战与不足:
- 部分特征缺失率高,填补策略对模型结果影响较大;
- 未进行模型集成与多模型对比,可能存在性能提升空间;
- 目标值分布存在长尾特征,未进行 log 或 Box-Cox 转换试验。
后续优化计划:
- 引入模型对比(XGBoost, CatBoost 等);
- 尝试 log-transformation 提升稳定性;
- 使用 SHAP 进行模型解释。
九、总结
该项目完整实现了一个从数据预处理、特征工程到模型训练与评估的回归建模流程,适用于内容消费类产品的数据建模分析。
作为初学者阶段的重要实战之一,本项目的建模过程有助于理解:
- 如何有效处理缺失值与异常值;
- 如何构造有效特征表达用户行为;