一、关键词与应用
关键词(Keywords)是最能代表一篇文档主题的少量词语。自动提取关键词是许多系统的基石:
- 搜索与检索:用关键词建立倒排索引、做文档召回;
- 内容运营:自动打标签、生成新闻热榜、相关文章推荐;
- 文本摘要与问答:先抓关键词,再围绕关键词组织答案;
- 舆情监控:监控品牌、事件关键词的热度与情感变化。
关键词方法分两大流派:无监督的 TF-IDF、TextRank(无需标注,拿来即用)和有监督的关键词序列标注(精度高但需要标注语料)。本章聚焦两个最经典的无监督算法。
二、TF-IDF 原理
TF-IDF 由两部分相乘构成:
词频 TF(Term Frequency)
一个词在当前文档出现得越多,越可能与主题相关:
TF(t, d) = 词 t 在文档 d 中出现的次数 / 文档 d 的总词数
逆文档频率 IDF(Inverse Document Frequency)
但「的、是、在」这类词处处出现,并没有区分度。IDF 对普遍常见的词降权,只在少数文档出现的词反而权重高:
IDF(t) = log( 文档总数 N / 包含词 t 的文档数 DF(t) )
最终:
TF-IDF(t, d) = TF(t, d) × IDF(t)
工程实现中常对 IDF 做平滑,避免词从未出现导致除零:
IDF(t) = log( (N + 1) / (DF(t) + 1) ) + 1
TF-IDF 的局限:不考虑词序与语义,「不喜欢」和「喜欢」会被同等对待;对短文本统计不稳;高频但确有实义的领域通用词可能被误伤(可用自定义 IDF 表修正)。
三、用 Python 实现 TF-IDF
方法一:直接调用 jieba 内置的 TF-IDF(自带一份 IDF 语料库):
python · jieba 关键词import jieba.analyse
doc = """自然语言处理是人工智能的重要分支。中文分词、关键词提取、
文本向量化是自然语言处理的基础技术。问答机器人则综合运用了
语义分析与情感分析技术,为用户提供智能问答服务。"""
for word, weight in jieba.analyse.extract_tags(doc, topK=8, withWeight=True):
print(f"{word}: {weight:.4f}")
# 自然语言处理 0.62 / 问答机器人 0.41 / 关键词 0.33 / ...
方法二:用 scikit-learn 对一批文档计算完整 TF-IDF 矩阵(第五章还会用到):
python · sklearnfrom sklearn.feature_extraction.text import TfidfVectorizer
import jieba
docs = ["自然语言处理 是 人工智能 的 分支",
"问答机器人 运用 语义分析 与 情感分析",
"中文分词 是 自然语言处理 的 基础"]
# 用 jieba 分词后用空格连接,再交给 sklearn
tok_docs = [" ".join(jieba.lcut(d)) for d in docs]
vec = TfidfVectorizer(stop_words=["的", "是"])
matrix = vec.fit_transform(tok_docs)
print(vec.get_feature_names_out()) # 词表
print(matrix.shape) # (3 篇文档, 词表大小)
print(matrix.toarray()) # 每篇文档的 TF-IDF 向量
四、TextRank 算法
TextRank 源自网页排序算法 PageRank,核心思想是「投票」:一个词被越多重要的词共现,它自己也越重要。
- 分词与过滤:切词后只保留名词、动词等实词;
- 构建词图:滑动窗口(如大小为 5)内共同出现的词之间连一条无向边;
- 迭代投票:每个节点把分数均分给邻居,反复迭代直至收敛,公式为
WS(Vᵢ) = (1-d) + d × Σ 邻居的加权贡献,阻尼系数 d 通常取 0.85; - 排序输出:得分最高的若干词即关键词,相邻关键词还可拼接成关键短语。
python · jieba 的 TextRankfrom jieba.analyse import textrank
for word, weight in textrank(doc, topK=8, withWeight=True):
print(word, round(weight, 4))
与 TF-IDF 相比:
| TF-IDF | TextRank | |
|---|---|---|
| 所需语料 | 需要多篇文档统计 DF | 单篇文档即可 |
| 依据 | 词频的全局稀有度 | 词在词图中的共现关系 |
| 适用 | 大规模语料批量处理 | 单文档、长文摘要前处理 |
| 代价 | 快 | 需构建图并迭代,略慢 |
五、主题模型 LDA 简介
当目标不是为单篇文档抽词,而是发现整个语料库隐含的若干主题时,可以使用 LDA(Latent Dirichlet Allocation)主题模型。
它假设每篇文档是多个主题的混合,每个主题又是一组词的概率分布。例如从大量新闻中可自动学出:主题 A「比赛、球队、冠军、球员」,主题 B「股市、利率、基金、上涨」。
python · gensim LDA(示意)from gensim.corpora import Dictionary
from gensim.models import LdaModel
texts = [["比赛", "球队", "冠军"],
["股市", "基金", "上涨"]]
dictionary = Dictionary(texts)
corpus = [dictionary.doc2bow(t) for t in texts]
lda = LdaModel(corpus, id2word=dictionary, num_topics=2, passes=10)
print(lda.print_topics())
六、交互演示:亲手算 TF-IDF
在下方输入多篇文档(文档之间用空行分隔),点击计算,再用下拉框切换查看每篇文档的 TF-IDF 关键词。注意观察:在多篇文档中反复出现的词,分数会被 IDF 压低。
试试把某个词加入所有文档(例如都写上「自然语言处理」),再看它在结果中的排名变化——这就是 IDF 在起作用。