419. Rainforest Connection Species Audio Detection | rfcx-species-audio-detection
感谢 Kaggle 和 RFCx 举办了这场有趣的比赛。我未经过后处理的最终提交得分为 Private LB 0.926,而经过后处理的提交得分为 Private LB 0.963!后处理带来了 +0.037 的提升!
本次比赛的评估指标与其他比赛不同。我们需要提交 submission.csv,其中每一行是一个测试样本,每一列是一个物种的预测结果。
在其他比赛中,指标通常计算列方向 AUC。而在本次比赛中,指标本质上是行方向 AUC。因此,我们需要每一列代表概率。常见物种的列值需要较大,而稀有物种的列值需要较小。
训练数据的分布中,每个物种的假阳性数量大约是真阳性数量的 6 倍。如果你使用这些数据训练模型,那么当模型对预测不确定时,它会预测在训练数据中观察到的均值,即 1/7。因此,如果它不确定物种 3,它会预测 1/7;如果不确定物种 19,它也会预测 1/7。
这是一个问题,因为物种 3 大约出现在 90% 的测试样本中,而物种 19 仅出现在大约 1% 的测试样本中。因此,当你的模型不确定时,它应该预测 90% 给物种 3,预测 1% 给物种 19。
为了修正模型的预测,我们对几率进行缩放。注意,缩放几率不会影响 0 和 1 的预测,它只影响不确定的中间预测值。
首先,我们将 submission.csv 的概率列通过公式转换为几率:
$$ \text{odds} = \frac{p}{1-p}$$
然后我们通过以下公式缩放几率:
$$ \text{new odds} = \text{factor} * \text{old odds}$$
最后我们转换回概率:
$$ \text{prob} = \frac{\text{new odds}}{1 + \text{new odds}}$$
# 将概率转换为几率,应用乘数,再转换回概率
def scale(probs, factor):
probs = probs.copy()
idx = np.where(probs!=1)[0]
odds = factor * probs[idx] / (1-probs[idx])
probs[idx] = odds/(1+odds)
return probs
for k in range(24):
sub.iloc[:,1+k] = scale(sub.iloc[:,1+k].values, FACTORS[k])
剩下的唯一细节是如何计算上面的 FACTORS(因子)。至少有 3 种方法。
submission.csv 来探测 LB。然后利用数学计算该物种的 factor。更新:使用小于 1 的随机数代替 0,以避免排序的不确定性。就我个人而言,我使用了上面列出的第一种方法。我没有 5 天的时间去探测 LB 24 次(针对第二种方法)。至于第三种方法,我在比赛最后一天才找到那篇论文。
我的单模型未经后处理的得分为 Private LB 0.921,经过后处理得分为 Private LB 0.958。集成多种图像尺寸和主干网络后,LB 分别提升至 0.926 和 LB 0.963。
我使用 Librosa 的 feature.melspectrogram 和 power_to_db 将每个音频文件转换为梅尔频谱图,参数为采样率 32_000,n_mels = 384