docs: document duration efficiency, up follower snapshot and nav split

This commit is contained in:
kairee committed 2026-11-01 11:36:34 +08:00
1 parent c0b0286395
commit cb9e8e031b
2 files changed
+101 -22

No files matched your search

+51 -12
View File
@@ -1,7 +1,7 @@
# 咻咻满 Reaction 视频数据看板 —— 可行性分析与技术路线
> 状态:**设计定稿;P0(数据底座与收藏夹同步)、P1(每日快照与粉丝追踪)、P2(只读本地看板)、P3(Telegram 与一键加入)已实施**
> 最后更新:2026-10-31(第 8 轮:P2 只读看板与预览数据落地)
> 状态:**设计定稿;P0(数据底座与收藏夹同步)、P1(每日快照与粉丝追踪)、P2(只读本地看板)、P3(Telegram 与一键加入)已实施;第 9 轮加入时长效率榜、UP 粉丝快照与导航拆分**
> 最后更新:2026-11-01(第 9 轮:时长效率榜、粉丝快照采集、视频/UP 导航拆分与数据说明页)
> B 站探测均为只读(GET),尚未调用 `fav/resource/deal`、`fav/resource/sort`
---
@@ -517,6 +517,15 @@ CREATE TABLE fav_action (
CREATE TABLE kv (k TEXT PRIMARY KEY, v TEXT);
```
**第 9 轮新增(schema v4,已迁移)**
- `video.pages`:分 P 数(来自 `infos` 的 `page`),只用于详情展示与包装诊断,不参与排序;
- `video.up_follower` / `up_follower_at` / `up_follower_backfilled`:视频**入库时**的 UP 粉丝数快照;
- `up_profile(mid, name, follower_first, following_first, first_captured_at, follower_latest, last_refreshed)`:每个 UP 的首次/最近粉丝数。`follower_first` 不可被覆盖;
- 采集:收藏夹同步结束时对仍缺粉丝数的 UP 调一次 `relation/stat`(匿名可用);`first_seen >= 本次运行开始前 1 小时` 的视频记为实时采集,更早的记为回填;
- 回填:`python app.py backfill-followers [--limit N] [--dry-run]`,只补 `up_follower IS NULL` 的追踪视频;
- 基于粉丝数的榜单暂不实现,本轮只保证数据从现在起不再缺失。
**要点**
- `status` 是核心状态机:
@@ -661,6 +670,25 @@ fan_delta_cum = follower(d) - follower(首日)
- 缺失日不插值,曲线断开并标注;
- 首日没有前值,第一条增量从第 2 天开始。
### 8.5 时长效率与 UP 内容效率(第 9 轮)
Reaction 视频时长差异极大(100~336 分钟),而播放是累计计数;若不加时长分母,长视频会天然占优,短视频/切片则天然吃亏。因此新增与时长相关的口径:
```
内容小时 = duration / 3600 # 多 P 的 duration 已是各 P 之和
内容效率 = view / 内容小时
互动效率 = (like + coin + favorite) / 内容小时
UP 内容效率 = EB 收缩后的 Σview / Σ内容小时
```
- 分母只用总时长,**不用分 P 数**:B 站播放记在 bvid 上,`view / pages` 没有统计含义;`pages` 仅用于详情展示与包装诊断;
- 效率榜只统计 `duration >= analytics.min_duration_seconds`(默认 600 秒)且发布满 `analytics.maturity_days`(默认 14 天)的视频;不足者标注"样本不足";
- **不用无界年龄项**:reaction 视频约两周进入平台期,`log(age)` 会系统性惩罚老视频,故采用"成熟窗口筛选"而非年龄回归;
- `duration` 为空或 ≤ 0(通常只在失效视频出现)不进入效率榜,不插补;
- UP 效率用 Gamma–Poisson 经验贝叶斯:`rate = (Σview + κ·μ₀) / (Σ内容分钟 + κ)`,`μ₀` 为全库播放/分钟,`κ` 自适应取全库 UP 总内容分钟中位数(配置 `analytics.shrink_minutes` 可覆盖,缺省回退 120 分钟);
- 视频榜默认 Tab 为内容效率,原始播放榜保留;互动单项只保留播放/投币/收藏/评论,点赞、弹幕、转发并入"互动";
- **UP 榜的"视频数"与"总时长"并列展示、分别可排序,不合成单一产出分**(两者高度共线,加权求和的权重是任意的)。
---
## 9. 看板
@@ -670,9 +698,11 @@ fan_delta_cum = follower(d) - follower(首日)
| 页面 | 内容 |
|---|---|
| 首页 | 最新动态优先:今日增量、最新入库、最近发布、增长动态、热度速览、收藏夹容量、采集状态 |
| 榜单 | Tab:综合热度/播放/点赞/投币/收藏/转发/评论/弹幕/互动率/播放增量/播放增速;视频与 UP 范围切换;筛选与搜索 |
| 视频详情 | 元数据 + 七项指标 + 单指标趋势(7/30/90/全部)+ 同 UP 对比 + 快照表(含失败标记) |
| UP 页 | 该 UP 全部视频、聚合趋势、单视频对比、平均互动率 |
| **视频** | Tab:内容效率/综合热度/播放/投币/收藏/评论/互动率/播放增量/播放增速;筛选与搜索 |
| **UP主** | 独立入口;列:视频数、总时长、总播放、播放·小时、互动·小时等,可分别排序 |
| 数据说明 | 数据来源与更新节奏、三个时间概念、指标公式、时长/成熟窗口筛选、粉丝快照覆盖与已知局限;数值由 `/api/about` 动态读取当前配置 |
| 视频详情 | 元数据 + 分 P 数 + 七项指标 + 内容/互动效率 + 入库时粉丝数 + 单指标趋势 + 同 UP 对比 + 快照表 |
| UP 页 | 该 UP 全部视频、聚合趋势、单视频对比、总时长/播放·小时、入库时与当前粉丝数 |
| **粉丝页** | 咻咻满粉丝数曲线 + 每日/7 日净增 + 累计增长(标注起始日期)+ 最近 14 天记录;支持 7/30/90/全部与自选起止日期,范围不超过一年按日绘制,超过一年按每月峰值日期绘制;只画粉丝,不叠加视频数据 |
| **候选池** | 候选、得分、通知时间、剩余 TTL;只读展示,操作指向 Telegram/CLI |
| **系统状态** | 最近任务、采集成功率、收藏夹同步时间、下次任务、备份、鉴权、黑名单 |
@@ -819,12 +849,21 @@ storage:SQLite WAL,单写线程
## 14. 下一步
P0、P1、P2、P3 已实施。P2 交付了只读本地看板与可重复生成的 7 天预览数据:
P0、P1、P2、P3 与第 9 轮已实施;P2 交付了只读本地看板与可重复生成的 7 天预览数据。
1. 首页、榜单、视频/UP 详情、粉丝曲线、候选池和系统状态页面;
2. 原生 ES Module + 本地 ECharts,本机默认绑定 `127.0.0.1:8080`;
3. 查询、热度、增长和互动率全部在服务端计算,前端只渲染;
4. Web 不提供业务写操作,数据管理继续通过 Telegram/CLI/数据库;
5. P3 的真实 `deal` / `sort` 待用户点击 Telegram 按钮或授权测试视频后补充验证记录。
第 9 轮(2026-11-01)交付:
> P4(容器化 + 反代)继续保持可选。
1. schema v4:`video.pages`、`video.up_follower*`、`up_profile`;
2. 入库时采集 UP 粉丝快照 + `python app.py backfill-followers` 历史回填(基于粉丝数的榜单暂不做);
3. 时长效率榜(内容效率/互动效率)与 UP 内容效率(EB 收缩),过滤 < 600 秒与未满 14 天的视频;
4. 主导航拆分:「榜单」→「视频」+「UP主」,两者独立页面;新增「数据说明」页(`/about` + `/api/about`);
5. 列表精简:卡片只保留主指标 + 互动率,七项明细与分 P、粉丝快照移到详情页。
仍待处理:
1. 真实 `deal` / `sort` 与 Telegram 按钮回调的补充验证记录;
2. 基于粉丝数的"破圈"维度(播放/入库时粉丝数、粉丝分段、UP 中位数)——数据已就绪,榜单未实现;
3. P4(容器化 + 反代)继续保持可选。
> 本地数据:第 9 轮起本地只保留可再生的预览库 `data/preview/app.db`(`tools/seed_preview_db.py` 生成),
> 原 `data/app.db` 真实副本已删除;需要重新生成或恢复时,用 `--source data/backup/app-local-before-reseed-20261101.db`。