“爆款”这个词听起来很直观,真正写进系统时却很麻烦。

一条内容拿到 1 万赞,到底算不算爆?如果作者有 100 万粉丝,可能只是正常发挥;如果作者只有 1 万粉丝,可能已经完成了明显破圈。只看绝对点赞数,最终得到的通常是大账号排行榜,而不是值得研究的异常内容。

本文给出一套适合个人项目起步的评分方法:用账号内相对倍数判断“是否超过日常”,用赞粉比判断“是否可能破圈”,再用粉丝量分层调整门槛。所有阈值都是可调的工程参数,不是适用于所有平台和领域的行业标准。

一、先定义“值得研究的爆款”

系统不需要给每条作品贴一个绝对真理标签。更实际的目标是把作品分成几组:

这套分类服务于排序和人工复盘,不代表平台官方评级,也不能直接证明内容一定好。评分引擎的任务是减少人工浏览量,把注意力集中到少量候选作品上。

二、R 值:和作者自己的日常比

第一个信号是账号内相对倍数:

R = 当前作品核心指标 / 作者最近 N 条作品核心指标的中位数

如果某个账号最近 20 条作品的点赞中位数是 1000,最新作品获得 8000 赞,那么:

R = 8000 / 1000 = 8

这意味着它的表现约为作者近期常态的 8 倍。这里的“8 倍”只描述相对变化,不代表它在全网排名前多少。

为什么用中位数

均值容易被极端值影响。如果最近 20 条内容中有一条已经爆过,均值会被抬高,普通作品可能被低估;如果有几条数据异常低,均值也会扭曲基线。

中位数对极端值更不敏感,适合个人项目的滚动基线:

import statistics


def compute_baseline(posts, core_metric, window=20):
    recent = sorted(
        posts,
        key=lambda post: post.get("create_time") or 0,
        reverse=True,
    )[:window]
    values = [core_metric(post) for post in recent]
    values = [value for value in values if value is not None]
    if not values:
        return 1.0
    return max(statistics.median(values), 1.0)


def relative_multiple(value, baseline):
    if value is None:
        return None
    return value / max(baseline, 1.0)

max(baseline, 1.0) 是为了避免空数据和全 0 数据导致除零。它不能解决小样本问题,所以系统还要记录样本数量。

小样本不能假装稳定

一个刚开始发内容的账号,最近可能只有 3 条作品。用 3 条作品计算中位数,结果会非常不稳定。建议在数据里保存 baseline_sample_size,并根据样本量降低置信度:

样本少于 5 条:只做观察,不参与正式排名
样本 5 到 19 条:可以计算,但标记为低置信度
样本达到 20 条:使用滚动基线

这只是一个起步策略,具体数量应该根据账号发文频率和领域波动调整。不要把“20 条”写成普遍正确的统计标准。

三、M 值:用赞粉比做破圈校验

第二个信号是赞粉比:

M = 作品点赞数 / 作者粉丝数

它解决的问题是:某个账号平时数据很低,偶尔一条作品从 10 赞涨到 100 赞,R 值可以达到 10,但这不一定是值得研究的破圈内容。M 值可以帮助系统判断绝对传播相对于粉丝规模是否有说服力。

例如:

账号 A:1000 粉,作品 1000 赞,M = 1.00
账号 B:100000 粉,作品 10000 赞,M = 0.10

账号 A 的相对传播可能更突出,但 M 值不能单独证明内容质量。平台推荐机制、粉丝活跃度、发布时间和内容类型都会影响赞粉比。

指标不是所有平台都一样

不同平台的互动字段和用户行为不同:

因此,core_metric(platform, work) 应该由平台和内容类型共同决定,而不是所有作品都只看点赞:

def core_metric(platform, work):
    if platform == "douyin":
        return work.get("likes")
    if platform == "xhs":
        likes = work.get("likes") or 0
        collects = work.get("collects") or 0
        return likes + collects
    if platform == "youtube":
        return work.get("views") or work.get("likes")
    raise ValueError(f"unsupported platform: {platform}")

上面只是示例,不能直接认为它适合所有账户。真正上线前,应该抽取一批历史作品,比较不同核心指标和人工判断之间的差异。

四、Tier:按粉丝量调整门槛

大账号要取得高赞粉比,通常比小账号更难;但小账号的样本和数据波动也可能更大。因此可以按粉丝量设定层级,再给每一层一个起始门槛:

def tier_of(followers):
    followers = followers or 0
    if followers < 10_000:
        return "C", 0.30
    if followers < 100_000:
        return "B", 0.15
    if followers < 1_000_000:
        return "A", 0.08
    return "S", 0.04

这些数字只能作为待校准的初始配置。它们不是平台标准,也不是“达到就一定爆”的证明。不同垂直领域、内容形态和平台分发机制都可能需要不同门槛。

阈值最好放到配置表,而不是写死在业务代码里:

{
  "C": {"followers_lt": 10000, "m_base": 0.30},
  "B": {"followers_lt": 100000, "m_base": 0.15},
  "A": {"followers_lt": 1000000, "m_base": 0.08},
  "S": {"m_base": 0.04}
}

这样你可以针对不同平台、内容类型或账号集合维护不同版本,并在分析结果中保存当时使用的参数版本。

五、两个信号同时达标再分级

一个简单的阶梯规则可以是:

def grade_work(r, m, m_base):
    if r is None or m is None:
        return "insufficient_data", "数据不足"
    if r >= 8.0 and m >= 3.0 * m_base:
        return "T3", "现象级"
    if r >= 4.0 and m >= 1.5 * m_base:
        return "T2", "爆款"
    if r >= 2.0 and m >= 1.0 * m_base:
        return "T1", "小爆"
    if r >= 2.0 and m < 1.0 * m_base:
        return "low_quality", "低质爆款"
    return "ordinary", "普通"

举个只用于说明算法的例子:一个粉丝量在 10 万左右的账号,假设当前层级的 m_base 是 0.08。

作品 1:1 万赞,M = 0.10
作品 2:10 万赞,M = 1.00

作品 1 可能超过了作者日常,但 M 值只刚刚超过起始门槛;作品 2 的破圈信号明显更强。最终是否达到 T1、T2 或 T3,还要同时看 R 值。

六、为什么要冻结证据

一条作品的互动数据会持续变化,作者的粉丝量和近期基线也会变化。如果每次查看都用今天的数据重算,过去的评级会不断漂移。

例如某条作品第一次被发现时:

当时粉丝数:100000
当时基线中位数:1000
当时点赞:10000
当时 R:10
当时 M:0.10

一个月后作者整体表现上涨,基线变成 3000。如果重新计算,R 变成 3.33,系统会把当时的爆款改判成普通内容。这不符合“当时为什么值得关注”的事实。

因此,作品第一次进入评级时,应该冻结:

后续可以继续更新当前指标,但不要覆盖首次评级证据。数据库可以增加一张 grade_events

CREATE TABLE IF NOT EXISTS grade_events (
    id INTEGER PRIMARY KEY,
    work_id INTEGER NOT NULL,
    detected_at TEXT NOT NULL,
    followers_snapshot INTEGER,
    baseline_value REAL,
    baseline_sample_size INTEGER,
    r_value REAL,
    m_value REAL,
    tier TEXT,
    config_version TEXT NOT NULL,
    UNIQUE(work_id, config_version)
);

七、如何校准阈值

不要凭感觉不断改阈值。先建立一份人工标注集:随机挑选一段时间内的作品,由你按“值得研究、普通、事件型、数据异常”进行标注,再运行不同参数,比较漏报和误报。

重点观察:

可以把结果记录成参数实验表:

参数版本 R 阈值 M 倍数 候选数 人工认可数 主要问题
v1 2 / 4 / 8 1 / 1.5 / 3
v2 3 / 5 / 10 1 / 2 / 4

评分引擎不是越复杂越好。只要它能稳定地把你真正想看的内容排到前面,就已经达成了第一阶段目标。

结论

R 值回答“这条内容是否超过作者日常”,M 值回答“它相对于粉丝规模是否有传播”,Tier 负责让不同体量的账号使用不同的起始参照。三个信号结合起来,比全网按点赞排序更适合个人选题研究。

但算法只是在做候选筛选,不是在给内容质量盖章。阈值需要用历史样本校准,缺失字段要保留不确定性,首次评级的基线和粉丝快照要冻结,后续才能解释“当时为什么把它判成爆款”。

参考资料