背景

介绍几种工业界比较常用的时长建模方案。

Weighted Logloss

Weighted Logloss是YouTube论文1提出的一种方法。将时长转换成,把它当做正类label,那么负类label就是,可以套用交叉熵损失。

实际中一般将loss中分母的去掉,不影响以上推导过程,既:

线上预估时,需要将预估的转换成时长。通过得到,既用作为预估时长。

时长归一化

长视频的消费时长往往更高,所以Weighted Logloss中长视频的比重更大,更倾向于优化长视频的效果。所以,为了消除视频本身长短带来的偏差,可以先将训练样本按video duration分桶,比如0-1分钟的一档,1-5分钟的一档等等,然后每档内部按消费时长分段,最后将消费时长归一化到0到1内的值,用这个归一化后的值做label进行训练。

最优解,线上预估时,将预估的转换成真实时长。先按照video duration找到在哪个分桶,再按分桶内的时长分段,将逆操作得到真实时长。

这里如果用Weighted Logloss是否可以呢?

那么, 但是,,只有当的情况下才是有意义的,模型预估并不能保证这一点。当然,得到后可以人工变换到,比如用。所以工程上用Weighted Logloss也是可以的,但理论上还是存在一定缺陷。

另外,时长归一化在后面的几种方法里都可以叠加使用。

CREAD

CREAD是快手的论文2中提出的方法。

图片替换文本

将消费时长从小到大排序,比如是,然后通过m+1个阈值,其中,将时长分成m+1个区间,每个区间就可以得到一个二分类任务:,共m个二分类任务。线上预估时,可以通过以下公式还原成时长。

实际上,训练时除了m个分类任务,还增加了两个其他损失,一个是还原时长与真实时长的偏差(采用Huber loss),另一个是的序关系(采用Hinge loss)。

Earth Mover’s Distance

传统的多分类任务,label中只有一个是正类,其他是负类,类别之前没有关系。但是在某些任务中,类别之间是有一定关系的。下图是收入预估的一个例子,adult是真实label,AB两种分布的loss是一样的,但明显B比A更合理一点。在时长预估上也有同样的道理,把时长分成10个区间,真实label在区间5,做多分类任务,我们希望5区间的预估概率最高,向左向右的概率平滑的降低。

图片替换文本

论文3使用的是Squared EMD Loss:

论文3不是做时长预估的,我们这里为时长预估任务稍微改动一下。 和CREAD类似,将消费时长从小到大排序,比如是,然后通过m+1个阈值,其中,将时长分成m+1个区间。

线上预估时,可以通过以下公式还原成时长,和CREAD其实一样。

EMD和CREAD的实现其实本质一样,只是出发角度不同。相当于CREAD里的相当于CREAD里的二分类label。但是,EMD相比于CREAD有几个好处。第一,不需要了;第二,CREAD是多个二分类损失叠加,尺度较大,与其他目标做多目标联合训练时不好平衡其他目标,而EMD是一个多分类的loss,尺度比较小;第三,EMD可以和接下来要介绍的Distill Softmax合起来用,效果更佳。

Distill Softmax

和EMD有点类似,只不过EMD从预估值分布角度考虑,而Distill Softmax是从label角度考虑,直接将时长做成了平滑的多分类soft-label。比如,把时长分成10个区间,真实label在区间5,本来的多分类label是[0,0,0,0,1,0,0,0,0,0],这里对时长做了平滑,希望5区间的预估概率最高,向左向右的概率平滑的降低,做成[0.001,0.005,0.03,0.1,0.7,0.1,0.05,0.008,0.005,0.001]。

具体做法,时长先做下laplace分布变换,得到每个区间的概率值,越靠近真实label的区间概率越大。

import numpy as np

def laplace_pdf(x, mean):
variance = 0.1 * x
return 1.0 / (2.0 * variance) * np.exp(-1.0 * np.abs(x - mean) / variance)

def distill_label(time_label):
time_bins = [0.0, 10.0, 30.0, 60.0, 100.0, 150.0] # 时长分桶门槛
time_max = 200.0
time_label = np.clip(time_label, 0.01, time_max)
probs = laplace_pdf(time_label, time_bins)
probs_sum = np.sum(probs)
soft_label = probs / probs_sum
return soft_label

soft_label = distill_label(85.0)
print(soft_label)
# [2.00654601e-04 6.50704494e-04 6.84310455e-03 2.33376557e-01 7.56818804e-01 2.11017508e-03]
# 85在区间[60-100]的概率最大,向左向右平滑降低。

损失函数就是多分类交叉熵:

线上预估时,可以通过以下公式还原成时长,和EMD一样。

Distill Softmax也能和EMD一起用,既先做soft-label变换后,再使用EMD。

参考

  • [1][Recommending What Video to Watch Next: A Multitask Ranking System](https://dl.acm.org/doi/10.1145/3298689.3346997)
  • [2][CREAD: A Classification-Restoration Framework with Error Adaptive Discretization for Watch Time Prediction in Video Recommender Systems](http://arxiv.org/abs/2401.07521)
  • [3][Squared Earth Mover’s Distance-based Loss for Training Deep Neural Networks](http://arxiv.org/abs/1611.05916)