floret:fastText + Bloom嵌入,为spaCy提供紧凑、全覆盖的向量
floret是fastText的扩展版本,能够从紧凑的向量表中为任何单词生成词表示。它结合了:
- fastText的子词,为任何单词提供嵌入
- Bloom嵌入("哈希技巧")用于紧凑的向量表
要了解更多关于floret的信息,请查看我们的floret向量博客文章。
如需实践介绍,请在此示例笔记本中试验英语向量:intro_to_floret
安装floret
从源代码构建floret
git clone https://github.com/explosion/floret
cd floret
make
这将生成主要的二进制文件floret
。
为Python安装
使用pip
安装Python包装器:
pip install floret
或者以开发模式从源代码安装:
git clone https://github.com/explosion/floret
cd floret
pip install -r requirements.txt
pip install --no-build-isolation --editable .
请参阅Python文档。
使用方法
floret
在fasttext
的基础上增加了两个额外的命令行选项:
-mode fasttext(默认)或floret(单词和字符n-gram散列到桶中)[fasttext]
-hashCount 仅floret模式:每个单词/子词的哈希数(1-4)[1]
使用-mode floret
时,单词条目与子词嵌入(桶)存储在同一个表中,减少了保存的向量数据大小。
使用-hashCount 2
时,每个条目作为内部子词哈希表中2行的和存储。floret
支持在嵌入表中每个条目使用1-4个哈希。通过将嵌入表中的一个条目存储为多于一行的和,可以大幅减少表中的行数,同时对性能的影响相对较小,无论是在准确性还是速度方面。
以下是如何训练CBOW嵌入的示例,使用4-gram和5-gram作为子词,每个条目使用2个哈希,并使用50K条目的紧凑表,而不是默认的2M条目。
floret cbow -dim 300 -minn 4 -maxn 5 -mode floret -hashCount 2 -bucket 50000 \
-input input.txt -output vectors
使用-mode floret
选项时,floret将保存一个额外的向量表,文件扩展名为.floret
。其格式与.vec
非常相似,包含一个头行,后面跟着每个向量一行。单词标记被行索引替代,头部扩展包含了在spaCy中加载此表所需的所有相关训练设置。
要在spaCy v3.2+中导入此向量表:
spacy init vectors LANG vectors.floret spacy_vectors_dir --mode floret
floret的工作原理
在原始实现中,fastText将单词和子词存储在两个独立的表中。单词表包含词汇表中每个单词的一个条目(通常约100万个条目),而子词存储在一个单独的固定大小表中,通过将每个子词散列到表中的一行(默认200万个条目)。使用相对较大的表是为了减少子词之间的冲突。然而,对于100万个单词+ 200万个子词,每个使用300维32位浮点数向量,你需要约3GB来存储结果数据,这对许多用例来说是难以接受的。
此外,许多导入向量的库只支持单词表(.vec
),这将覆盖范围限制在训练数据中频率高于某个阈值的单词。对于形态丰富的语言来说,即使是大型向量表也可能无法为训练中看到的单词提供良好的覆盖,而且你仍然可能遇到训练中完全没有见过的单词。
为了以更紧凑的格式存储单词和子词向量,我们转向了一直被spaCy使用的算法:Bloom嵌入。Bloom嵌入(也称为"哈希技巧",或在spaCy的机器学习库thinc中称为HashEmbed
)可用于通过将每个条目散列到表中的多行来在紧凑表中存储不同的表示。通过将每个条目表示为多行的和,其中两个条目不太可能在多个哈希上发生冲突,大多数条目最终会得到不同的表示。
使用设置-minn 4 -maxn 5 -mode floret -hashCount 2
,单词apple
的嵌入在内部存储为单词、4-gram和5-gram各自2个散列行的和。单词用BOW和EOW字符<
和>
填充,创建以下单词和子词条目:
<apple>
<app
appl
pple
ple>
<appl
apple
pple>
为了与spaCy兼容,使用MurmurHash对单词和字符n-gram字符串进行散列。apple
的最终嵌入是上述每个单词和字符n-gram两行(-hashCount 2
)的和。
使用-mode floret
时,floret
将在常规的.bin
和.vec
文件旁保存一个额外的向量表,扩展名为.floret
。其格式与.vec
非常相似,包含一个头行,后面跟着向量表中每个条目一行,每行开头是行索引而不是单词标记。头部扩展包含了在其他应用程序或库(如spaCy)中使用此表所需的所有训练设置。
头部包含以空格分隔的设置:
bucket dim minn maxn hashCount hashSeed BOW EOW
使用-bucket 10 -dim 10 -minn 2 -maxn3 -hashCount 2
的演示.floret
表:
10 10 2 3 2 2166136261 < >
0 -2.2611 3.9302 2.6676 -11.233 0.093715 -10.52 -9.6463 -0.11853 2.101 -0.10145
1 -3.12 -1.7981 10.7 -6.171 4.4527 10.967 9.073 6.2056 -6.1199 -2.0402
2 9.5689 5.6721 -8.4832 -1.2249 2.1871 -3.0264 -2.391 -5.3308 -3.2847 -4.0382
3 3.6268 4.2759 -1.7007 1.5002 5.5266 1.8716 -12.063 0.26314 2.7645 2.4929
4 -11.683 -7.7068 2.1102 2.214 7.2202 0.69799 3.2173 -5.382 -2.0838 5.0314
5 -4.3024 8.0241 2.0714 -1.0174 -0.28369 1.7622 7.8797 -1.7795 6.7541 5.6703
6 8.3574 -5.225 8.6529 8.5605 -8.9465 3.767 -5.4636 -1.4635 -0.98947 -0.58025
7 -10.01 3.3894 -4.4487 1.1669 -11.904 6.5158 4.3681 0.79913 -6.9131 -8.687
8 -5.4576 7.1019 -8.8259 1.7189 4.955 -8.9157 -3.8905 -0.60086 -2.1233 5.892
9 8.0678 -4.4142 3.6236 4.5889 -2.7611 2.4455 0.67096 -4.2822 2.0875 4.6274
在spaCy v3.2+中,可以使用spacy init vectors
和选项--mode floret
将此表导入到spaCy管道中:
spacy init vectors LANG vectors.floret spacy_vectors_dir --mode floret
注意事项
fastText和floret的二进制格式(.bin
)不兼容,因此使用训练它的同一程序加载.bin
文件很重要。
有关所有其他命令和选项的详细信息,请参阅 fastText 文档。floret
支持所有现有的 fasttext
命令,并且不会修改任何 fasttext
默认设置。
以下为原始 fastText README 供参考。
fastText README
fastText 是一个用于高效学习词表示和句子分类的库。
目录
资源
模型
- 最新的最先进英语词向量。
- 在维基百科和网络抓取数据上训练的 157 种语言的词向量。
- 语言识别和各种监督任务的模型。
补充数据
- [2] 中使用的预处理过的 YFCC100M 数据。
常见问题
速查表
我们还提供了一个包含有用单行命令的速查表。
要求
我们使用 circleci 在各种 docker 镜像下持续构建和测试我们的库、CLI 和 Python 绑定。
通常,fastText 可以在现代 Mac OS 和 Linux 发行版上构建。 由于它使用了一些 C++11 特性,因此需要具有良好 C++11 支持的编译器。 这些包括:
- (g++-4.7.2 或更新版本) 或 (clang-3.3 或更新版本)
编译是通过 Makefile 进行的,所以你需要有一个可以工作的 make。 如果你想使用 cmake,你需要至少 2.8.9 版本。
我们成功构建和测试 CLI 的最老发行版之一是 Debian jessie。
对于词相似性评估脚本,你需要:
- Python 2.6 或更新版本
- NumPy & SciPy
对于 Python 绑定(见 python 子目录),你需要:
- Python 2.7 或 >=3.4 版本
- NumPy & SciPy
- pybind11
我们成功构建和测试 Python 绑定的最老发行版之一是 Debian jessie。
如果这些要求使你无法使用 fastText,请提出问题,我们会尝试满足你的需求。
构建 fastText
我们讨论构建 fastText 的最新稳定版本。
获取源代码
你可以在通常的位置找到我们的最新稳定版本。
还有 master 分支,其中包含我们所有最新的工作,但也伴随着不稳定分支的所有常见注意事项。如果你是开发者或高级用户,你可能想使用这个。
使用 make 构建 fastText(推荐)
$ wget https://github.com/facebookresearch/fastText/archive/v0.9.2.zip
$ unzip v0.9.2.zip
$ cd fastText-0.9.2
$ make
这将为所有类生成目标文件以及主二进制文件 fasttext
。
如果你不打算使用默认的系统范围编译器,请更新 Makefile 开头定义的两个宏(CC 和 INCLUDES)。
使用 cmake 构建 fastText
目前这不是发布版的一部分,所以你需要克隆 master 分支。
$ git clone https://github.com/facebookresearch/fastText.git
$ cd fastText
$ mkdir build && cd build && cmake ..
$ make && make install
这将创建 fasttext 二进制文件以及所有相关库(共享、静态、PIC)。
为 Python 构建 fastText
目前这不是发布版的一部分,所以你需要克隆 master 分支。
$ git clone https://github.com/facebookresearch/fastText.git
$ cd fastText
$ pip install .
有关更多信息和介绍,请参见 python/README.md
示例用例
这个库有两个主要用例:词表示学习和文本分类。 这些在两篇论文 1 和 2 中有描述。
词表示学习
为了学习词向量,如 1 中所述,执行:
$ ./fasttext skipgram -input data.txt -output model
其中 data.txt
是包含 UTF-8
编码文本的训练文件。
默认情况下,词向量将考虑 3 到 6 个字符的字符 n-gram。
在优化结束时,程序将保存两个文件:model.bin
和 model.vec
。
model.vec
是一个文本文件,每行包含一个词向量。
model.bin
是一个二进制文件,包含模型参数以及字典和所有超参数。
二进制文件可以稍后用于计算词向量或重新启动优化。
获取词表外词的词向量
之前训练的模型可以用来计算词表外词的词向量。
假设你有一个文本文件 queries.txt
,包含你想要计算向量的词,使用以下命令:
$ ./fasttext print-word-vectors model.bin < queries.txt
这将输出词向量到标准输出,每行一个向量。 这也可以与管道一起使用:
$ cat queries.txt | ./fasttext print-word-vectors model.bin
查看提供的脚本以获取示例。例如,运行:
$ ./word-vector-example.sh
将编译代码、下载数据、计算词向量并在罕见词相似性数据集 RW [Thang et al. 2013] 上评估它们。
文本分类
这个库也可以用来训练监督文本分类器,例如用于情感分析。 为了使用 2 中描述的方法训练文本分类器,使用:
$ ./fasttext supervised -input train.txt -output model
其中 train.txt
是一个文本文件,每行包含一个训练句子及其标签。
默认情况下,我们假设标签是以字符串 __label__
为前缀的词。
这将输出两个文件:model.bin
和 model.vec
。
一旦模型训练完成,你可以通过在测试集上计算 k 值的精确率和召回率(P@k 和 R@k)来评估它:
$ ./fasttext test model.bin test.txt k
参数 k
是可选的,默认为 1
。
为了获取一段文本的 k 个最可能的标签,使用:
$ ./fasttext predict model.bin test.txt k
或使用 predict-prob
来同时获取每个标签的概率
$ ./fasttext predict-prob model.bin test.txt k
其中 test.txt
包含每行一个要分类的文本片段。
这样做会将每行的 k 个最可能的标签打印到标准输出。
参数 k
是可选的,默认为 1
。
查看 classification-example.sh
以获取示例用例。
为了复现论文 2 中的结果,运行 classification-results.sh
,这将下载所有数据集并复现表 1 中的结果。
如果你想计算句子或段落的向量表示,请使用:
$ ./fasttext print-sentence-vectors model.bin < text.txt
这假设 text.txt
文件包含你想要获取向量的段落。
程序将在文件中每行输出一个向量表示。
你也可以使用以下命令量化监督模型以减少其内存使用:
$ ./fasttext quantize -output model
这将创建一个内存占用更小的 .ftz
文件。所有标准功能,如 test
或 predict
,在量化模型上的工作方式相同:
$ ./fasttext test model.ftz test.txt
量化过程遵循 3 中描述的步骤。你可以运行脚本 quantization-example.sh
以获取示例。
完整文档
不带参数调用命令以列出可用参数及其默认值:
$ ./fasttext supervised
输入或输出路径为空。
以下参数为必填项:
-input 训练文件路径
-output 输出文件路径
以下参数为可选项:
-verbose 详细程度 [2]
以下字典相关参数为可选项:
-minCount 单词最小出现次数 [1]
-minCountLabel 标签最小出现次数 [0]
-wordNgrams 单词n元组最大长度 [1]
-bucket 桶的数量 [2000000]
-minn 字符n元组最小长度 [0]
-maxn 字符n元组最大长度 [0]
-t 采样阈值 [0.0001]
-label 标签前缀 [__label__]
以下训练相关参数为可选项:
-lr 学习率 [0.1]
-lrUpdateRate 学习率更新频率 [100]
-dim 词向量维度 [100]
-ws 上下文窗口大小 [5]
-epoch 训练轮数 [5]
-neg 负采样数量 [5]
-loss 损失函数 {ns, hs, softmax} [softmax]
-thread 线程数 [12]
-pretrainedVectors 监督学习的预训练词向量 []
-saveOutput 是否保存输出参数 [0]
以下量化相关参数为可选项:
-cutoff 保留的单词和n元组数量 [0]
-retrain 应用截断时是否微调嵌入 [0]
-qnorm 是否单独量化范数 [0]
-qout 是否量化分类器 [0]
-dsub 每个子向量的大小 [2]
默认值可能因模式而异。(词表示模式 skipgram
和 cbow
使用默认的 -minCount
为 5。)
参考文献
如果使用此代码学习词表示,请引用 1;如果用于文本分类,请引用 2。
用子词信息丰富词向量
[1] P. Bojanowski*, E. Grave*, A. Joulin, T. Mikolov, 用子词信息丰富词向量
@article{bojanowski2017enriching,
title={Enriching Word Vectors with Subword Information},
author={Bojanowski, Piotr and Grave, Edouard and Joulin, Armand and Mikolov, Tomas},
journal={Transactions of the Association for Computational Linguistics},
volume={5},
year={2017},
issn={2307-387X},
pages={135--146}
}
高效文本分类的技巧包
[2] A. Joulin, E. Grave, P. Bojanowski, T. Mikolov, 高效文本分类的技巧包
@InProceedings{joulin2017bag,
title={Bag of Tricks for Efficient Text Classification},
author={Joulin, Armand and Grave, Edouard and Bojanowski, Piotr and Mikolov, Tomas},
booktitle={Proceedings of the 15th Conference of the European Chapter of the Association for Computational Linguistics: Volume 2, Short Papers},
month={April},
year={2017},
publisher={Association for Computational Linguistics},
pages={427--431},
}
FastText.zip:压缩文本分类模型
[3] A. Joulin, E. Grave, P. Bojanowski, M. Douze, H. Jégou, T. Mikolov, FastText.zip:压缩文本分类模型
@article{joulin2016fasttext,
title={FastText.zip: Compressing text classification models},
author={Joulin, Armand and Grave, Edouard and Bojanowski, Piotr and Douze, Matthijs and J{\'e}gou, H{\'e}rve and Mikolov, Tomas},
journal={arXiv preprint arXiv:1612.03651},
year={2016}
}
(* 这些作者贡献相同。)