目标:单一算法各有噪声,把多种结果交叉验证或合并,再接入停用词、词性过滤和批量处理,形成可用的主题词提取流程。
1. 交集与并集:用多算法投票降低噪声
有研究对比了 TF-IDF、TextRank、LDA 两两交集与并集的效果,发现“先两两相交再取并集”既能过滤单一算法产生的噪声词,又能弥补交集造成的信息损失。一个实用的融合策略是:
取 TF-IDF 前 20 和 TextRank 前 20 的交集,得到高置信度核心词;
再与 LDA 某主题下的高概率词取并集,补充语义相关但词频不高的主题词。
python
import jieba.analyse def fuse_keywords(text, topk=20): tfidf_words = set(w for w, _ in jieba.analyse.extract_tags(text, topK=topk, withWeight=True)) textrank_words = set(w for w, _ in jieba.analyse.textrank( text, topK=topk, withWeight=True, allowPOS=('ns', 'n', 'vn', 'v', 'nt') )) # 高置信度交集 core = tfidf_words & textrank_words # 并集作为候选池,可再按业务规则筛选 union = tfidf_words | textrank_words return core, union2. 生产化过滤:停用词、词性、长度与业务黑名单
真实语料里,“用户”“问题”“进行”这类词在统计上可能权重不低,但对主题表达没有价值。除了通用停用词表,建议再加一层业务黑名单和词性白名单。
python
# 业务黑名单示例 domain_stopwords = {"用户", "问题", "进行", "一个", "没有", "可以", "这个"} # 词性过滤:只保留名词、动名词、专名 allow_pos = ('n', 'ns', 'nt', 'nz', 'vn', 'v') def clean_keywords(words, extra_stop=None): stop = domain_stopwords | (extra_stop or set()) result = [] for w in words: if w in stop: continue if len(w) < 2: continue # 可选:用 jieba.posseg 判断词性 result.append(w) return result3. 批量处理与输出
实际使用时通常是一批文档一起处理。下面的模式可以复用于新闻列表、评论集合或工单文本:
python
import csv def batch_extract(docs, topk=10): rows = [] for doc_id, text in enumerate(docs): tfidf = jieba.analyse.extract_tags(text, topK=topk) tr = jieba.analyse.textrank(text, topK=topk, allowPOS=('ns', 'n', 'vn', 'v')) fused_core = set(tfidf) & set(tr) rows.append({ "doc_id": doc_id, "tfidf": ",".join(tfidf), "textrank": ",".join(tr), "core": ",".join(fused_core), }) with open("topic_words.csv", "w", newline="", encoding="utf-8-sig") as f: writer = csv.DictWriter(f, fieldnames=["doc_id", "tfidf", "textrank", "core"]) writer.writeheader() writer.writerows(rows)github.0voice