416. Riiid Answer Correctness Prediction | riiid-test-answer-prediction
大家好,
从其他人的解决方案中学到了很多!在这篇文章中,我想分享一些关于我的解决方案的见解。
总而言之,我最好的单一NN模型可以达到813/815的公开/私有分数,通过5折集成和每折3个快照,最终15个nn模型达到了814/816的公开/私有分数。
使用15个nn模型,在线推理成本不到4小时,因此该流程至少可以集成30个模型。
我通过以下几个步骤划分训练集和验证集:
这样我们在训练集和验证集中都有独立的用户,也有许多同时出现在训练集和验证集中的用户。这种划分方式与LB(排行榜)的分数差异可以小于0.001。
通过更改不同的随机种子,我们可以获得不同的折。
由于其他帖子中已经有很多详细的FE(特征工程),我只分享一些重点。
评估用户能力
评估内容难度
评估用户 x 内容特征
即使内容很难,用户可能仍然足够熟练并能正确解决。因此我们还需要描述用户在此内容上的表现。
user_acc_diff:对于某个内容,如果该内容的全局准确率较低,但用户回答正确,则该用户可能高于所有用户的平均水平。我们可以使用 $logloss(content\_global\_average\_acc, user\_answer)$ 来评估差异。
user_elapsed_diff:类似于user_acc_diff,我们也可以评估用户历史内容中的用户耗时差异。
我们可以在上述三个领域挖掘许多特征,例如,用户在历史内容/历史相同部分内容/历史相同标签内容上的平均滞后时间……也可能是有用的特征。
此外,还使用了诸如当前内容ID/当前时间戳/当前部分等特征。最后,我得到了120维特征,单折的单个lgb模型可以获得公开分数0.806。
P.S. lightgbm的分类特征(在content id上设置)可以使我的分数提高约0.003。
还有许多有用的提示可以提高速度并节省内存:
因为当我注意到顶尖选手的关键是NN模型时已经太晚了,我没有太多时间分析NN模型,特别是设计特定的特征或结构。为了节省时间,我使用lightgbm特征作为NN输入(添加了时间轴,序列长度为128)。
lightgbm的特征中有许多异常值,因此简单地利用标准化很难获得理想的结果。我利用鲁棒标准化来标准化所有特征:
def robust_normalization(column):
cur_mean = np.nanmedian(column)
cur_qmin, cur_qmax = np.nanpercentile(cur,[2.5, 97.5])
cur_std = np.nanstd(column[(column>=cur_qmin) & (column<=cur_qmax)])
column = np.clip(column, a_min = cur_qmin, a_max = cur_qmax)
column = (column-cur_mean)/cur_std
return column