AI赋能文献检索聚类分析,这句话放到去年我会觉得是个“科研项目管理术语”,但这半年帮课题组做完两轮长篇综述之后,我可以负责任地说:它已经在实实在在改变文献调研的工作方式。过去接到一个陌生研究方向,我会去数据库里筛关键词,导出两三百条记录,再用Excel手工分类;运气好一天能分完,运气不好反复调整分类标准,越分越乱。现在我的流程很固定:把文献的标题和摘要批量转成语义向量,交给聚类算法自动切出若干主题簇,再用大模型给每个簇命名,最后回到原文抽检。整个过程通常一个晚上就能完成,而且覆盖宽度和分类粒度比手工整理稳定得多。
这篇内容不是讲空泛的“AI+科研”概念,而是把整套链路拆开:从数据获取、文本清洗、向量化、降维聚类,到结果解读和论文落地,每一步都给出我实际使用的方案、代码片段和参数。适合正在做综述、开题、文献调研的研究生,也适合想给组里搭建一套文献分类流程的科研工作者。
1. 传统文献整理方式的痛点:为什么我换成AI聚类
先聊一个最真实的场景。我之前需要调研“机器学习在电池材料领域的应用”,关键词一换就出一批新文献:同一篇工作可以是“预测电池寿命”,也可以被库里的关键词标记为“数据驱动”“状态估计”“健康管理”。要保证不漏检,我得把变体词全部拼一遍,得到的结果是800多篇文献,然后按研究方向人工分类。这个过程最大的问题不是累,而是标准不稳定。
1.1 关键词检索的语义断裂
关键词检索本质是词面匹配,它处理不了三个常见问题。
一是同义改写。同一种方法,有人写“natural language processing”,有人写“text mining”,还有人用“NLP”缩写。你在检索式里漏掉任何一个变体,就会漏掉一批重要文献。二是跨语言差异。中文文献和英文文献用的是两套词表,但研究的可能完全是同一个子方向。三是语境歧义。“Transformer”在电力领域指变压器,在深度学习领域指模型架构,在语义检索里它是词向量模型,关键词系统根本做不到语境理解,只能一起返回,然后靠人工二次过滤。
这些问题的本质是文献检索停留在“字符匹配”层面,没有进入“语义理解”层面。而AI嵌入向量本身就携带语境信息,它能把不同词面、相似意思的内容映射到空间里的邻近位置,这是传统检索方式很难做到的。
1.2 手工分类的三重困境
传统聚类分析在情报学里并不新鲜,共词分析、引文耦合、文献计量都是老办法。但落到实际工作中,它们的使用门槛和粒度问题一直存在。手工分类就更费力了,我总结下来有三个无法回避的困境。
第一,分类标准随进度漂移。第一天我把“数据驱动建模”设为一个类,第三天发现文献量太大,又想把“深度学习生命周期预测”单独拆出来,结果前两天的分类又得重来。这种主观标准的不稳定会导致综述的统计口径前后矛盾。第二,文献体量与时间不成比例。几百篇文献手工分类,每篇都要读标题、摘要、必要时翻正文,一天最多处理一百篇,而且注意力下降后误判率激增。第三,新主题难以发现。手工整理只能按预设框架去套,那些跨多个主题的“桥梁型文献”和新兴交叉方向,很容易被忽略或硬塞进旧分类里。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 整体思路与技术选型:从Embedding到聚类的完整链路
我现在的做法可以概括成五步:数据采集、文本清洗、向量化、降维聚类、语义解读。每一环节都会直接影响最终分类质量,下面把链路完整拆开。
2.1 从“词面匹配”到“语义空间”
先把基础概念讲清楚。传统TF-IDF或BM25把一篇文章表示成一个高维稀疏向量,向量的每一维是一个词,文章之间的相似度取决于共同出现多少词。这种表示方式计算简单、可解释性强,但语义泛化能力很差。后来的LDA主题模型能生成主题分布,却需要预设主题数,而且面对短文本(比如只有标题和摘要的文献记录)效果往往不稳定。
现在更常用的方案是Transformer编码器,它把一段文本编码成一个稠密向量,这个向量被称为文本嵌入。两篇文献如果语义相似,它们在向量空间中的距离就更近。比如“使用循环神经网络预测锂电池剩余使用寿命”和“基于RNN的电池健康状态估计”,词面重合度很高,比较容易命中;而“数据驱动方法评估电动汽车电池老化”和上两句的表达差异很大,词面重合度低,但语义指向相同,在向量空间里依然会靠在一起。这一步就把“文献检索”从关键词匹配升级成了语义匹配,而聚类分析可以直接在这个语义空间中完成。
2.2 五步链路与关键问题
用超市货架来类比这条链路会更好理解。传统方法是先定好货架编号(预设分类),然后一本一本找书放进去。我的做法是让所有书先站到空地上,观察它们和哪些书长得像、内容相近,再让系统自动给出分组的建议。药品类会聚在一起,烹饪书籍会聚在一起,甚至能自动发现“健康饮食”和“疾病预防”之间存在一个交叉区域。
这里有一个容易混淆的点:AI聚类不帮你直接判断“这篇文献属于哪个主题”,它只负责告诉你“哪些文献彼此更接近”。主题到底是什么,最后还要靠人或者大模型去命名。所以整条链路的设计原则是:让聚类算法做分组,让人和大模型做解释。
下面这张表是我在做技术选型时经常对照的底稿:
| 环节 | 要考虑的问题 | 我常用的方案 |
|---|---|---|
| 数据获取 | 数据源是否免费、是否有API、字段是否完整 | Semantic Scholar、OpenAlex、arXiv |
| 文本清洗 | 是否缺摘要、是否有乱码、字段如何合并 | 优先级:摘要+标题+关键词,缺失时降级 |
| 向量化 | 中文还是英文、算力多少、本地还是API | 本地BGE系列,英文场景也可用API |
| 降维 | 样本量大不大、要不要可视化 | UMAP先降到50维再做聚类 |
| 聚类 | 是否知道簇数、是否有离群文献 | HDBSCAN,其次K-Means |
| 解读 | 簇标签怎么命名、如何避免幻觉 | 代表文献+关键词交给大模型,再人工抽检 |
3. 文献数据获取与清洗:聚类的成败藏在第一步
数据获取这一步看似枯燥,却是影响聚类结果最多的一步。向量模型再强,喂进去一堆脏数据也白搭。我的建议是尽量使用结构化API和标准文献导出格式,而不是从PDF里抽文本。PDF解析会带来大量格式噪声,比如页眉页脚、双栏顺序、公式乱码,这些噪声在后续分词和向量化阶段都会被放大。
3.1 免费可靠的文献元数据源
我目前用得最多的是Semantic Scholar,原因是它的API免费,返回字段包含标题、摘要、年份、外部ID、引用数,而且对学术搜索的语义字段做了不少优化。OpenAlex的覆盖范围更广,适合大规模计量分析。如果你常用arXiv,也可以直接走它的API拉预印本元数据。Crossref则适合按DOI批量核对文档信息。实际使用中,我会先通过关键词从Semantic Scholar拉一批,再用DOI去Crossref补齐缺失字段。
给一段调Semantic Scholar API的示例代码,注意加上限速处理:
python复制import requests
import time
def search_semanticscholar(query, limit=100):
url = "https://api.semanticscholar.org/graph/v1/paper/search"
params = {
"query": query,
"limit": limit,
"fields": "title,abstract,year,externalIds,citationCount"
}
papers = []
for offset in range(0, limit, 100):
params["offset"] = offset
r = requests.get(url, params=params, timeout=20)
if r.status_code == 429:
time.sleep(5)
continue
r.raise_for_status()
papers.extend(r.json().get("data", []))
time.sleep(1) # 免费接口限流,必须慢一点
return papers
提示:免费接口没有API key也能用,但并发调高后很容易触发429限流。稳妥的做法是每两次请求之间至少间隔1秒,大批量抓取建议注册key,并把每批请求间隔降到0.5秒左右。这部分经验是在跑大范围调研的时踩出来的。
3.2 本地文献库导出文件的解析
很多研究生手头已经有一批文献,存在EndNote、Zotero或NoteExpress里。与其重新检索,不如把库里的文献导出成RIS或BibTeX,再脚本化解析。RIS格式是行结构的,标签很规整,解析起来不容易出错。这里给一个基于Python的解析示例:
python复制import re
def parse_ris(content):
records = []
current = {}
for line in content.splitlines():
if not line.strip():
continue
tag, _, value = line.partition(" - ")
if tag == "TI":
current["title"] = value.strip()
elif tag == "AB":
current["abstract"] = value.strip()
elif tag == "KW":
current.setdefault("keywords", []).append(value.strip())
elif tag == "PY":
current["year"] = value.strip()
elif tag == "ER":
records.append(current)
current = {}
return records
实际使用时要先观察自己导出文件里的分隔符到底是什么,不同软件导出的RIS在“ - ”的间距上可能略有差别。如果解析结果为空,优先检查这里,而不是怀疑脚本逻辑。
3.3 字段优先级与缺失处理
在做聚类时,向量模型需要的不是PDF全文,而是能概括文章核心的文本。我通常按这个优先级组成一条“语义文本”:标题 + 摘要 + 作者关键词。如果摘要缺失,就退化成“标题 + 关键词”;如果标题都没了,这条记录基本可以丢弃,因为语义信息太弱,放进聚类只会成为噪声点。
清洗时要处理的细节比想象中多。比如摘要里常见的数字编号前缀“1. Introduction”“2. Methods”,HTML转义符&,PDF复制产生的多余空格和换行,这些都要统一清理。我习惯用一个简单的清洗函数:
python复制import re
import html
def clean_text(text):
if not text:
return ""
text = html.unescape(text)
text = re.sub(r"\b\d+\.\s*", "", text) # 去数字编号
text = re.sub(r"\s+", " ", text) # 合并多余空白
return text.strip()
很多人在这个阶段偷懒,觉得“反正向量模型能理解语义,脏一点没关系”。但我的实测结论是:清洗做得好的3000条数据,聚类效果普遍优于未清洗的5000条数据。因为乱码和无意义字符会让向量被无关特征干扰,还会让后续的关键词提取产生垃圾词。数据质量永远优先于数据数量。
4. 文本向量化:中文、英文模型怎么选,坑在哪里
数据准备好后,下一步就是把文本变成向量。模型选型这一点上,我倾向于给出一个很直接的结论:中文文献优先用本地BGE系列,英文文献看规模选本地或API。先说为什么这样选。
4.1 模型选型的原则
中文文本的向量模型这些年进步非常快。北京智源人工智能研究院开源的BGE系列在中文语义匹配和检索任务上表现稳定,bge-large-zh-v1.5的向量维度是1024,对标题加摘要这种文本长度完全够用。如果你想在中文和多语言之间兼顾,可以试bge-m3,它支持100多种语言,而且做了稀疏向量和稠密向量的混合,信息保留更充分。
英文场景里,如果追求开箱即用,SentenceTransformers里的all-mpnet-base-v2表现不错。如果追求SOTA,可以上OpenAI的text-embedding-3-small或3-large,代价是每条文本需要调用API,费用按token算。做研究时我建议优先本地模型,理由有三:没有网络依赖,不会因为批量调用过慢或超时中断;摘要和全文数据不出本地机器,规避了敏感数据的上传问题;没有调用费用,跑大规模文献集不心疼。
4.2 本地BGE模型实测
给一段我在项目里直接用的向量化代码:
python复制from sentence_transformers import SentenceTransformer
model = SentenceTransformer("BAAI/bge-large-zh-v1.5")
texts = df["semantic_text"].tolist()
vecs = model.encode(
texts,
batch_size=32,
normalize_embeddings=True,
show_progress_bar=True
)
print(vecs.shape)
注意normalize_embeddings=True,这个参数会把向量归一化成单位向量,后续计算余弦相似度时数值更稳定,聚类前也省掉一次额外的标准化。另外要留意BGE系列的文档中有个“查询指令”的说明:对检索任务,模型官方建议给查询文本增加一个短指令,以提升匹配效果。但我们在做无监督聚类时,是对整篇文献的标题和摘要做向量化,不是做“查询-文档匹配”,所以不需要加指令。这是我最初踩过的一个坑,加了指令之后,同类文献的向量反而被带偏,聚类结果变得很碎。
4.3 长度截断与批量处理的细节
Transformer编码器都有最大输入长度限制,BGE系列通常是512个token。标题加摘要一般不会超,但也有例外:有些综述文献的摘要很长,或者作者的“结构化摘要”包含背景、方法、结果、结论四个大段。对于超长文本,我建议先看上下文长度分布,再做截断。截断策略上,保留开头和结尾比只留开头效果好,因为很多摘要的核心结论写在结尾,不过简单实现时直接截前面也算可用方案:
python复制from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("BAAI/bge-large-zh-v1.5")
max_len = 512
def truncate_text(text):
tokens = tokenizer.tokenize(text)
if len(tokens) <= max_len:
return text
return tokenizer.convert_tokens_to_string(tokens[:max_len])
得到向量后,建议直接保存为.npy或.npz文件,缓存到本地。原因很现实:重新跑一遍5000篇文献的向量化要几十分钟,而缓存能让你在调节参数时跳过这一步。我的习惯是清洗完文本先存一份CSV,向量化完存一份npy,后面对接任何可视化或聚类脚本都能快速读取。
5. 降维与聚类:K-Means、DBSCAN、HDBSCAN的实战选择
向量长度一般从768到1536不等,直接在这个高维空间上做聚类,会遇到“维度灾难”。距离度量在高维空间会变得不那么敏感,噪声项吃掉信号项,聚类结果出现大量碎片。所以我的流程是先降维,再聚类。
5.1 为什么要先降维到50维
很多教程直接让读者用UAMP降到2维之后聚类,这是个典型的错误。降到2维是为了给人类肉眼看,不是给算法聚类用的。2维空间丢失了太多结构信息,聚类出来的簇往往是视觉上的“一团”,而不是真正的语义簇。我的做法是把原始向量先用UMAP降到50维,在这个维度上保留足够的全局结构,再做聚类算法。最后需要可视化时,再对已经产生的簇中心或者原始向量单独降一次维到2维。
为什么是50维而不是10维或100维?这个数字来自UMAP官方和HDBSCAN文档中的常见建议,也符合我自己的实验观察。10维虽然跑得快,但容易丢失细节;50维给出的簇更稳定。如果你用的是BGE系列的1024维向量,从1024直接降到50维,可以在几分钟内完成;样本量特别大时,先降到100维再降到50维也可以,效果差别不大。
UMAP的示例代码:
python复制import umap
reducer = umap.UMAP(
n_components=50,
n_neighbors=15,
min_dist=0.1,
random_state=42
)
vecs_50d = reducer.fit_transform(vecs)
random_state一定要固定,否则每次运行UMAP结果都会不同,后面的聚类标签和可视化都会跟着变。n_neighbors控制局部邻近信息的范围,文献聚类场景我常用10到15之间;min_dist越小,点越容易聚成密集团,但太小时和噪声很难区分。在实际跑批时,我会先在小规模子集上试几组参数,确认簇数合理之后再跑全量。
5.2 三种聚类算法的选用逻辑
降维之后是聚类。我最常用的三个候选分别是K-Means、DBSCAN和HDBSCAN,它们的适用场景差异很大。
K-Means的优点是快、可解释性强,缺点是必须提前给定簇数K,而且它假设簇是近球形且规模相近。文献主题分布往往不均匀,有些大方向几百篇,有些新兴方向只有几篇,这时候K-Means的表现就不太好。如果你明确知道自己领域就是五六个大方向,K-Means完全可以胜任,用肘部法或轮廓系数选择K。
DBSCAN不需要指定簇数,基于密度聚簇,能找到任意形状的簇,还能把离群点标为噪声。但它对eps参数非常敏感,eps稍微调大就会把多个簇合并,调小又会产生大量碎片。文献数据经过UMAP降维后,每个簇的密度并不一致,DBSCAN很难通过单个参数同时兼顾稀疏和密集的簇。
HDBSCAN可以理解为DBSCAN的层次化改进,它对密度的变化更鲁棒,支持变密度的簇,也能自动把噪声点单独标出。文献聚类场景里,我的首选就是HDBSCAN。它可以自动决定簇的数量,并且会返回一个“噪声类”(标签为-1),这些点往往就是综述型文章、跨领域文章或是元数据质量太差的文献。带着这些点回到原文去看,会发现它们确实很难归属到单一主题。
5.3 参数配置与调参心得
以3000篇文献为例,我常用的HDBSCAN参数如下:
python复制import hdbscan
clusterer = hdbscan.HDBSCAN(
min_cluster_size=15,
min_samples=5,
metric="euclidean",
cluster_selection_method="eom"
)
labels = clusterer.fit_predict(vecs_50d)
min_cluster_size控制最小簇规模,定在10到20之间比较常见。如果设置太小,比如5,聚类结果会碎片化,产生几十个主题相近的小簇,综述没法用;设置太大又容易把两个独立主题硬揉在一起。min_samples更多影响聚类边界的松散程度,值越小越容易把边界点归入簇内,值越大边界点越容易变成噪声。我一般从5开始调。cluster_selection_method="eom"是HDBSCAN默认的“多余度最小的簇”选择策略,适合大多数文本数据。
调参的关键不是追求“所有文献都被分进簇里”,而是接受一定比例的噪声。这个噪声比例通常在10%到30%之间,取决于文献集本身的多样性。如果噪声比例超过了一半,说明特征提取或者清洗环节可能出了问题,先回去查数据,别急着调参数。
6. 让模型解释聚类结果:簇标签生成与领域图谱
聚类做完,你手里有了“每篇文献属于哪个簇”的标签,但簇本身还没有名字。这一步我交给大模型配合人工抽检共同完成,方法比想象中简单,但细节决定成败。
6.1 提取代表文献与簇内高频词
给大模型做输入前,我先为每个簇准备两类信息:代表文献和簇内关键词。代表文献可以通过距离簇质心最近来选,也可以用HDBSCAN给每个样本标记的“概率”或“异常度”来筛选。我一般选距离质心最近的5篇文献标题,交给模型概括主题;同时用TF-IDF统计每个簇合并文本后的top 15关键词,作为辅助参考。
关键词提取这一步,英文场景用CountVectorizer或sklearn.feature_extraction.text.TfidfVectorizer都行,注意加入自定义停用词。中文场景建议先做粗切词,因为默认的分词结果太碎,大量单字词会干扰关键词质量。我是用jieba配合停用词表处理的:
python复制import jieba
jieba.setLogLevel(60)
stopwords = {"我们", "研究", "方法", "问题", "分析", "基于", "一种"}
def extract_keywords(texts, topk=15):
corpus = [" ".join([w for w in jieba.cut(t) if w not in stopwords and len(w.strip()) > 1])
for t in texts]
vec = TfidfVectorizer(max_features=200)
tfidf = vec.fit_transform(corpus)
word_scores = tfidf.sum(axis=0).A1
ids = word_scores.argsort()[::-1][:topk]
return [vec.get_feature_names_out()[i] for i in ids]
实际跑的时候你会发现,不同簇的清晰度差别很大。有些簇的高频词非常集中,一眼就看出是“电池寿命预测”;有些簇的关键词东一个西一个,很可能是聚类算法把不该合并的文献合了,或者这类文献本身是跨领域的。遇到后一种情况,可以把簇拆开重跑,也可以接受它为“混合簇”,在综述里单独处理。
6.2 用LLM生成主题标签与综述骨架
给大模型的提示词,我建议写清楚三件事:角色、素材、要求。一个我常用的模板是这样的:
text复制你是情报学专家。下面是一组成对出现的文献标题和关键词,来自同一个主题簇。请为这个簇给出:
1. 1-10字的中文主题名
2. 一段150字以内、说明该主题研究脉络的话
3. 建议是否拆分为2个子主题
文献标题:{titles}
关键词:{keywords}
给模型的素材越具体,幻觉越少。我会把标题和关键词原样放进去,先不给人为翻译,让模型自己理解。生成结果出来后,要求模型给出“该簇代表性文献列表”,方便人工抽检。这一步很关键:如果模型给出的主题名和代表文献对不上,说明这簇数据有问题,不要强行采用。
还有一个经验:大模型的命名能力很强,但命名时容易出现“过度抽象”。比如给簇起名叫“智能算法优化与应用”,这种标签等于没起。我在提示词里加了一条限制:“主题名必须能具体反映该簇的代表性方法或研究对象,避免泛泛而谈。如果无法从素材中提炼,请回复‘需要人工复核’。”加了这条后,标签质量明显提升。
6.3 簇间关系与领域地图
有了簇标签,我会对每个簇的质心向量再做一次层次聚类或者UMAP降维可视化,把簇与簇之间的距离关系直观呈现出来。这一步能帮你看到哪些研究方向彼此靠近,哪些是孤立方向。那种位于两个大簇中间的文献,往往是交叉研究,做综述时单独设一个“交叉前沿”小节,会显得你整理得很精细。
我自己实际跑出来的一次结果是这样的:一个关于“机器学习在锂电池领域应用”的300篇文献集,被HDBSCAN自动分成6个主簇,包括“容量衰减预测”“电解液配方优化”“充电策略与寿命”“老化机理分析”“材料筛选与发现”和“电池管理系统状态估计”。还有大概15%的文献被标记为噪声,抽查后发现多数是综述性论文或者只带短摘要的研究短文。这个结果直接构成我那一章综述的小节框架。
7. 完整案例:从一批文献到清晰的研究版图
前面讲的是单个环节,把这套流程串起来跑一遍,总共需要多少时间?我用一个可复现的Mini项目来说明。
假设目标是调研“数据驱动方法在电池健康管理中的最新进展”。我先生成检索词集合,用Semantic Scholar API抓了300条文献元数据。清洗后构造“标题+摘要”文本,用BGE中文模型向量化,跑出来的向量大概是300×1024的矩阵。这一步在普通办公电脑上用CPU跑,耗时大概两分钟,GPU会更快。
随后用UMAP降到50维,HDBSCAN聚类。根据领域经验,我把min_cluster_size设为12,min_samples设为5,得到5个主簇和15%的噪声点。5个主簇分别是大致对应的研究主题。为了可视化,我再用一次UMAP降维到2维,用matplotlib画散点图,颜色按簇标签区分。这个图看起来就是文献主题地图,不同颜色在平面上自然分成几块。
下面是整个流程的核心骨架代码:
python复制corpus = (df["title"] + " " + df["abstract"]).tolist()
vecs = model.encode(corpus, normalize_embeddings=True)
reducer_50 = umap.UMAP(n_components=50, random_state=42)
vecs_50d = reducer_50.fit_transform(vecs)
clusterer = hdbscan.HDBSCAN(min_cluster_size=12, min_samples=5)
labels = clusterer.fit_predict(vecs_50d)
# 可视化
reducer_2d = umap.UMAP(n_components=2, random_state=42)
coords = reducer_2d.fit_transform(vecs)
df["x"], df["y"], df["cluster"] = coords[:, 0], coords[:, 1], labels
跑完之后,我会把每个簇的代表文献打印出来,逐簇核对。核对时不需要全看,每簇随机抽5篇,看标题和摘要描述是否和模型生成的标签一致。我通常要求准确率在85%以上才把这套结果用于正式综述。如果某簇准确率不达标,优先调整min_cluster_size,而不是min_samples。因为min_cluster_size控制的是“聚拢多少人算一个主流方向”,这个更接近你的领域直觉。
整个流程从抓取到核对结束,大约需要40分钟,其中人工核对的15分钟必不可少。对比原先手工整理两到三天的耗时,这个效率提升非常明显。
8. 我踩过的坑和值得保留的习惯
最后把这些年使用这套方法积累的经验集中说一下,很多是在实际操作中碰过的雷区。
8.1 高频踩坑点
第一个坑是直接用2维UMAP结果做聚类,导致簇边界看着清楚,实际主题混乱。解决方法是先降到50维,再聚类,最后为了可视化另跑一次2维降维。
第二个坑是给BGE模型的无监督聚类任务误加了检索用的查询指令。我在这上面吃了不少亏,后来在代码里明确区分“用于检索”和“用于聚类”两种编码方式,聚类时不加指令,语义稳定性反而更好。
第三个坑是不固定随机种子。UMAP和HDBSCAN都有随机因素,不固定状态,同一批数据每次跑出来的簇都不一样。在八股里固定random_state,写研究报告时也方便复现。
第四个坑是忽视摘要缺失带来的噪声。很多文献只有标题没有摘要,如果整个数据集里这类记录占比较高,聚类时会产生大量“标题噪声”。我的做法是把这些记录单列,不在主聚类中强行处理。
第五个坑是数据量太小。少于50篇文献时,聚类结果往往不稳定,U型曲线偶然性很强;这时候手工分类反而更靠谱。AI聚类更适合百篇以上的规模,规模越大越能体现优势。
8.2 值得保留的好习惯
我给自己定了三条纪律。第一,每次聚类结果必须附带“簇-代表文献-主题名”三列表格,任何讨论都基于这个表格,避免口头讨论“感觉分得对不对”。第二,每次跑完至少人工抽检10%的文献,把抽检结果记录下来。如果某簇抽检全对,说明这个簇的边界清晰,可以在综述里直接使用;如果连续抽检都出错,就回到清洗和参数调整环节重新来一轮。第三,在项目的早期,先把聚类跑完再读原文,而不是边读边分类。这个顺序顺应了“先粗后细”的调研节奏,让我不至于在前十篇文章里就固化了整个综述的框架。
还有一个小技巧是:把第一轮聚类得到的簇,作为第二次聚类的“输入目录”,对每个簇内部再做一次子聚类。这样能构建出一个两级主题树:第一级是领域大方向,第二级是具体研究热点。做博士论文综述的时候,这种层级结构能直接演变成章节大纲,省掉了重新梳理结构的大量时间。
最后我想强调一点:AI聚类不是来替代判断的,它改变的是前期整理和分类的效率。它帮你快速搭建一个宽谱的领域框架,但什么该写进综述、哪些方向值得展开、哪些成果存在明显局限,这些判断仍然需要靠你回到原文去完成。省下来的时间,恰恰应该投入在真正有价值的精读和批判性思考上。我把这套流程已经用在了十几轮课题调研里,到目前为止,它还没有让我失望过。
