返回教程列表
文本分析基础教程主题模型BERTopic语义聚类主题演化

BERTopic 主题聚类完整教程:从抽象标签到主题拆分合并,再到时间演化与追问

几百份政策文件或几十份访谈稿,怎样看清它们主要在谈哪几件事?这篇教程顺着 BERTopic 的计算流程讲。长文先切成片段,再用语义向量衡量两段话意思有多近,经过 UMAP 降维和 HDBSCAN 按疏密聚类分成主题;主题数可以手动指定,也可以由四个聚类读数自动给出。关键词按 TF-IDF 算出,抽象标签根据关键词和它们在原文里的上下文起名。每一步都配公式和可以手算的例子,并对应到 TATOOLS 工具页上的参数。结果出来以后,可以在报告里合并、拆分或移出主题,生成新版本,没改的主题片段保持不变,改动记录能直接写进论文附录。文章还讲时间演化曲线怎样从正文里的时间说法读出年月,年份算错了怎样在报告里改;追问能问哪些问题,回答里的编号怎么来,怎么问更准。最后给出论文方法部分的写法示例。

作者:TATOOLS 研究团队|更新于 2026-09-17|22319 个字符|约 75 分钟读完

手里有三百份政策文件,或者四十份深度访谈的转写稿,第一个问题往往是这批材料到底在讲哪几件事。一份一份读能回答这个问题,只是很慢,读到后面,前面的印象也模糊了。主题模型(Topic Model,从大量文本里自动归纳话题的方法)就是用来回答这个问题的,它把文本归成若干主题,每个主题配一组关键词。

经典的 LDA(潜在狄利克雷分配,按词语一起出现的规律归纳主题)数的是词。【房价上涨让年轻人推迟结婚】和【住房成本高企,青年婚期后延】说的是一回事,切成词以后却没有一个词相同,LDA 很难把它们放到一起。BERTopic 是 Grootendorst 在 2022 年提出的主题模型。它先用语言模型把每段话变成一组表示意思的数字,意思相近的段落,这组数字也相近,于是能聚到一起,然后再从每一组里找出关键词。

在 TATOOLS 的【BERTopic 主题聚类】里【上传文档】,就能拿到主题清单,每个主题带关键词和一个概括出来的名字。报告还会画出主题之间的远近关系,列出每个主题的代表原文,统计主题随时间的变化。从切片段到算关键词,每一步的参数都在工具页上开放,可以按研究需要调整。结果出来以后,分得太细的主题可以合并,混在一起的可以拆开,每改一次生成一个新版本;也可以直接向这批材料提问,回答附原文出处。

这篇教程分三部分。第一部分顺着 BERTopic 的计算流程讲,从把长文切成片段一直讲到给主题起名字,也讲清工具页上每个参数改的是哪一步。第二部分讲结果出来以后怎样合并、拆分和移出主题,新版本重新算了什么。第三部分讲时间演化和追问,最后是论文里的写法。

01

BERTopic 分哪几步把文本变成主题

先看一个结果长什么样。一份 3,000 字的社区调研报告切成 10 个片段,6 个片段归入【住房负担】,3 个归入【养老服务】,剩下 1 个没有归入任何主题。从这组结果能读出,这份报告六成的篇幅在谈住房。

主题模型的输入是一组文本单位,输出是每个单位的主题归属和每个主题的关键词。在 BERTopic 里,一个单位只归入一个主题,或者被标为离群。用符号写出来是这样。

· · ·

输入:片段集合 D = {d_1, d_2, …, d_n}

输出:每个片段的主题归属 z_i ∈ {−1, 0, 1, …, K − 1}

      每个主题 k 的关键词表 (t_1, w_1), (t_2, w_2), …

z_i = −1 表示片段 d_i 没有归入任何主题,称为离群片段

LDA 假设每篇文档由几个主题按比例混合而成,一篇文档可以同时属于好几个主题。BERTopic 让每个片段只属于一个主题,一篇长文讲了几件事,靠把它切成片段来体现。上面那份调研报告就是这样,同一份报告的不同片段落进了不同主题。

Grootendorst 的论文把 BERTopic 写成一条流水线,前后几步各管一件事。判断两段话意思近不近,交给语义向量和聚类;主题用哪些词来描述,交给词频统计。两件事分开做,换掉其中一步,另一步照常工作。TATOOLS 按这条流水线实现,每一步都有对应的工具页设置和报告区块。

步骤 这一步做什么 工具页上的设置
切片段 把长文切成长度接近的片段 【文本分割窗口大小】
语义向量 把每个片段变成一个表示意思的向量 【嵌入距离】
降维 用 UMAP 把向量压到几维 UMAP 降维参数
定主题数 决定分成几个主题 【主题数量设置】【参数预设】
聚类 用 HDBSCAN 按疏密把片段分组 HDBSCAN 聚类参数
关键词 按 TF-IDF 给每个主题算关键词 文本向量化参数、停用词和词形合并
主题名 根据关键词和原文上下文起名字 【所属行业】

下面几节按这个顺序展开。

02

先把长文切成片段

一份 1,500 字的政策文件,前半部分谈财政补贴,后半部分谈监管要求。整篇当成一个单位,只能归进一个主题。按 300 字一段切开,大约得到 5 个片段,谈补贴的片段和谈监管的片段就能各自归进不同的主题。

分析单位(Unit of Analysis)是一次统计或判断针对的对象。BERTopic 在 TATOOLS 里的分析单位是文档片段,一份文件能切出多少片段,可以这样估算。

· · ·

n_f ≈ L_f / w

n_f:第 f 份文件切出的片段数

L_f:这份文件清理后的字符数

w:文本分割窗口大小(字符数)

例:L_f = 1,500,w = 300,n_f ≈ 5

切点尽量落在窗口长度附近的句号、问号或叹号处,每个片段接近一个意思完整的小段。每份文件单独切,一个片段里不会混进两份文件的内容。每个片段都记下来源文件和它在文件里的顺序,报告里的每条原文都能找回出处。

窗口大小决定一个片段装多少内容。

窗口 片段大致是什么样 适合的材料
较小,100 到 200 一两句话,一段只说一件事 访谈、评论、短新闻
中等,200 到 350 一个自然段 政策文件、调研报告
较大,350 到 500 几段连在一起,语境更完整 论文、长篇评论

片段数是后面所有占比的分母。某个主题有 60 个片段,全部片段有 400 个,这个主题的占比就是 60 / 400 = 15%,离群片段也算在分母里。

TATOOLS 工具页上的【文本分割窗口大小(字符数)】可以在 100 到 500 之间调,默认 300。切片段之前,工具会先清理文本。中文模式只保留汉字、数字和最常用的几种标点,夹在中文里的英文字母会在这一步去掉,英文材料要在【文档主要语言】里选英文。目录、致谢和参考文献也会被切成片段参与聚类,上传前最好删掉。报告【主题建模分析概览】里的【文档片段数】,就是这次一共切出的片段数。

03

说法不同的两段话,怎么认出是一回事

【房价上涨让年轻人推迟结婚】和【住房成本高企,青年婚期后延】切成词以后,没有一个词相同。按词来比,这两句话毫不相干;按意思来比,它们说的几乎是同一件事。

语义嵌入(Sentence Embedding,把一段话变成一组表示意思的数字)把每个片段映射成 d 维空间里的一个向量 v。训练好的嵌入模型会让意思相近的话落在空间里相近的位置。Reimers 和 Gurevych 2019 年提出 Sentence-BERT,让这类句子向量可以大规模计算,BERTopic 的第一步用的就是这类向量。两个向量有多近,最常用余弦相似度来量。

· · ·

cos(a, b) = (a · b) / (‖a‖ × ‖b‖)

余弦距离 = 1 − cos(a, b)

a · b:两个向量对应位置相乘再相加

‖a‖:向量 a 的长度,各分量平方和再开方

余弦相似度看的是两个向量的方向,取值在 −1 到 1 之间,越接近 1 方向越一致。用三个三维向量手算一遍,a = (1, 0, 1),b = (1, 1, 0),c = (2, 0, 2)。

比较 点积 长度相乘 余弦相似度 欧氏距离
a 和 b 1 √2 × √2 = 2 0.5 √2 ≈ 1.41
a 和 c 4 √2 × √8 = 4 1 √2 ≈ 1.41

a 和 c 方向完全相同,只是 c 长了一倍,余弦相似度是 1。按欧氏距离算,a 离 c 和 a 离 b 一样远。把向量先缩放到长度为 1,两种量法就对上了,单位向量之间的欧氏距离只由余弦决定。

· · ·

‖â − b̂‖² = 2 − 2 × cos(a, b)

例:cos(a, b) = 0.5,距离 = √(2 − 1) = 1

    cos(a, c) = 1,距离 = √(2 − 2) = 0

用词不同、意思相同的片段,靠语义向量才能聚到一起。访谈里的口语说法和政策文件里的书面说法谈的是同一件事,也能落进同一个主题。

TATOOLS 为每个片段计算一个语义向量。工具页【自定义参数】里的【嵌入距离】选余弦距离时,所有向量先缩放到长度 1 再进入下一步,后面比的就是方向;选欧氏距离,向量保留原来的长度。默认是余弦距离。

04

UMAP:向量太长,先压缩再分组

语义向量通常有几百甚至上千维。维度一高,任意两点之间的距离会变得差不多,最近的点和最远的点拉不开差距。Beyer 等人 1999 年专门分析过这个现象,它是维度灾难(Curse of Dimensionality,维度越高、距离越难区分远近)的一种表现。按疏密找分组的算法最怕这种情况,到处都一样稀,就找不出哪里密。

UMAP(统一流形逼近与投影,一种降维方法,由 McInnes、Healy 和 Melville 在 2018 年提出)先在原来的高维空间里给每个点找 k 个最近的邻居,连成一张邻居关系图;再在低维空间里摆放这些点,让邻居关系尽量保持原样。低维空间里两点的相似程度,用下面这条曲线计算。

· · ·

q_ij = 1 / (1 + a × d_ij^(2b))

d_ij:点 i 和点 j 在低维空间里的距离

a、b:由最小距离 min_dist 和散布参数 spread 决定的两个常数

取 a = 1、b = 1 作为示例,距离 0.5 时 q = 1 / 1.25 = 0.8,距离 1 时 q = 0.5,距离 2 时 q = 1 / 5 = 0.2。距离越远,相似程度降得越快。min_dist 调大,曲线在近处变平,邻居之间允许留出一定间隔;调小,邻居会被挤得更紧,一簇一簇更分明。

TATOOLS 工具页的【UMAP(把高维数据压成少数几个维度)降维参数】有四个滑块,距离度量设置里另有【UMAP 距离】,可选余弦或欧氏。

设置 范围 调小 调大
邻居数量 n_neighbors 2 到 50 更看重局部,小分组更容易显出来 更看重整体结构,相近的小分组容易连成大组
降维维度 n_components 2 到 15 压缩得更多,疏密对比更明显 保留的信息更多,需要更多片段才能分出疏密
最小距离 min_dist 0.001 到 0.5 点挤得更紧,簇更分明 点之间留出间隔,分布更均匀
散布参数 spread 0.1 到 3.0 整体分布更收拢 整体分布更舒展

邻居数量可以按片段总数来想。400 个片段、邻居数量 15 时,每个片段只参考离它最近的 15 个片段,占其余片段的 15 / 399 ≈ 3.8%。邻居数量调到 40,参考范围扩大到 40 / 399 ≈ 10.0%,局部的小分组更容易被周围的大组吸收。

UMAP 算出的低维坐标会随任务一起保存。第二部分讲的拆分主题,就是在这组坐标上重新分组,整批材料不用重算。

05

HDBSCAN:扎堆的成主题,零散的单列

从高处看一片乡村,房子密集的地方是一个个村子,村子之间零星散着几户人家。把片段看成房子,村子就是主题,零星的几户就是离群片段。按疏密分组的算法做的就是这件事,而且事先不用说好有几个村子。

HDBSCAN(基于密度的层次聚类,Campello、Moulavi 和 Sander 2013 年提出)先给每个点量一个核心距离,再用它把稀疏处的距离拉长。

· · ·

core_k(x) = x 到第 k 近的其他点的距离

d_mreach(x, y) = max{ core_k(x), core_k(y), d(x, y) }

k:最小样本数 min_samples

d(x, y):两点之间的原始距离

核心距离小,说明这个点周围很密。互达距离(Mutual Reachability Distance)取三个数里最大的一个,密集处的距离基本不变,稀疏处的点和别人的距离会被拉长。用一条直线上的四个点手算,A = 0,B = 1,C = 2,D = 10,k = 2。

离它最近的两个点 核心距离
A B(1)、C(2) 2
B A(1)、C(1) 1
C B(1)、A(2) 2
D C(8)、B(9) 9

A 和 B 的原始距离是 1,互达距离是 max{2, 1, 1} = 2。C 和 D 的原始距离是 8,互达距离是 max{2, 9, 8} = 9,D 被推得更远了。A、B 和 C 两两之间的互达距离都是 2,自成一组,D 离它们都在 9 以上。最小聚类大小设为 3 时,A、B 和 C 构成一个主题;D 单独一个点凑不成主题,标为离群,主题归属记作 −1。

算法接着把所有点按互达距离连成一棵树,从远到近逐级切断,得到一层套一层的分组。最小聚类大小决定多小的分组还算一个主题。最后要从这棵层次树里挑出最终的主题,EOM(超额质量法,偏向保留持续稳定的大组)和 Leaf(叶节点法,偏向切出最细的小组)是两种挑法。选择阈值 ε 让距离小于 ε 的相邻小组合并成一组。聚类结束后,HDBSCAN 还给每个片段算一个归属分数,取值 0 到 1,越接近 1,这个片段越靠近所在主题的密集核心。

TATOOLS 工具页【HDBSCAN(按疏密分层自动分类)聚类参数】开放了这一步的设置,【HDBSCAN 距离】决定原始距离 d(x, y) 怎么量。

设置 范围或选项 作用
最小聚类大小 min_cluster_size 2 到 50 一个主题至少要有多少个片段
最小样本数 min_samples 1 到 20,滑到 1 显示【自动】 核心距离里的 k,越大越保守,离群片段越多
选择阈值 cluster_selection_epsilon 0 到 0.1 距离小于它的相邻小组合并
选择方法 EOM、Leaf 偏向稳定的大组,还是细分的小组
HDBSCAN 距离 欧氏、曼哈顿、切比雪夫 原始距离的量法
计算概率 开或关 是否保留每个片段的归属分数

三种距离用两个点手算,x = (1, 2),y = (4, 6)。

· · ·

欧氏距离 = √((4 − 1)² + (6 − 2)²) = √(9 + 16) = 5

曼哈顿距离 = |4 − 1| + |6 − 2| = 3 + 4 = 7

切比雪夫距离 = max{|4 − 1|, |6 − 2|} = 4

欧氏距离是两点之间的直线距离。曼哈顿距离把每一维的差加起来,每一维的差异都算数;切比雪夫距离只看差得最大的那一维。

主题数有了目标值 K 以后,TATOOLS 先用你在工具页上设的这些参数跑一遍 HDBSCAN,再把主题数调到 K。聚出来的组比 K 多,就反复合并中心离得最近的两组,距离的量法和【HDBSCAN 距离】一致;比 K 少,就用 K 均值把片段最多的一组分成两半,每半至少 2 个片段。离群片段只由 HDBSCAN 决定,调主题数时不增也不减。只有当前参数下全部片段都被判为离群、一个组都没有时,才改用 K 均值把全部片段分成 K 组,这时片段没有归属分数。报告的【主题原文片段】按归属分数给每个主题的片段排序。

06

主题数怎么定:手动指定和自动发现

400 个片段,分成 6 个主题还是 10 个主题,两种结果可能都说得通。6 个主题对应材料里的几大议题,10 个主题把其中几个议题又分出了子话题。主题数决定的是看材料的分辨率,要按研究问题来选。

TATOOLS 工具页的【主题数量设置】有两种方式。【手动指定】用滑块直接定主题数,范围 2 到 200,工具页提示设到 20 个以上时,实际得到的主题数可能略少。【自动发现】让工具从数据里读出主题数,候选范围有上限,需要几十个细分主题时用【手动指定】。

自动发现在降维后的坐标上,用 K 均值聚类(K-Means,把点分成 K 组、让每组尽量围着自己的中心)把候选的 K 逐个试一遍,每个 K 算四个读数。

· · ·

组内平方和 W(K) = Σ_j Σ_{x∈C_j} ‖x − μ_j‖²

轮廓系数 s(i) = (b(i) − a(i)) / max{a(i), b(i)},整体取所有点的平均

CH 指数 CH(K) = [B(K) / (K − 1)] / [W(K) / (n − K)]

DB 指数 DB(K) = (1/K) × Σ_i max_{j≠i} (σ_i + σ_j) / d(μ_i, μ_j)

C_j 是第 j 组,μ_j 是它的中心。a(i) 是点 i 到同组其他点的平均距离,b(i) 是它到最近的另一组的平均距离。B(K) 是各组中心之间的离散程度,σ_i 是第 i 组的点到中心的平均距离。

读数 衡量什么 取哪个 K
肘部 组内平方和随 K 下降,在哪里突然变缓 拐点处的 K
轮廓系数(Rousseeuw,1987) 每个点离自己组近、离别的组远的程度 最大值处的 K
CH 指数(Caliński 与 Harabasz,1974) 组间分散和组内紧凑的比值 最大值处的 K
DB 指数(Davies 与 Bouldin,1979) 每组和最像它的那组有多难分开 最小值处的 K

手算两个读数。先看组内平方和从 K = 2 到 K = 6 怎样变化。

· · ·

K 2 3 4 5 6

W(K) 1000 520 300 260 240

比上一个少 480 220 40 20

到 K = 4 以后下降突然变缓,肘部在 K = 4。再看轮廓系数,某个点到同组其他点的平均距离 a = 2,到最近的另一组平均距离 b = 6,它的轮廓系数是 (6 − 2) / 6 ≈ 0.67,这个点明显更靠近自己的组。

TATOOLS 把四个读数汇成两个数。主结构读数优先取肘部位置,肘部落在候选范围外时,改取几条曲线近优位置的中位数。细分读数取轮廓系数和 DB 指数两条曲线最优位置附近最大的 K,而且不小于主结构读数。【参数预设】里的三种策略,就是在这两个读数之间选。

预设 选哪个主题数 主结构 6、细分 10 时 主结构 6、细分 9 时
保守策略 主结构读数 6 6
平衡策略 两个读数之和除以 2,向下取整 8 7
激进策略 细分读数 10 9

三种预设还同时设定了降维、聚类和关键词的一组参数,选中以后,这些值会显示在【自定义参数】卡片里。

参数 保守策略 平衡策略 激进策略
邻居数量 20 15 10
降维维度 3 5 8
最小距离 0.2 0.1 0.05
最小聚类大小 15 10 5
选择阈值 0 0 0.02
HDBSCAN 距离 欧氏 切比雪夫 曼哈顿
最频繁词汇数量 5,000 10,000 20,000
多样性参数 0.1 0.1 0.3
计算概率

保守策略看的是材料的主干,适合先摸清一批材料有哪几大块。已经知道有哪几块、想看细节时用激进策略,它会把子话题分出来。选【自定义参数】后,卡片里的每个设置都能自己改。TATOOLS 报告【主题建模分析概览】的【运行设置】记录了这次的主题数量模式和最终主题数。

07

关键词怎么算出来

一个谈住房的主题里,【我们】和【政策】几乎每个片段都有,【租金】【首付】【公积金】主要出现在这个主题的片段里。描述这个主题,后面三个词有用得多。算关键词要做的,就是给集中在本主题里的词打高分,给到处都有的词打低分。

TF-IDF(词频–逆文档频率,一个词在这段里常见、在别处少见的程度)是做这件事的经典办法。逆文档频率由 Sparck Jones 在 1972 年提出,Salton 和 Buckley 1988 年系统比较了各种加权方式。

· · ·

tfidf(t, d) = tf(t, d) × idf(t)

idf(t) = log(n / df(t))

tf(t, d):词 t 在片段 d 里出现的次数

df(t):包含词 t 的片段数

n:片段总数

手算一个小例子。一共 4 个片段,片段 1 和片段 2 属于住房主题。【租金】在片段 1 出现 2 次,在片段 2 出现 1 次,别处没有,df = 2,idf = log₁₀(4 / 2) ≈ 0.301。【我们】在 4 个片段里各出现 1 次,df = 4,idf = log₁₀(4 / 4) = 0。

片段 1 片段 2 住房主题得分,两段平均
租金 2 × 0.301 = 0.602 1 × 0.301 = 0.301 (0.602 + 0.301) / 2 ≈ 0.452
我们 1 × 0 = 0 1 × 0 = 0 0

BERTopic 原论文用的是类别级 TF-IDF(c-TF-IDF),把一个主题的所有片段当成一份大文档来算。

· · ·

W(t, c) = tf(t, c) × log(1 + A / f(t))

tf(t, c):词 t 在主题 c 全部片段里的出现频率

f(t):词 t 在所有主题里的总出现次数

A:每个主题平均包含的词数

TATOOLS 先给每个片段算 TF-IDF 向量,再在主题内部取平均,得分最高的词排在最前面,上面的手算例子就是这个算法。实际计算用的是 TF-IDF 的常用改进版本,词频取对数,idf 做了平滑,每个片段的向量缩放到长度 1,长片段不会因为字多占便宜。【向量化类型】选 Count 时,改为把主题内各片段的词频直接相加。

工具页的【文本向量化参数】和上方的词表设置一起决定哪些词有资格当关键词。

设置 范围或选项 作用
向量化类型 TF-IDF、Count 按集中程度打分,或者按出现次数打分
N-gram 范围 下限 1 到 3,上限 1 到 5,默认 1 到 2 关键词可以是单个词,也可以是连续几个词组成的短语
最小文档频率 min_df 1 到 10 一个词至少要在多少个片段里出现才保留
最频繁词汇数量 max_features 1,000 到 50,000 只保留出现最多的这么多个词参与计算
自定义停用词 自己填写 这些词不参与计算,留空时使用内置停用词表
词形合并 一行一组 分词后把几种写法并成一种再计数,原文不变

N-gram 上限调到 3,【住房 公积金 贷款】这样的三词短语也能成为关键词。词形合并写成【养老院:敬老院,老人院】,三种写法都按【养老院】计数,关键词表里只出现一次。最小文档频率设为 3,只在一两个片段里出现的生僻词会被排除,关键词更集中在反复出现的说法上。出现在绝大多数片段里的词也会被自动排除。

只按权重取词,排在前面的几个关键词可能意思差不多,比如【租金】【房租】【租房】挤在一起,关键词表读起来很重复。工具页【其他设置】里的【多样性参数】就是管这件事的。TATOOLS 先按权重给每个主题取 30 个候选词,再用最大边际相关(Maximal Marginal Relevance,MMR,一边看权重,一边避开和已选词重复)挑出 20 个。这个方法由 Carbonell 和 Goldstein 在 1998 年提出,BERTopic 的开源实现里也有同名的多样性参数。

· · ·

MMR(w) = (1 − λ) × s(w) / s_max − λ × max_{v∈S} cos(e_w, e_v)

λ:多样性参数,取值 0 到 1

s(w):候选词 w 的权重,s_max 是本主题最高的权重

S:已经选中的词

e_w:词 w 的语义向量

每一步选 MMR 最高的候选词,选够 20 个为止。λ = 0 时第二项消失,就是直接取权重最高的 20 个。选中的词保留原来的权重,并按权重排序,报告里权重图和排名曲线的读法不变。

手算一步。【租金】权重最高,已经选中。剩下两个候选,【房租】的相对权重是 0.9,和【租金】的余弦相似度是 0.9;【首付】的相对权重是 0.8,和【租金】的相似度是 0.3。

候选词 λ = 0 时的得分 λ = 0.5 时的得分
房租 0.9 0.5 × 0.9 − 0.5 × 0.9 = 0
首付 0.8 0.5 × 0.8 − 0.5 × 0.3 = 0.25

λ = 0 时,下一个选的是【房租】;λ = 0.5 时,下一个选的是【首付】,意思和【租金】重复的【房租】往后排。三档预设里,保守策略和平衡策略的多样性参数是 0.1,激进策略是 0.3。

最小文档频率设得太高,可能没有词满足条件,计算就进行不下去。TATOOLS 遇到这种情况会自动调低最小文档频率重试,报告【主题建模分析概览】顶部会出现【参数已自动调整】,写明从几调到几、调了几次。关键词算好以后,报告的【主题关键词权重】【主题词权重排名】和【主题—关键词得分矩阵】分别用条形图、排名曲线和矩阵展示它们。

08

抽象标签:给每个主题起一个人读得懂的名字

关键词表是一串排好序的词,比如【租金 首付 公积金 通勤 学区 房东】。研究者读到这串词,会自己把它们归成一件事,也许叫【住房负担与居住选择】。这个归纳出来的名字,就是抽象标签。

主题标注(Topic Labeling)是主题模型研究里的一个专门问题。Mei、Shen 和 Zhai 2007 年最早系统研究自动给主题起名,先从语料里找出候选短语,再按候选短语和主题词分布的语义相关程度挑出最合适的一个。Lau 等人 2011 年把候选名扩展到维基百科的条目标题,再用排序模型挑选。大语言模型出现以后,直接读关键词和原文、概括出一个短名字,成了常见做法。

主题名把研究者的解读压缩成几个字,方便在报告、论文和编码表里指称一个主题。它本身就是一种解读,读的时候要和关键词、代表原文对照着看。关键词告诉你这个主题里常出现什么词,原文告诉你这些词在谈什么。

TATOOLS 给每个主题起名分三步。

1

取这个主题得分最高的几个关键词。

2

在原文里找到每个关键词出现的位置,截取它前后的一小段文字作为上下文。

3

把关键词、上下文和工具页选定的【所属行业】一起交给语言模型,要求写出一个简短的名字,概括这些词共同指向的意思,不能直接把关键词拼起来,也不能带【主题】二字。

所有主题同时起名。生成的名字不符合要求时,这个主题显示为【主题 N】。

【所属行业】给语言模型一个领域背景,工具页上有 13 个选项,从通用领域到政府与政策都有。同一组关键词放在不同领域里,会读出不同的意思。

关键词(示例) 所属行业 可能起出的名字(示例)
流量 转化 投放 复购 电商与零售 店铺引流与复购运营
流量 转化 投放 复购 文化创意与传媒 内容传播与受众转化
轮候 配租 保障 审核 政府与政策 公租房申请与配租

主题名在报告里多处出现。【这份结果说明了什么】列出前几个主题名,【主题建模分析概览】的【主题与关键词】把每个主题名和它的关键词放在一起。【主题分布散点图】和【文档片段分布图】勾选【显示主题标签】后,名字直接标在图上。追问时,TATOOLS 也靠主题名认出问题点到了哪个主题。

TATOOLS 还会为每个主题另起一个章节或编码名称,写在【章节或编码名称草案】表里,这个名字更适合直接用作论文小节标题或编码表条目。这张表同时按主题片段占全部片段的比例给出建议位置。

片段占比 按占比建议的位置
20% 及以上 报告重点章节
10% 及以上,不到 20% 独立小节
5% 及以上,不到 10% 合并讨论
不到 5% 附录/补充

09

工具页上的设置分别改哪一步

TATOOLS 的【BERTopic 主题聚类】把流水线每一步的设置都放在了工具页上。常用的设置在页面上方,降维、聚类和关键词的细节参数在【自定义参数】卡片里,【参数预设】选中【自定义参数】后就能逐项修改。下表按工具页从上到下的顺序列出这些设置。

设置 范围或选项 作用在哪一步
文档主要语言 中文、英文 清理文本、分词和停用词表
主题时间演化基准 年月,可以不填 时间演化,文件里找不到时间锚点时兜底
自定义停用词 自己填写 关键词
词形合并 一行一组 关键词
所属行业 13 个领域 主题名和章节名
主题数量设置 手动指定、自动发现 定主题数
固定主题数量 2 到 200 定主题数,手动指定时使用
文本分割窗口大小 100 到 500 字符 切片段
参数预设 保守、平衡、激进、自定义 定主题数,并批量设定下方参数
嵌入距离 余弦、欧氏 语义向量
UMAP 距离 余弦、欧氏 降维
邻居数量、降维维度、最小距离、散布参数 见 UMAP 一节 降维
HDBSCAN 距离 欧氏、曼哈顿、切比雪夫 聚类
最小聚类大小、最小样本数、选择阈值、选择方法 见 HDBSCAN 一节 聚类
计算概率 开、关 归属分数
向量化类型、N-gram 范围、最小文档频率、最频繁词汇数量 见关键词一节 关键词
多样性参数 0 到 1 关键词

按研究需要调参数,可以从下面几种情况入手。

想要的效果 先调哪个设置
主题分得更粗,先看大块 【保守策略】,或【手动指定】一个较小的数
主题分得更细,看子话题 【激进策略】,或【手动指定】一个较大的数
一个片段里只说一件事 调小【文本分割窗口大小】
离群片段少一些 调小【最小样本数】或【最小聚类大小】
关键词里少出现泛泛的词 把这些词补进【自定义停用词】
同一个说法的几种写法合成一个关键词 【词形合并】
关键词里少出现意思相近的词 调大【多样性参数】
关键词里多出现固定搭配 把 N-gram 上限调到 3
主题名更贴近研究领域 选对【所属行业】
已经分好,只有个别主题不满意 在报告里合并、拆分或移出,第二部分会讲

同一批材料换一组设置再跑一次,会得到一份新的结果,比较几次运行时可以参考下一节的模型评估分数。

10

模型评估分数怎么读

TATOOLS 报告的【主题建模分析概览】给出【模型评估综合分】和【模型评估等级】,下面的【各项评分】列出六项分数。综合分是六项分数的加权平均。

· · ·

S = Σ_d w_d × s_d / Σ_d w_d

s_d:第 d 项评分,取值 0 到 1

w_d:第 d 项的权重

评分项 看的是什么 权重
聚类质量 轮廓系数、CH 指数和 DB 指数,各主题大小是否均衡,离群片段多少 25%
主题词连贯性 关键词得分是否集中,同一主题片段的语义向量是否紧凑,主题之间的关键词是否区分得开 25%
主题差异度 词汇的丰富程度,主题大小的差异,主题之间的语义差异 15%
参数匹配度 降维、聚类和关键词参数与材料规模是否相称 15%
数据适配性 片段数和主题数是否合适,离群片段比例,片段覆盖情况 15%
运行稳定性 计算过程是否稳定收敛 5%

按上表的顺序给六项分数假设一组数值,代入公式手算一遍。

· · ·

S = 0.25 × 0.62 + 0.25 × 0.70 + 0.15 × 0.55 + 0.15 × 0.80 + 0.15 × 0.66 + 0.05 × 0.90

  = 0.155 + 0.175 + 0.0825 + 0.120 + 0.099 + 0.045

  = 0.6765 ≈ 67.7%

综合分 模型评估等级
80% 及以上 优秀
60% 及以上,不到 80% 良好
40% 及以上,不到 60% 中等
20% 及以上,不到 40% 较差
不到 20%

67.7% 落在良好一档。这个分数衡量的是聚类结构和参数设置,同一批材料换几组设置各跑一次,可以用它比较哪次运行的结构更清楚。主题名起得贴不贴切、主题对研究问题有没有用,要回到代表原文里判断。

11

报告前半部分怎么读

TATOOLS 的报告从上到下排了十几个区块,主题编辑、时间演化和追问放在后面两部分讲,其余区块可以分五层读。

层次 区块 先看什么
总览 【这份结果说明了什么】【主题建模分析概览】 片段数、主题数、离群片段占比,主题名和关键词
主题之间 【主题分布散点图】【主题层级关系图】【不同层级的文档片段分布】 哪些主题挨得近,能不能归成更大的一类
主题内部 【主题关键词权重】【主题词权重排名】【主题原文片段】【主题文档片段占比分布】【主题—关键词得分矩阵】 每个主题靠哪些词撑起来,原文在谈什么,占多大比例
片段 【文档片段分布图】 每个片段落在哪里,离群片段在什么位置
写作 【章节或编码名称草案】【写作结构草案】 章节名、建议位置和章节结构

几个区块要多看一眼。

1

【主题分布散点图】里一个圆点是一个主题,圆点位置用来比较主题之间的相对远近,点击圆点可以看这个主题的详情。

2

【文档片段分布图】里一个圆点是一个片段,颜色表示所属主题,圆点大小和圆点距离都能调。

3

【主题层级关系图】用 Ward 层次聚合(Ward,1963,每次合并让组内离散程度增加最少的两组)把相近的主题一级一级合并。【不同层级的文档片段分布】里 L0 是原来的主题,层级越高,合并得越多。

4

【主题原文片段】每个主题最多列 5 个片段,按归属分数排序,每条最多显示 200 个字符,关键词在片段里标出。

5

【主题文档片段占比分布】按片段数排序,条形长度是这个主题的片段占全部片段的比例,分母包含离群片段。

6

【写作结构草案】根据主题名和关键词,结合片段数和截断后的原文片段生成,每节写明对应的主题编号和论述方向。

12

主题分得不满意,在报告里直接改

一份结果有 12 个主题,读完代表原文,研究者往往会有自己的判断。主题 2【保障房申请流程】和主题 5【公租房轮候】,对这项研究来说是同一件事;主题 8 里一半片段谈养老床位,一半谈医保报销;主题 11 全是会议通知里的套话。这三个问题可以直接在报告里处理,前面的计算都不用重做。

研究者看完模型给的结果,动手调整,再让模型重新算,是主题模型研究里专门讨论过的做法。Hu、Boyd-Graber、Satinoff 和 Smith 2014 年提出交互式主题模型,让使用者告诉模型哪些词应该放在一起。Smith 等人 2018 年做了一套可以合并和拆分主题的系统,还请用户试用,检验这些改法是否顺手。做质性研究的人对这件事更熟悉,编码的合并与拆分本来就是整理编码本的常规步骤,Saldaña 的《质性研究编码手册》里,第二轮编码的主要工作之一就是把第一轮的编码归并和重新分类。

TATOOLS 改主题时,已经生成的结果保持原样,每次改动生成一个新版本。

· · ·

R_(v+1) = F(S_v, O)

S_v:第 v 版存下来的结果,包括片段、语义向量、降维坐标、主题归属和识别出的时间表达

O:这次要做的改动

F:按改动重新计算报告

新版本直接沿用上一版的语义向量、降维坐标和聚类结果,只按你的改动改写主题归属。没有被改的主题,片段一个都不变,两个版本之间的差别只来自你的改动。

合并

合并把几个主题的片段并成一个主题。

· · ·

C_new = C_a ∪ C_b ∪ …

|C_new| = |C_a| + |C_b| + …

主题 2 有 48 个片段,主题 5 有 22 个,合并后的新主题有 48 + 22 = 70 个片段。合并至少要选 2 个主题。合并后的主题可以自己起名字,不起名字,TATOOLS 按合并后的关键词重新生成一个。

拆分

拆分在一个主题内部重新分组。TATOOLS 取这个主题所有片段的降维坐标,用 K 均值分成 p 组,p 可以是 2 到 5。K 均值要找一种分法,让每组片段到本组中心的距离平方和最小。

· · ·

min Σ_{j=1..p} Σ_{x∈C_j} ‖x − μ_j‖²

μ_j:第 j 组片段坐标的平均值

用一维坐标手算,某个主题 6 个片段的坐标如下,拆成 2 组。

· · ·

坐标:1, 2, 3, 10, 11, 12

分法一:{1, 2, 3} 和 {10, 11, 12}

  中心 2 和 11,平方和 = (1 + 0 + 1) + (1 + 0 + 1) = 4

分法二:{1, 2, 3, 10} 和 {11, 12}

  中心 4 和 11.5,平方和 = (9 + 4 + 1 + 36) + (0.25 + 0.25) = 50.5

分法一的平方和小得多,K 均值会选它。拆出来的每个子主题至少要有 2 个片段,所以一个主题至少要有 2p 个片段才能拆成 p 组,片段不够时,编辑栏会标出【片段不足】。拆分的起点是固定的,同一个主题拆成同样的组数,每次结果都一样。子主题的名字由 TATOOLS 重新生成。

移出

移出把一个主题的片段全部归入离群片段,适合处理套话、格式文字这类和研究无关的主题。

· · ·

离群片段占比 = 离群片段数 / 片段总数

400 个片段里原有 32 个离群片段,占比 32 / 400 = 8.0%。移出一个有 15 个片段的主题以后,离群片段变成 47 个,占比 47 / 400 = 11.75%,报告显示为 11.8%。

合并、拆分和移出可以放在同一次里一起改,主题数按每项改动加加减减。一个主题一次只能用一种改法,也不能把主题全部移出。

· · ·

开始:12 个主题

合并 2 个主题为 1 个:12 − 1 = 11

把 1 个主题拆成 3 个:11 + 2 = 13

移出 1 个主题:13 − 1 = 12

13

在报告底部的编辑栏里改

TATOOLS 报告页底部固定着一条编辑栏,左边是【报告版本】下拉框,右边是【编辑报告】和【展开编辑】按钮。展开以后有三个标签页,分别是【合并或移出】【拆分主题】和【时间锚点】,时间锚点放在第三部分讲。

改主题分四步。

1

在【合并或移出】里勾选主题,点【合并所选】或【移出所选】。在【拆分主题】里勾选主题,填好【每个主题拆为】几个子主题,点【拆分所选】。

2

要改的地方先列在【本次将执行】里。合并组可以在【合并后名称】里填名字,留空就按合并后的关键词重新命名,不想改了就点【撤销】。

3

编辑栏底部显示主题数从几变成几、受影响的片段数,以及这次基于哪个版本。

4

点【生成新版本】,新版本生成好以后,页面自动切换过去。

已经选过的主题会带上【组 1】【拆 3 份】或【移出】标记,不能再用别的改法,【清空】可以一次撤掉全部改动。新版本还可以接着改,下拉框里写明它基于哪个版本,一版接一版形成版本链。原来的版本一直保留,随时可以切回去看。

14

改完以后,报告里哪些内容会变

内容 新版本怎么处理
片段、语义向量、降维坐标 沿用上一版
主题归属 被改的主题按改动重新分,其余片段仍在原来的主题里
主题编号 按原来的顺序重新连续编号,拆出的子主题排在原主题的位置
关键词 所有主题按新的分组重新计算
主题名 没动的主题沿用;合并组填了名字就用你的名字,没填名字的合并组和拆出的子主题重新生成
章节或编码名称 没动的主题沿用,合并和拆分产生的主题重新生成
写作结构草案 整份重新生成
散点图、层级图、占比分布、得分矩阵、模型评估 按新的分组重新计算
主题时间演化 沿用上一版识别出的时间表达,按新的分组重新汇总
追问 片段的语义向量沿用,主题名和各主题的数字按新结果重新准备,按改过以后的主题回答
归属分数 这次有拆分时,原来的归属分数和子主题对不上,新版本不再沿用

没动的主题沿用原来的名字,你已经在笔记和编码表里用过的主题名,在新版本里还是同一个名字。质性研究讲究审计轨迹(Audit Trail,把每一次分析决定记录下来,供别人检查),Lincoln 和 Guba 1985 年把它列为检验研究可靠性和可确认性的手段,每一次分类调整都要留下记录。TATOOLS 为每个新版本保存一份变更摘要,承担的就是这份记录的作用。

15

改了什么,报告里都记着

新版本的报告靠上的位置多出一个【相对 vN 的变更】区块,N 是上一版的编号。

区块内容 写了什么
主题数 改之前和改之后的主题数
离群片段占比 改之前和改之后的占比
未改动主题 名称和章节名沿用上一版的主题个数
重新生成的主题 合并或拆分产生、重新命名的主题个数
合并 新主题,合并前的各个主题和片段数,命名来源
拆分 原主题,拆出来的各个主题和片段数
移出主题 被移出的主题和片段数
时间锚点 调整过锚点的文件,改前改后的锚点和来源

接着用前面的例子,一共 12 个主题和 400 个片段,其中 32 个是离群片段。同一次里合并主题 2 和主题 5,把主题 8 拆成 3 个,移出有 15 个片段的主题 11,变更摘要顶部的四个数字见下表。

指标 数值 怎么算
主题数 12 → 12 12 − 1 + 2 − 1
离群片段占比 8.0% → 11.8% 32 / 400 和 47 / 400
未改动主题 8 12 个主题里有 4 个被改过
重新生成的主题 4 合并出 1 个,拆分出 3 个

合并表写明新主题由哪几个原主题组成、各有多少片段,命名来源一栏标出【用户命名】或【自动生成】。写论文时,TATOOLS 的这份摘要可以直接整理成附录里的主题调整记录。

16

主题怎样随时间变化:时间从原文里读出来

一份政策回顾里写着【2023 年第一季度,全市新开工保障房……】,一篇访谈里受访者说【去年 10 月我们递交了申请】。这些时间表达说明了片段在谈哪个时期的事。把每个主题的片段里提到的时间汇总起来,就能看出每个主题主要在讲哪段时期。

主题演化分析(Topic Evolution)研究主题怎样随时间出现、增强和消退。Blei 和 Lafferty 2006 年提出动态主题模型,让主题的词分布随时间片变化;Wang 和 McCallum 同年提出 Topics over Time(主题随时间模型),把时间戳当成和词一起生成的变量。这两种做法都要求每篇文档带一个时间戳。TATOOLS 走的是另一条路,从原文里的时间表达读出时间,再按主题汇总到月份。

识别时间表达并换算成标准日期,是自然语言处理里的一项基础任务,TimeML 标注规范(Pustejovsky 等,2003)把它分成识别和归一化两步。原文里的时间表达分三类,处理方式各不相同。

类型 例子 怎么处理
绝对时间 2023 年 3 月,2023 年第一季度 直接换算成月份
相对时间 去年 10 月,上个月 按所在文件的时间锚点换算
宽泛时间 本世纪,八十年代,近年来 不计入时间轴

时间锚点是换算相对时间用的参照日期。【去年 10 月】写在 2024 年的材料里是 2023 年 10 月,写在 2019 年的材料里是 2018 年 10 月。TATOOLS 给每份源文件定一个锚点,同一份文件的片段共用这个锚点,按四级顺序确定。

1

在文件开头部分找第一个带明确年份的日期。

2

找不到时,把开头部分切成小段,逐段识别其中的时间。

3

还找不到,由语言模型先判断文中有没有明确的时间,有的话读出年月。

4

前三步都没有结果,用工具页上填的【主题时间演化基准】。

四步都没能确定锚点的文件,里面的相对时间不计入时间轴。

每个时间表达换算成它覆盖的月份,权重平均分到这些月份上。把一个主题所有片段里的时间表达分到某个月的权重加起来,就是这个主题在这个月的时间权重。

· · ·

W(k, m) = Σ_{e ∈ E_k} 1[m ∈ M(e)] / |M(e)|

E_k:主题 k 的片段里识别出的全部时间表达

M(e):时间表达 e 覆盖的月份集合

1[m ∈ M(e)]:月份 m 在 M(e) 里取 1,否则取 0

手算一个例子。主题 3 的片段里识别出三个时间表达,所在文件的锚点是 2024 年 6 月。

时间表达 覆盖的月份 每个月分到的权重
2023 年 3 月 2023-03 1
2023 年第一季度 2023-01 到 2023-03 1/3
去年 3 月 2023-03 1
· · ·

W(3, 2023-01) = 1/3 ≈ 0.33

W(3, 2023-02) = 1/3 ≈ 0.33

W(3, 2023-03) = 1 + 1/3 + 1 ≈ 2.33

主题 3 的峰值在 2023 年 3 月。

这条曲线记录的是各主题的片段提到了哪些月份。回忆录、政策回顾和历史叙述把时间写在正文里,用这条曲线能看出每个主题讲的是哪段时期的事,也能看出不同主题在时间上怎样前后衔接。TATOOLS 把时间统一汇总到月份,跨度超过 60 个月的表达,比如【上世纪】,展开后会铺满几百个月,不计入时间轴。

17

时间演化报告怎么读

TATOOLS 报告的【主题时间演化(月份精度)】区块,最上面是四个统计卡片。

卡片 数的是什么
识别到时间的主题数 至少有一个时间表达计入时间轴的主题数,旁边写着主题总数
识别时间跨度 最早和最晚的月份
已确定时间锚点的源文件 有锚点的文件占全部源文件的比例
未计入的时间表达 相对时间缺少锚点的条数,加上时间范围过宽的条数

卡片下面是【时间锚点来源】条,按【自动确定】【全局基准】和【未确定】三段显示各有多少份文件。

曲线图上方可以在【主题筛选】里勾选要看的主题。【显示模式】有【偏移显示】【分离线图】和【堆叠图】三种,【时间轴】可以选【统一时间轴】或【各主题独立】。纵轴是时间权重,鼠标停在数据点上,能看到这个月计入了哪些时间表达,涉及几个片段。

【各主题时间分布】表每行一个主题,列出【出现时间跨度】【最高权重月份】【峰值位置】和【有记录月份数】。【原文中的时间表达明细】列出每个时间表达出现的次数、换算成的月份和处理状态,还有它前后 30 个字符的原文上下文。

状态 含义
已纳入 已经计入时间轴
无锚点丢弃 相对时间,所在文件没有锚点
跨度过大丢弃 换算后的时间范围太宽
宽泛时间丢弃 本世纪、年代、近年来这类说法
解析失败 识别出来了,但没能换算成日期

区块底部的【时间汇总口径】写明了这几条规则。核对某个月的峰值时,先在明细表里找到对应的时间表达,再看上下文里它指的是不是这个主题谈的那件事。

18

年份算错了,在报告里改

一份访谈稿开头写着【1998 年房改以后,单位就不再分房了】,访谈时间是 2024 年 6 月。按第一步的规则,这份文件的锚点定在了 1998 年,文中的【去年 10 月】被换算成了 1997 年 10 月。

打开编辑栏的【时间锚点】标签页,表格列出每份源文件的片段数、当前锚点和来源。

来源 含义
自动确定 前三步从原文里找到的锚点
全局基准 来自工具页或编辑栏设置的全局基准
手动设置 在编辑栏里给这份文件单独设的锚点
未确定 没有锚点

在这份文件的【设置为】里选 2024 年 6 月 15 日,生成新版本。新版本沿用已经识别出的时间表达,只按新锚点重新换算相对时间,【去年 10 月】变成 2023 年 10 月,绝对时间保持不变。表格上方的【全局基准】只作用于还没有锚点的文件。

变更摘要的【时间锚点】部分会列出改过锚点的文件,写明改前改后的锚点和来源。时间锚点可以和合并、拆分放在同一次里改,TATOOLS 一次算出新版本。

19

追问:直接向材料提问,回答附原文出处

读完报告,你手里往往还有很多具体问题。受访者谈公租房轮候时,最常抱怨的是什么?主题 3 在 2023 年 3 月前后集中谈了哪些事?这些问题可以直接在报告的【向这份材料提问】里问 TATOOLS。

直接问通用的 AI 助手,它靠训练时学到的知识作答,依据在哪说不清楚。检索增强生成(Retrieval-Augmented Generation,RAG,先找原文再回答)由 Lewis 等人 2020 年提出,先从材料里找出和问题相关的段落,再要求模型只照着这些段落作答,每句结论都能指回出处。TATOOLS 的追问就是这样做的,检索范围只限你这次上传的材料。

20

能问哪些问题

TATOOLS 在任务完成时,就把每个主题的数字和一句话内容概括准备好了。数字包括片段数、占比和排名,有时间数据的还有峰值月份;内容概括由语言模型读过关键词和最有代表性的几个片段后写成。全部原文片段也预先算好了语义向量,换一种说法提问也能搜到,离群片段同样在内。下面几类问题都能直接问。

想知道 可以这样问 回答里有什么
整体有哪几类 这批材料主要在讨论哪几类主题? 各主题名和占比,逐个列出
哪个最大 占比最大的主题是什么,说了些什么? 主题名、片段数和内容概括
某个主题谈什么 主题 3 主要在讨论什么? 内容概括、关键词和占比,加几段原文
具体怎么说 受访者怎么谈公租房轮候? 摘出原话,每句标出处
有没有提到 有没有人提到租金补贴? 提到的原文;材料里没有就直接说没有,并指出最接近的内容
什么时候 各主题随时间有什么变化? 各主题的峰值月份和先后顺序
两个主题的差别 主题 2 和主题 5 有什么不同? 两个主题各自的数字和原文

同一个问题对应好几个主题或好几份文件时,回答会逐项列出,每项给出结论和数字。问数量和排名,回答靠准备好的数字;问具体内容,回答靠搜出来的原文。

一次问答大致是下面这样,材料和回答都是为说明而构造的示例。

示例 内容
问题 主题 3 里,受访者怎么谈公租房轮候?
回答 受访者谈得最多的是轮候时间长,有人递交申请两年多还没排到[1];也有人说不知道自己排在第几位,只能隔段时间打电话去问[2]。
出处 [1] 访谈-04:我们是前年递的申请,到现在两年多了还没轮到。
出处 [2] 访谈-11:排到第几号也没人告诉,只能隔一段时间打电话去问。

报告还按这次的结果给出几个起手问题,比如【占比最大的主题是什么,说了些什么?】,有时间数据时会加上【各主题随时间有什么变化?】,点一下就能问。

21

回答里的编号是怎么来的

你问一句话,TATOOLS 在背后走四步。

1

先认主题。问题里直接出现主题名、【主题 N】或者某个关键词,就算点到了这个主题。主题名较长时,问题里出现了名字一半以上的两字组合,也算点到。其余主题再和问题比语义向量,意思相近的作为次要线索。

2

再取数字。点到了主题,就取这个主题的片段数、占比、排名和峰值月份;一个主题都没点到,就按和问题字面重合的程度,给全部主题的数字排序。

3

然后找原文。点到主题时,先取这个主题的片段,再补上次要线索主题的片段,以及全部材料里语义最相近的片段。没点到主题时,按语义相似度排序;材料来自多份文件而且问题没点名文件,先让每份文件各出一条最相关的片段。内容太短的片段排在有实质内容的片段后面,各主题的内容概括单独放一路,只作背景,不当出处。

4

最后写回答。语言模型只照着取到的原文、数字和内容概括作答,第一句直接给结论,用方括号编号标出每句话引用的原文片段。回答写完以后,没被引用的候选片段去掉,编号按在回答里第一次出现的顺序重新排。

编号指向的都是你上传的原文,数字都来自这次的分析结果,两样都能回到报告里核对。

22

怎么问,回答更准

这样问 为什么更准
直接写【主题 3】或主题名 第 1 步一下就能认出主题
用材料里的原话 更容易搜到对应的段落
一次只问一件事 找来的原文更集中
把【它】【这个】换成具体名字 每次提问相互独立,不记得上一句

主题名比较长时,问题里不必一字不差。第 1 步的两字组合可以手算。

· · ·

主题名:住房负担与居住选择

两字组合:住房 房负 负担 居住 住选 选择,共 6 个(含【与】的组合不算)

问题:居住选择上遇到哪些难处

问题的两字组合:居住 住选 选择 择上 上遇 难处(含【到】【哪】【些】的组合不算)

重合:居住 住选 选择,共 3 个,达到名字的一半,算点到这个主题

最省事的办法是用【主题原文片段】里的【就这个主题提问】按钮,点一下,输入框自动填上【主题 N】。

每个版本有自己的提问记录。生成新版本时,片段的语义向量直接沿用,主题名和各主题的数字按新结果重新准备,在新版本上追问,用的就是改过以后的主题。TATOOLS 的公开示例任务里,访客能看到创建者问过的问题和回答,出处可以逐条展开核对。

23

把结果写进论文

TATOOLS 报告里有两份直接为写作准备的草案。【章节或编码名称草案】给每个主题一个适合当小节标题或编码条目的名字,附上关键词、片段数和按占比建议的位置。【写作结构草案】按主题组织出论文结果部分的章节结构,每节写明对应的主题编号和论述方向,引用前要回到原文核对。

方法部分要交代的参数,在【主题建模分析概览】的【运行设置】和【下载原始数据】里的参数表都能找到。下载的数据表还包括片段的主题归属和主题清单,章节或编码名称草案和主题原文片段也各有一张表。

下面是一段方法部分的写法示例,方括号里换成自己的数字。

本研究使用 TATOOLS 的 BERTopic 主题聚类工具(Grootendorst,2022)分析 [文件数] 份文本。文本按约 [窗口大小] 个字符切分为 [片段数] 个片段,计算语义向量后用 UMAP 降至 [降维维度] 维(邻居数量 [邻居数量],最小距离 [最小距离]),再用 HDBSCAN 聚类。主题数采用 [自动发现的平衡策略,或手动指定为 K 个],最终得到 [主题数] 个主题,离群片段占 [比例]。主题关键词取主题内各片段 TF-IDF 权重的平均值,主题名称由语言模型根据关键词及其原文语境生成,研究者对照代表原文逐一核对。研究者在初始结果上合并了 [a] 组主题,拆分 [b] 个主题,移出 [c] 个主题,形成第 [v] 版结果,调整记录见附录。主题的时间分布依据原文中的时间表达汇总到月份。

24

小结

BERTopic 先用语义向量判断片段之间意思远近,再用 UMAP 降维、HDBSCAN 按疏密聚类,最后用 TF-IDF 给主题算关键词,【多样性参数】可以压低意思重复的关键词。

片段是分析单位,【文本分割窗口大小】决定一个片段装多少内容,片段数是所有占比的分母。

主题数可以手动指定,也可以由肘部、轮廓系数、CH 指数和 DB 指数四个读数自动给出,三种预设分别取主结构、折中和细分。

抽象标签由关键词、关键词的原文上下文和【所属行业】生成,读主题名时对照代表原文。

TATOOLS 工具页开放了流水线每一步的设置,模型评估分数可以用来比较不同设置的运行结果。

合并、拆分和移出主题生成新版本,新版本沿用语义向量和降维坐标,没动的主题片段不变,变更摘要留下完整记录。

时间演化从原文的时间表达读出时间,相对时间按每份文件的锚点换算,锚点定错可以在报告里改。

追问能问整体有哪几类主题、哪个最大、某个主题谈什么、原文具体怎么说和各主题的时间先后,回答只引用原文片段,并用编号标出出处。

同一批材料想换一个角度看,可以交给 TATOOLS 的【高级LDA主题模型】,比较按词语共现归纳出的主题;想看材料里人物、机构和概念之间的关系,可以用【知识图谱】。

25

资料来源

Grootendorst:BERTopic: Neural topic modeling with a class-based TF-IDF procedure,arXiv:2203.05794,2022

Blei、Ng 与 Jordan:Latent Dirichlet Allocation,Journal of Machine Learning Research,第 3 卷,2003,第 993–1022 页

Reimers 与 Gurevych:Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks,EMNLP-IJCNLP,2019

Beyer、Goldstein、Ramakrishnan 与 Shaft:When Is Nearest Neighbor Meaningful?,ICDT,1999

McInnes、Healy 与 Melville:UMAP: Uniform Manifold Approximation and Projection for Dimension Reduction,arXiv:1802.03426,2018

Campello、Moulavi 与 Sander:Density-Based Clustering Based on Hierarchical Density Estimates,PAKDD,2013

MacQueen:Some Methods for Classification and Analysis of Multivariate Observations,Proceedings of the Fifth Berkeley Symposium on Mathematical Statistics and Probability,1967

Rousseeuw:Silhouettes: A Graphical Aid to the Interpretation and Validation of Cluster Analysis,Journal of Computational and Applied Mathematics,第 20 卷,1987

Caliński 与 Harabasz:A Dendrite Method for Cluster Analysis,Communications in Statistics,第 3 卷第 1 期,1974

Davies 与 Bouldin:A Cluster Separation Measure,IEEE Transactions on Pattern Analysis and Machine Intelligence,PAMI-1 卷第 2 期,1979

Sparck Jones:A Statistical Interpretation of Term Specificity and Its Application in Retrieval,Journal of Documentation,第 28 卷第 1 期,1972

Salton 与 Buckley:Term-Weighting Approaches in Automatic Text Retrieval,Information Processing & Management,第 24 卷第 5 期,1988

Carbonell 与 Goldstein:The Use of MMR, Diversity-Based Reranking for Reordering Documents and Producing Summaries,SIGIR,1998

Mei、Shen 与 Zhai:Automatic Labeling of Multinomial Topic Models,KDD,2007

Lau、Grieser、Newman 与 Baldwin:Automatic Labelling of Topic Models,ACL,2011

Ward:Hierarchical Grouping to Optimize an Objective Function,Journal of the American Statistical Association,第 58 卷第 301 期,1963

Hu、Boyd-Graber、Satinoff 与 Smith:Interactive Topic Modeling,Machine Learning,第 95 卷,2014

Smith、Kumar、Boyd-Graber、Seppi 与 Findlater:Closing the Loop: User-Centered Design and Evaluation of a Human-in-the-Loop Topic Modeling System,IUI,2018

Saldaña:The Coding Manual for Qualitative Researchers,第 2 版,SAGE,2013

Lincoln 与 Guba:Naturalistic Inquiry,SAGE,1985

Blei 与 Lafferty:Dynamic Topic Models,ICML,2006

Wang 与 McCallum:Topics over Time: A Non-Markov Continuous-Time Model of Topical Trends,KDD,2006

Pustejovsky 等:TimeML: Robust Specification of Event and Temporal Expressions in Text,New Directions in Question Answering,2003

Lewis 等:Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks,NeurIPS,2020


END