三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

CREAD框架:用分类-恢复范式解决视频观看时长预测难题

CREAD框架:用分类-恢复范式解决视频观看时长预测难题

1. 从“看多久”到“看不看”:视频推荐中观看时长预测的范式转变

在视频推荐系统的核心指标里,用户“看多久”一直是个让人又爱又恨的难题。爱它,是因为它直接关联着用户粘性、内容价值和平台收益,一个能准确预测用户观看时长的模型,理论上能让推荐更精准、更“上头”。恨它,是因为这个目标本身充满了不确定性——用户的注意力是流动的,中途退出可能因为一个电话、一条消息,或者仅仅是内容的一个小低谷。传统的回归方法,比如直接预测一个连续的时长数值,常常被数据中的极端长尾分布(大量短观看和少量超长观看)和噪声搞得焦头烂额,模型容易对异常值过度敏感,预测稳定性差。

最近读了一篇挺有意思的论文,标题是《CREAD: A Classification-Restoration Framework with Error Adaptive Discretization for Watch Time Prediction in Video Recommender Systems》。这个CREAD框架提出了一种全新的思路:我们不直接硬啃“预测具体分钟数”这块硬骨头,而是把它拆解成两个更可控的步骤。简单来说,就是先判断用户“会不会看”(分类),再根据判断的“信心”来精细化估计“大概看多久”(恢复)。这种“分类-恢复”的范式,加上其核心的“误差自适应离散化”机制,为解决观看时长预测的顽疾提供了一个非常巧妙的工程视角。我自己在构建类似预估模型时,也深受回归模型方差过大、校准困难的困扰,CREAD这种将连续问题离散化、再智能重建的思路,感觉像是一下子打开了一扇新窗户。它不仅是一个算法框架,更是一种处理复杂、噪声大、分布不均衡的连续值预测问题的通用方法论,特别适合推荐、广告、金融等领域的从业者深入琢磨。

2. CREAD框架总览:为何要“先分类,后恢复”?

在深入细节之前,我们得先理解CREAD框架的基本骨架和设计哲学。它的全称“Classification-Restoration framework with Error Adaptive Discretization”已经自述了三大核心部件:分类(Classification)、恢复(Restoration)和误差自适应离散化(Error Adaptive Discretization)。整个流程可以概括为:首先,将连续的观看时长通过一种智能的、非均匀的方式离散化成若干个区间(桶),变成一个多分类问题;然后,训练一个分类模型来预测样本属于每个区间的概率;最后,利用分类模型输出的概率分布,通过一个恢复模块,重建出连续的观看时长预测值。

2.1 传统回归方法的瓶颈与分类范式的优势

为什么非要绕个弯子,不直接回归呢?这得从实际业务数据的特性说起。以视频观看时长为例,其分布通常呈现严重的正偏态(右偏)。绝大多数观看行为集中在很短的区间(比如几秒到几分钟),但存在少数长达数小时甚至更久的观看。直接使用MSE(均方误差)或MAE(平均绝对误差)作为损失函数,模型会倾向于“讨好”那些数量占多数的短时长样本,而对长尾的长时长样本预测能力很弱。更糟糕的是,一个极端的长尾样本(比如一次意外的3小时观看)会产生巨大的损失,从而过度影响模型参数的更新,导致模型整体不稳定。

分类范式则巧妙地规避了这个问题。它将一个困难的回归任务,转化为一个相对更容易优化的分类任务。离散化之后,模型的目标不再是精确到一个具体的数值,而是判断“时长最可能落在哪个范围区间内”。这样做有几个直接的好处:

  1. 缓解极端值影响:无论实际时长是100秒还是10000秒,只要它们被划分到合适的、可能较宽的区间内,就不会因为绝对数值的巨大差异而产生破坏性的损失。
  2. 更易于模型学习:深度神经网络通常更擅长学习类别间的决策边界,而不是精确的数值映射。分类任务中的交叉熵损失函数对概率分布的优化更为平滑和稳定。
  3. 提供不确定性信息:分类模型输出的是一组概率分布,这本身就包含了预测的不确定性信息。例如,如果模型对“1-3分钟”和“3-10分钟”两个区间的预测概率都很高且接近,那么我们可以知道模型对这个样本的时长估计是比较不确定的,这个信息在后续的排序或决策中非常有价值。

2.2 CREAD的三阶段工作流

CREAD框架的工作流可以清晰地分为三个阶段,下图展示了其核心数据处理与模型预测的完整链路:

flowchart TD A[“原始连续观看时长数据<br>(长尾、噪声大)”] --> B[“误差自适应离散化模块<br>(EAD)”] subgraph B [误差自适应离散化模块] B1[“利用一个基准回归模型<br>(如简单线性模型)进行初步预测”] --> B2[“计算每个样本的预测残差(误差)”] B2 --> B3[“根据残差分布进行聚类分析<br>(如K-Means)”] B3 --> B4[“确定非均匀的离散化区间边界”] end B --> C[“离散化后的类别标签<br>(如区间 1, 区间 2, … 区间 K)”] C --> D[“分类模型训练<br>(输入:用户/视频特征<br>输出:K个区间的概率分布)”] D --> E[“恢复模块<br>(输入:分类模型输出的概率分布)”] subgraph E [恢复模块] E1[“方案A:加权求和<br>概率 × 区间代表值(如中位数)”] E2[“方案B:分布匹配<br>拟合连续分布(如对数正态)”] end E --> F[“最终连续的观看时长预测值”]

第一阶段:离散化(Discretization)这是整个框架的基石。CREAD没有采用简单的等宽或等频分桶,而是提出了“误差自适应离散化”。其核心思想是:离散化的区间边界不应该由原始时长的分布单独决定,而应该考虑一个简单回归模型的预测误差(残差)分布。具体做法是,先用一个简单的基准模型(比如线性回归)对时长做初步预测,然后分析预测误差的分布。在误差大的区域(即模型难以预测准的区域),我们需要划分更细、更多的区间,让后续的分类模型能在这里进行更精细的区分;在误差小的区域,则可以划分得粗一些。这样形成的离散化方案是“非均匀”的,是一种数据驱动、任务自适应的分桶策略,能更高效地利用模型容量。

第二阶段:分类(Classification)一旦获得了离散化的类别标签,我们就可以构建一个标准的分类模型(如DeepFM、DIN等深度网络)。模型的输入是丰富的用户和视频特征,输出是一个K维向量,代表样本属于K个时长区间的概率。这一步训练的目标是最小化预测概率分布与真实类别标签之间的交叉熵损失。由于变成了分类问题,我们可以方便地应用各种针对分类任务的技巧,如处理类别不平衡的Focal Loss、标签平滑等。

第三阶段:恢复(Restoration)分类模型输出了概率分布,但我们最终需要的还是一个连续的数值。恢复模块的任务就是将这个概率分布“翻译”回一个具体的时长预测值。最简单的方法是加权求和:预测时长 = Σ (第i个区间的概率 * 第i个区间的代表值),代表值可以取区间的中位数。更精细的方法可以假设时长在区间内服从某种分布(如均匀分布或截断分布),然后用概率去拟合这个分布,从而得到更平滑的预测。恢复模块是轻量级的,不参与训练,只在推理时使用。

3. 误差自适应离散化(EAD):让分桶策略“智能”起来

误差自适应离散化是CREAD框架的灵魂,也是它区别于普通分类方法的关键。理解EAD,就能理解CREAD为何有效。它的目标不是找到一个“最好看”的时长分桶,而是找到一个“最有利于后续分类模型学习”的分桶方案。

3.1 EAD的核心步骤与实现细节

EAD的实施可以分为以下几个具体步骤,我结合自己的理解,补充了一些工程实现中需要注意的细节:

  1. 训练一个基准回归模型

    • 模型选择:论文中使用的是简单的线性回归。在实践中,选择什么模型作为基准很重要。原则是“简单且快速”。因为它的目的不是追求极致精度,而是为了快速获得一个对数据模式有基本拟合能力的预测器,从而计算误差。逻辑回归、浅层决策树(如XGBoost with very shallow depth)都是不错的选择。切忌使用复杂的深度模型,那会本末倒置,且可能引入过拟合,干扰误差分布的真实性。
    • 特征工程:基准模型使用的特征可以和最终分类模型一致,也可以先用一套核心特征(如用户历史平均观看时长、视频类别、视频热度等)。目的是用最小的成本获得一个有意义的预测。
  2. 计算预测残差

    • 用基准模型在训练集上进行预测,对于每个样本i,计算残差e_i = y_i - ŷ_i,其中y_i是真实观看时长,ŷ_i是基准模型预测值。
    • 关键点:这里需要对时长做必要的预处理。由于时长是正数且长尾,通常先进行对数变换log(1 + y),让分布更接近正态,这样回归模型的训练会更稳定,残差也更有解释性。计算残差也是在变换后的空间进行的。
  3. 基于残差分布进行聚类

    • 这是EAD最核心的一步。我们不是直接对时长y聚类,而是对由(ŷ_i, e_i)构成的点进行聚类。ŷ_i是预测值,可以看作“基准认知”,e_i是认知偏差。聚类算法(如K-Means)会将预测值和误差模式相似的样本聚在一起。
    • 聚类的意义:同一个簇内的样本,意味着基准模型对它们的预测能力和误差模式是相似的。例如,一个簇可能包含所有“被基准模型严重低估的长视频”,另一个簇可能包含“被基准模型高估的短视频”。这样,簇的边界天然地定义了数据中“难易程度”不同的区域
    • 确定簇数K:这是一个超参数。可以通过肘部法则(Elbow Method)或轮廓系数(Silhouette Score)来辅助选择。也可以根据业务经验,比如希望最终有多少个时长档位(如5档或10档)。论文中通常实验确定。
  4. 从簇到离散化区间

    • 完成聚类后,每个样本都有一个簇标签。然后,我们在每个簇内部,对真实的观看时长y(或变换后的值)进行排序。
    • 对于目标为K个最终类别的任务,我们需要在每个簇内产生若干分位点,将簇内的时长进一步细分。一种策略是:根据簇内样本数量占总体的比例,来分配子区间数量。大簇多分,小簇少分。最终,所有簇的子区间合并起来,就形成了K个非均匀的、覆盖整个时长范围的离散化区间。
    • 最终输出:每个样本根据其真实时长y落入哪个最终的区间,获得一个类别标签label ∈ {1, 2, ..., K}

注意:EAD过程通常只在训练集上进行。我们需要保存最终确定的离散化区间边界(cut points)。在验证集和测试集上,我们直接应用这些边界来为样本分配标签,而不是重新运行EAD。这样才能保证数据划分的一致性。

3.2 与等宽/等频分桶的直观对比

为了更直观地理解EAD的优势,我们将其与两种传统分桶方法进行对比:

分桶方法核心思想优点缺点在观看时长预测中的问题
等宽分桶将时长范围[min, max]均匀分成K段。简单直观,区间宽度一致。完全忽略数据分布。长尾数据下,绝大多数样本挤在前几个桶,后面桶几乎为空。分类模型无法学习有效的特征,因为标签极度不平衡,且长尾区域的样本没有区分度。
等频分桶按样本数量均匀分桶,每个桶内样本数大致相等。解决了类别不平衡问题。桶的边界值可能没有业务意义(如一个桶是[3s, 15s],下一个是[15s, 2min])。在预测误差较大的区域(如中等时长),可能因为样本数量多而被划分得过粗,不利于模型精细化学习。
误差自适应离散化根据基准模型预测误差分布进行非均匀分桶。数据驱动,在模型难预测的区域划分更细。任务自适应,分桶策略服务于最终预测目标。实现相对复杂,需要训练基准模型和聚类。需要额外计算,但通常是一次性开销,换来的是分类模型更优的学习效率和最终效果。

从对比可以看出,EAD是一种“智能”的分桶。它像一个经验丰富的老师,知道学生(模型)在哪些知识点(数据区域)容易出错,就在那些地方多安排一些练习题(细分区间),帮助学生重点突破。

4. 分类与恢复模块的设计与实战要点

在获得了高质量的离散标签后,我们就进入了模型构建的核心阶段:分类与恢复。这部分虽然听起来标准,但在CREAD框架的语境下,有一些特定的设计和实战技巧。

4.1 分类模型的结构与特征工程

分类模型的选择非常灵活,可以是你业务中任何表现良好的深度推荐模型,如DeepFM、DCN、DIN、DIEN等。模型结构本身不是CREAD的创新点,关键在于如何针对“观看时长区间分类”这个任务进行适配。

  • 输入特征:需要充分利用用户和视频的两方面信息。

    • 用户侧:用户ID嵌入、历史行为序列(观看、点赞、收藏的视频ID序列)、人口统计学特征(如果可用)、用户长期兴趣标签、实时上下文(时间、设备、网络)。
    • 视频侧:视频ID嵌入、标题/描述文本的嵌入、封面图的多模态特征、类别标签、创作者信息、视频质量指标(分辨率、码率)、实时热度(近期播放量、互动率)。
    • 交叉特征:用户-视频匹配度特征至关重要。例如,用户历史兴趣标签与视频标签的余弦相似度、用户常看类别与该视频类别的重合度等。这些特征能直接反映“用户可能对这个视频有多感兴趣”。
  • 输出层与损失函数

    • 输出层是一个K维的全连接层,接Softmax激活,输出一个概率分布P = [p1, p2, ..., pK]
    • 损失函数使用标准的分类交叉熵损失:L_cls = -log(p_label),其中label是样本的真实离散标签。
    • 处理类别不平衡:尽管EAD在一定程度上缓解了不平衡,但可能仍然存在。可以采用Focal Loss来动态调整损失权重,让模型更关注难分类的样本(通常是那些处于区间边界附近的样本)。Focal Loss的公式为FL = -α_t * (1 - p_t)^γ * log(p_t),其中p_t是模型对真实类别的预测概率,α_t是类别权重,γ是调节因子,用于降低易分类样本的损失贡献。

4.2 恢复模块:从概率回到数值

分类模型训练好后,在线上服务时,我们需要将输出的概率分布转换回一个标量的观看时长预测值。这就是恢复模块的工作。这里有几个实用的方案:

  1. 区间中位数加权法(最常用)

    • 这是最简单直接的方法。预先计算好每个离散区间[l_i, r_i)的代表值,通常取中位数m_i = (l_i + r_i) / 2。在原始时长空间(而非对数空间)计算。
    • 预测时,计算加权和:ŷ = Σ (p_i * m_i)
    • 优点:计算简单,无需额外参数,线上推理速度快。
    • 缺点:假设每个区间内的时长均匀分布,可能与实际不符。对于宽区间,中位数可能代表性不强。
  2. 条件期望法(更精确)

    • 假设我们知道在每个区间内,时长的条件概率分布f(y | label=i)。那么,预测时长为:ŷ = Σ [ p_i * E(y | label=i) ],其中E(y | label=i)是该区间内时长的期望值。
    • 如何估计E(y | label=i)?可以在训练集上,对每个区间内的样本,计算其真实时长的平均值作为期望的估计。这个方法比中位数法更准确地反映了区间内的数据分布。
    • 实战技巧:为了防止过拟合,可以对每个区间的期望值进行平滑处理,比如使用全体的全局平均值进行贝叶斯平滑。
  3. 分布拟合法(最复杂但最灵活)

    • 这种方法不再将区间视为孤立的,而是假设整个观看时长服从一个参数化的连续分布,例如对数正态分布。因为对数正态分布非常适合描述这种正值、右偏的数据。
    • 分类模型输出的概率分布P,可以被视为这个连续分布在各个离散区间上的概率质量。恢复模块的任务是,找到一个对数正态分布的参数(均值μ和方差σ²),使得该分布在各区间上的积分值最接近模型输出的概率P。这可以通过最小化交叉熵或KL散度来实现。
    • 找到最优参数后,预测时长可以直接取该分布的期望值exp(μ + σ²/2)
    • 优点:预测非常平滑,且能给出预测的不确定性(分布的方差)。
    • 缺点:实现复杂,需要额外的优化步骤,线上推理开销稍大。

个人经验:在大多数业务场景中,区间中位数加权法条件期望法已经足够好,且易于上线和维护。分布拟合法更适合对预测精度和不确定性估计有极高要求的场景,如某些金融风险预估。建议先从简单方法开始,作为基线。

4.3 一个完整的训练与推理流程示例

假设我们使用DeepFM作为分类模型,采用条件期望法进行恢复。

训练阶段

  1. 数据准备:准备用户-视频交互日志,包含特征和真实观看时长y
  2. EAD离散化:
    • 用训练集训练一个浅层XGBoost回归模型,预测log(1+y)
    • 计算残差e
    • (ŷ, e)进行K-Means聚类(例如,聚成5个母簇)。
    • 在每个母簇内,根据样本比例分配子区间,最终得到10个离散区间。保存区间边界[l1, r1), [l2, r2), ..., [l10, r10)
    • 为每个训练样本打上区间标签(1到10)。
    • 计算每个区间的条件期望E_i(即该区间内所有样本y的平均值),并保存。
  3. 分类模型训练:
    • 构建DeepFM模型,输入特征,输出10维概率。
    • 使用带Focal Loss的交叉熵损失进行训练。
    • 在验证集上根据分类准确率或恢复后的回归指标(如MAE)调整超参数。

推理阶段

  1. 线上收到请求,提取用户和候选视频的特征。
  2. 输入DeepFM模型,得到10维概率向量P
  3. 恢复模块计算:预测时长 = p1*E1 + p2*E2 + ... + p10*E10
  4. 将预测时长输出,用于排序或后续业务逻辑。

5. 效果评估、实战陷阱与延伸思考

任何模型框架的价值,最终都要落到实际效果和落地可行性上。CREAD论文中展示了其在公开数据集和工业数据集上优于直接回归和均匀分桶分类方法的结果。但我们在自己实践中,应该如何评估,又会遇到哪些坑呢?

5.1 如何科学地评估CREAD的效果?

评估需要分两个层面:分类效果和最终回归效果。

  • 分类效果评估

    • 准确率:最直接的指标,看预测区间是否命中真实区间。但要注意,对于有序的区间,预测到相邻区间(如真实为第3类,预测为第2或第4类)的误差,应该比预测到远处区间(如第8类)的误差要小。因此,单纯准确率可能不够。
    • 加权准确率:根据预测类别与真实类别的“距离”来加权计算准确率。距离越远,惩罚越大。
    • 分类交叉熵损失:直接反映模型输出概率分布与真实one-hot标签的差异。
  • 回归效果评估(核心)

    • 这是我们最终关心的。在通过恢复模块得到连续预测值ŷ后,使用回归任务的标准指标:
      • MAE:平均绝对误差。MAE = mean(|y - ŷ|)。对异常值相对不敏感,解释直观。
      • MSE/RMSE:均方误差/均方根误差。MSE = mean((y - ŷ)^2)。对大的误差惩罚更重。
      • MAPE:平均绝对百分比误差。MAPE = mean(|(y - ŷ)/y|)。衡量相对误差,但y接近0时不稳定。
    • 特别重要的指标:分组误差分析。不要只看全局指标。将测试集按真实时长分组(如0-10s, 10s-1min, 1min-5min, 5min+),分别计算每组的MAE或MAPE。这能清楚地告诉我们,模型在短、中、长视频上的预测能力分别如何。CREAD的目标之一就是提升在难预测区域(通常是中等时长和长尾)的表现。

5.2 实战中可能遇到的“坑”与应对策略

  1. EAD的稳定性问题:EAD依赖于初始的基准模型和聚类算法。如果训练数据有小幅波动,EAD产生的区间边界可能会变化,导致标签分布不一致,影响模型迭代。策略:使用一个稳定的、数据量足够的子集(如上周全量数据)来运行EAD,确定区间边界后,固定下来用于未来一段时间(如一个月)的训练。定期(如每月)重新运行EAD,评估边界是否需要更新。

  2. 区间边界处的预测跳跃:这是分类方法固有的问题。假设两个样本的真实时长非常接近,但恰好落在区间的两侧(如一个29.9秒,一个30.1秒,边界是30秒),它们会被打上不同的标签。模型可能会学到完全不同的特征模式,导致预测出的概率分布差异很大,进而通过恢复模块算出的最终预测值可能产生一个不连续的“跳跃”。策略:可以采用“软标签”或标签平滑。例如,不为样本分配一个确定的类别,而是分配一个分布,让边界两侧的样本带有少量相邻类别的概率。这能缓解硬边界带来的不连续性。

  3. 恢复模块的偏差:如果分类模型预测的概率分布有系统性偏差(例如,总是高估短区间的概率),那么即使分类准确率高,恢复后的回归值也可能存在偏差。策略:在验证集上校准模型输出的概率。可以使用Platt Scaling或Isotonic Regression等方法,让预测概率的分布与真实分布更加匹配。校准后再进行恢复,能有效减少偏差。

  4. 线上推理延迟:相比单一回归模型,CREAD需要先运行分类模型(可能很复杂),再进行恢复计算。可能会增加少量延迟。策略:分类模型本身是高度优化的,恢复计算是简单的向量点乘,开销极小。主要瓶颈仍在特征获取和模型前向传播。确保分类模型结构高效,并利用模型剪枝、量化等技术进行加速。

5.3 延伸思考:CREAD思想的其他应用场景

CREAD框架的精髓——“将困难回归问题分解为分类+恢复,并利用误差指导离散化”——具有很好的普适性,可以迁移到许多其他具有类似数据特性的预估问题上:

  • 电商客单价预测:用户消费金额同样具有长尾分布(大量小额订单,少量巨额订单)。可以用EAD对金额分桶,预测用户本次消费最可能落入的金额区间,再恢复出具体金额。
  • 内容生成时长预测:预测用户创作一篇帖子、一个视频需要的时间。时间预估难度大,分布不规则。
  • 交通出行时间预估:预估从A点到B点的行程时间,受路况、天气影响大,分布复杂。可以将其离散化为“非常快”、“快”、“正常”、“慢”、“非常慢”等类别,结合实时特征进行分类,再恢复为具体分钟数。
  • 金融风控中的贷款违约损失预估:预估违约可能造成的损失金额,数据稀疏且长尾。分类可以判断损失等级(低、中、高),再精细化估计。

我个人在尝试类似思路时的体会是,这套方法最大的优势在于它提供了一种“分而治之”的工程化思维。当直接建模一个目标非常困难时,先把它转换成一个更容易学习、更稳定的中间表示(分类),再通过一个确定性的、可解释的映射(恢复)得到最终结果。这种解耦让模型训练更稳定,也让问题的调试和分析变得更清晰——你可以单独分析是分类不准,还是恢复策略有问题。当然,它引入了额外的步骤和超参数(如区间数量K),需要更多的实验和调优。但对于那些被回归问题折磨已久的场景,CREAD无疑是一个值得放入工具箱的强力候选方案。

← 返回列表