进阶主题
TF-IDF 算法
本地关键字提取的分词、词频、IDF 与退化策略全解
扩展的 「本地算法」模式 使用经典的 TF-IDF 在浏览器内完成关键字提取,完全不走网络。本页还原算法的全部细节,方便你判断结果是否合理,也方便基于源码做二次开发。
输入输出
- 输入:某个收藏夹内的 视频标题数组
titles: string[]; - 输出:若干个
{ keyword, score }组成的排序列表,默认取 Top 10。
默认参数:
| 参数 | 默认值 | 含义 |
|---|---|---|
maxKeywords | 10 | 返回前 N 个关键字 |
minScore | 0.1 | 分数低于阈值的直接丢弃 |
minLength | 2 | 长度小于此值的关键字丢弃 |
分词策略
扩展没有引入 jieba 之类的分词库,而是使用 轻量级启发式分词:
- 去噪:用正则把非
\u4e00-\u9fa5(中文字符)、非a-zA-Z、非0-9的符号替换为空格; - 英文分词:按空格切出英文单词;
- 中文 n-gram:对原始标题字符串,滑动窗口提取 2 ~ 4 字 的纯中文子串(
/^[\u4e00-\u9fa5]+$/)。
n-gram 是一种"暴力但有效"的分词方法:例如标题 React 教程合集 会产出 React、教程、程合、合集、教程合、程合集、教程合集 等候选,之后由停用词表与 TF-IDF 筛掉低质量项。
停用词表
以下词会在计算分数之后被直接过滤(无论分数多高):
的、了、在、是、我、有、和、就、不、人、都、一、一个、上、也、很、到、说、要、去、你、会、着、没有、看、好、自己、这、那、里、就是、什么、可以、这个、我们、他、她、教程、视频、合集、系列、第、集、期、完整版、全集、更新、最新、高清、中文、字幕
包含了常见无意义虚词 + B 站视频标题中频繁出现但通常不携带语义的词(如「教程」「合集」「字幕」)。
打分算法
文档数 > 2 时:标准 TF-IDF
以 每条标题作为一个"文档" 构建 TF-IDF:
- TF(词频):整个标题集合中词
w出现的总次数(注意:是 全局 TF,不是单文档 TF); - IDF(逆文档频率):
Math.log(docCount / 出现该词的文档数); - 分数:
score(w) = TF(w) * IDF(w)。
这意味着 在多个标题中都出现的词 反而 IDF 较低、得分较低;只在少量标题中集中出现 的词 IDF 高、得分高。
文档数 ≤ 2 时:退化为纯词频
当收藏夹只有 1~2 条视频时 IDF 退化没意义(极端情况 log(1/1)=0),扩展会回退为 只用 TF 打分,即出现次数越多分越高。
过滤与排序
最终输出前要经过三道闸门:
- 长度:
keyword.length >= minLength(默认 2); - 停用词:
STOP_WORDS.has(keyword)为false; - 分数:
score >= minScore(默认 0.1)。
通过后按 score 降序,取前 maxKeywords 条。
典型行为与调优建议
| 症状 | 原因 | 缓解方式 |
|---|---|---|
关键字全是碎片(如 程合) | n-gram 产生的副作用,且你的标题主题太分散 | 切换到 「AI 智能」 模式,模型会输出更连贯的短语 |
| 热门词没被选中 | 该词在所有标题都出现 → IDF 很低 | 说明该词无区分度;换用更具体的变种(如把「编程」换成「编程原理」) |
| 结果条数少于 10 | 多数候选被分数阈值 0.1 过滤 | 说明该收藏夹视频数量少或主题高度一致;可手动补充 |
| 单视频收藏夹没出关键字 | titles.length <= 2 → TF 模式 → 能提出来,但若全是停用词会被清空 | 手动添加关键字 |
如果你想二次开发
算法实现位于 src/utils/keyword-extractor.ts。你可以通过以下方式定制:
- 扩展停用词表:在源码的
STOP_WORDS集合里增删词条; - 调 n-gram 范围:修改
simpleTokenize的内循环len = 2 ~ 4; - 调整阈值:在调用
extractKeywords(titles, options)时传入自定义maxKeywords / minScore / minLength; - 接入真实分词:如果你希望更精细,可以把
simpleTokenize替换为 jieba-wasm / segmentit 等库,其他逻辑不变。