“爆款”这个词听起来很直观,真正写进系统时却很麻烦。
一条内容拿到 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,系统会把当时的爆款改判成普通内容。这不符合“当时为什么值得关注”的事实。
因此,作品第一次进入评级时,应该冻结:
- 账号粉丝快照;
- 基线样本的作品 ID 和指标;
- 使用的指标版本;
- R、M、Tier 和阈值配置版本;
- 首次发现时间。
后续可以继续更新当前指标,但不要覆盖首次评级证据。数据库可以增加一张 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 负责让不同体量的账号使用不同的起始参照。三个信号结合起来,比全网按点赞排序更适合个人选题研究。
但算法只是在做候选筛选,不是在给内容质量盖章。阈值需要用历史样本校准,缺失字段要保留不确定性,首次评级的基线和粉丝快照要冻结,后续才能解释“当时为什么把它判成爆款”。
参考资料
- Python statistics 文档,用于核对中位数等统计函数。
- SQLite CREATE INDEX 文档,用于核对唯一索引和约束设计。