跳到正文
Hacker News· Anon84·· 5 天前AI 评分20

从词袋模型到词向量:文本如何变成数字

From bag-of-words to word vectors

AI 导读

一篇技术教程分三阶段讲解文本向量化:从词袋模型、n-gram 到稠密词向量,核心问题是"能从上下文里恢复多少词义"。实验基于 WikiText-2 语料(约 200 万 token、约 3.6 万篇文档),清洗后保留 21,465 行,训练集 1,680,658 个 token、61,822 个唯一类型,嵌入使用词频下限 5,测试集 OOV 率为 0.0417。

正文 · AI 翻译

Stochastic Blog

Feature figure for From bag-of-words to word vectors

在第 23 和 24 篇文章中,我们教会了机器阅读:加载原始文本,用正则表达式清洗,最终得到一张整洁的文档表。但我们从未决定过,清洗完成后,一个文档究竟是什么。一串字符不是模型能相乘的东西。本文搭建从文本到数字的桥梁,分三个阶段进行,每个阶段都增加一个前一阶段缺少的机制。我们从最粗糙的表示——词袋开始,最终得到稠密向量,其中 king 与 queen 仅一步之遥。贯穿始终的是一个每个方法都比前一个回答得稍好一点的问题:从一个词所处的语境中,我们能恢复多少它的含义?词袋模型说一点也恢复不了,n-gram 模型说能恢复一点,而嵌入说能恢复足够多,以至于对词做算术开始行得通。

我们在 WikiText-2 上工作,这是原始的维基百科语料库,约 200 万个 token,分布在约 3.6 万篇文档中。一个 token 是一个正在运行的词实例。一个 type 是一个唯一的词形。它小到可以在笔记本电脑上训练几个嵌入模型,又大到词汇表、频率曲线和 n-gram 计数表现得像真实文本。下面的一切都在单个 GPU 上运行,每个数字都直接来自 notebook。

语料库,以及探索性数据分析(EDA)告诉我们的信息

在任何变换之前,我们先查看原始文档,因为变换会隐藏空行、重复的样板文本和截断。加载后得到 21,580 行、三列,split、doc_id 和 text,内存占用 18.8 MB。没有文本字段缺失,因此没有因这个原因丢弃任何内容。划分分配是这个语料库携带的唯一标签,所以这就是我们绘制的平衡情况。

Train dominates the split, so the base rate for the split label is the train share

训练集占文档的 81.35%,验证集占 8.53%,测试集占 10.12%。这种不平衡是任何基于此标签的分类器都必须超越的基准率,它也提醒我们,在训练时验证集和测试集保持不动。

另外两个发现决定了后续的一切。第一,每个划分内部都存在重复文档,并且有 9 个精确的训练/测试重叠。我们在各自划分内丢弃 106 个重复项,并移除 9 个泄漏的测试行,剩下 21,465 行,训练集和测试集之间干净地零重叠。第二,token 频率曲线在双对数坐标轴上接近一条直线,这意味着 type 分布是齐普夫式的:几千个 type 覆盖了大多数 token,而数千个 type 恰好只出现一次。

The straight log-log line shows a few thousand types cover most tokens while thousands occur once

那条长尾很重要。对训练划分进行分词后,我们有 1,680,658 个 token、61,822 个唯一 type,以及只有 36,909 个至少出现两次的 type。单例的嵌入行永远不会获得足够的梯度来移动,因此我们的嵌入使用计数下限 5。齐普夫曲线也是为什么词汇表外比率值得测量的原因:相对于完整的训练词汇表,测试 OOV 率为 0.0417,而相对于计数为 2 的词汇表,它上升到 0.0539。这个数字是任何词级模型的上限,也是子词单元在本文后面赢得一席之地的原因。

文本基础

OOV 上限从表示本身开始。第一种表示将文档视为其单词的词袋。顺序消失,只有计数保留下来。我们可以直接看到这种盲目性:两个句子共享相同的单词但顺序相反,the dog bit the man 和 the man bit the dog,产生的余弦相似度为 1.0,而余弦相似度衡量两个计数向量之间的角度,因此 1.0 意味着方向相同。本笔记本中后续的每个模型都继承了这种盲目性,除非它重新加入上下文。

根据单词在整个语料库中的稀有程度对每个计数进行加权,就得到了 TF-IDF,其中权重是词频乘以 IDF,即总文档数的对数除以包含该词的文档数。在真实语料库的 600 篇文档样本上,使用 min_df=2(忽略出现在少于两篇文档中的词)来去除一次性样板内容,我们得到一个 600 乘 4,332 的稀疏矩阵,包含 32,312 个非零项,IDF 值范围从 1.14 到 6.3。每篇文档的顶部词是可读的,这就是为什么 TF-IDF 仍然是搜索和标记的默认基线。

来源:Hacker News · stochastic.blog