Files
re-xxm/reaction_board/web/static/views/about.js
T

107 lines
6.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { api } from "../api.js";
import { escapeHtml } from "../format.js";
function weightRows(weights) {
return Object.entries(weights || {})
.map(([metric, value]) => `<li><code>${escapeHtml(metric)}</code> ${(Number(value) * 100).toFixed(0)}%</li>`)
.join("");
}
export async function renderAbout(root) {
const data = await api("/api/about");
const analytics = data.analytics || {};
const followers = data.followers || {};
const coverage = followers.videos_total
? Math.round((followers.videos_covered / followers.videos_total) * 100)
: 0;
const fansStart = data.fans_start_date
? escapeHtml(data.fans_start_date)
: "暂无";
root.innerHTML = `<section class="page about-page">
<header class="page-head">
<h1>数据说明 <span class="page-sub">统计口径与方法</span></h1>
</header>
<section class="panel">
<h2>数据来源与更新</h2>
<ul class="about-list">
<li>所有数据来自 B 站以及部分 MCN 统计网站。</li>
<li>新视频人工入库;库内视频数据每天更新一次;最新数据日:<strong>${escapeHtml(data.data_date || "暂无")}</strong>。</li>
<li>当前视频数据覆盖 <strong>${data.snapshot_days}</strong> 天${data.snapshot_first_date ? `(起始 ${escapeHtml(data.snapshot_first_date)})` : ""};历史快照无法从 B 站回填,只能从部署当天开始积累。</li>
<li>咻咻满粉丝数据的起点日期为 <strong>${fansStart}</strong>。</li>
</ul>
${data.preview ? `<p class="section-note">当前为预览数据,不影响真实数据库。</p>` : ""}
</section>
<section class="panel">
<h2>三个时间概念</h2>
<ul class="about-list">
<li><strong>发布时间</strong>(<code>pubdate</code>):视频在 B 站发布的时刻。</li>
<li><strong>入库时间</strong>(<code>first_seen</code>):本站第一次录入该视频的时刻。</li>
<li><strong>快照日期</strong>(<code>stat_date</code>):每天更新一次视频的播放与互动数据。缺失日不插值,曲线直接断开。</li>
</ul>
<p class="section-note">因此,同一个视频的“发布后 7 天数据”和“入库后 7 天数据”可能不是同一段区间;详情页会同时展示发布时间与入库时间。</p>
</section>
<section class="panel">
<h2>指标口径</h2>
<ul class="about-list">
<li><strong>播放 / 投币 / 收藏 / 评论</strong>:直接取当日快照;弹幕与转发不单列,已并入“互动”。</li>
<li><strong>互动</strong>:点赞 + 投币 + 收藏。综合热度也使用全部七项指标,按配置权重加权。</li>
<li><strong>互动率</strong>:(点赞 + 投币 + 收藏) / 播放;播放不足 100 不计算。</li>
<li><strong>综合热度</strong>:每项先 <code>log1p</code>,再按中位数与 IQR 做稳健标准化,最后加权求和。分数只用于同一批数据内排序,不能跨日期比较。</li>
<li><strong>内容效率</strong>:播放 / 内容小时。内容小时 = 视频总时长(多 P 为各 P 之和)÷ 3600。</li>
<li><strong>互动效率</strong>:互动 / 内容小时,互动口径同上。</li>
<li><strong>UP 内容效率</strong>:把该 UP 的全部视频合并后计算,并用 Gamma–Poisson 经验贝叶斯向全库均值收缩,避免单条视频或极小样本冲榜。收缩强度 κ ${analytics.shrink_minutes ? `固定为 ${analytics.shrink_minutes} 分钟` : "取全库 UP 总内容分钟的中位数"}。</li>
<li><strong>累计触达</strong>:总播放。它是规模指标,不代表吸引力;高产 UP 排在前列是正常结果。</li>
<li><strong>分 P</strong>:<code>pages</code> 是分 P 数,<code>duration</code> 是该 bvid 各 P 时长之和。B 站不公开单 P 播放,因此没有单 P 榜;分 P 数只用于详情展示,不参与排序。</li>
</ul>
</section>
<section class="panel">
<h2>榜单筛选</h2>
<ul class="about-list">
<li>内容效率与互动效率只统计时长 ≥ <strong>${analytics.min_duration_seconds}</strong> 秒的视频,排除结构不同的短视频与切片。</li>
<li>只统计发布满 <strong>${analytics.maturity_days}</strong> 天的视频;reaction 视频通常在发布前两天完成数据积累,两周内接近平台期,过早比较会系统性低估新视频。</li>
<li>不引入无界的“年龄惩罚”:超过成熟窗口后不再按天加分或扣分。</li>
<li><code>duration</code> 为空或 ≤ 0 的视频(通常只在失效视频上出现)不进入任何时长相关榜,也不做插补。</li>
<li>当前配置的最小播放门槛为 <strong>${analytics.min_view_for_efficiency}</strong>。</li>
</ul>
</section>
<section class="panel">
<h2>综合热度权重</h2>
<ul class="about-list about-weights">${weightRows(data.heat_weights)}</ul>
<p class="section-note">权重是主观配置,可在配置文件中调整;页面展示的是当前生效值。</p>
</section>
<section class="panel">
<h2>UP 粉丝快照</h2>
<ul class="about-list">
<li>视频入库时记录一次 UP 当前粉丝数,后续更新视频数据不刷新 UP 的入库时粉丝数。</li>
<li>历史视频的粉丝数是回填值,会标记 <code>backfilled</code>;它与真实的“入库时”存在时间差,暂不用于榜单排序。</li>
<li>当前覆盖:${followers.videos_covered} / ${followers.videos_total} 条视频(${coverage}%),涉及 ${followers.ups_tracked} 个 UP;缺失 ${followers.videos_missing} 条,可运行 <code>app.py backfill-followers</code> 补齐。</li>
</ul>
</section>
<section class="panel">
<h2>已知局限</h2>
<ul class="about-list">
<li>播放是累计值,受发布时间影响;效率榜用成熟窗口过滤,但无法完全消除历史推荐差异。</li>
<li>B 站不公开完播率与单 P 播放,内容小时是“供给时长”,不是“实际观看时长”。</li>
<li>多 P 可能让同一用户产生多次播放计数,本站不单独校正,属于已知偏差。</li>
<li>粉丝数可能包含不活跃账号;粉丝快照暂不参与任何榜单。</li>
<li>样本不足(少于 2 天快照、单视频 UP)会显示提示,不伪造 0。</li>
</ul>
</section>
<section class="panel">
<h2>技术信息</h2>
<ul class="about-list">
<li>数据库 schema 版本 <code>${data.schema_version}</code>。</li>
<li>${data.preview ? "当前为预览数据,不影响真实数据库。" : "当前为真实数据库。"}</li>
</ul>
</section>
</section>`;
}