fasttext.supervised 参数如下
```javascript
input_file 训练文件路径(必须)
output 输出文件路径(必须)
label_prefix 标签前缀 default __label__
lr 学习率 default 0.1
lr_update_rate 学习率更新速率 default 100
dim 词向量维度 default 100
ws 上下文窗口大小 default 5
epoch epochs 数量 default 5
min_count 最低词频 default 5
word_ngrams n-gram 设置 default 1
loss 损失函数 {ns,hs,softmax} default softmax
minn 最小字符长度 default 0
maxn 最大字符长度 default 0
thread 线程数量 default 12
t 采样阈值 default 0.0001
silent 禁用 c++ 扩展日志输出 default 1
encoding 指定 input_file 编码 default utf-8
pretrained_vectors 指定使用已有的词向量 .vec 文件 default None
训练词向量
基于这个数据来学习词向量只需要一个命令就能实现:
$ mkdir result
$ ./fasttext skipgram -input data/fil9 -output result/fil9
解释这行命令: ./fastext 用 skipgram 模型(或者是 cbow 模型)调用 fastText 二进制的可执行文件(在这里参考如何安装 fastText )。然后,'-input' 选项要求我们指定输入数据的位置,'-output' 指定输出要保存的位置。
当 fastText 运行时,屏幕上会显示进度和预计完成时间。一旦程序结束,result 目录中应该有两个文件:
$ ls -l result
-rw-r-r-- 1 bojanowski 1876110778 978480850 Dec 20 11:01 fil9.bin
-rw-r-r-- 1 bojanowski 1876110778 190004182 Dec 20 11:01 fil9.vec
fil9.bin 是一个二进制文件,用于存储整个 fastText 模型,并可以在之后重新加载。 fil9.vec 是一个包含词向量的文本文件,词汇表中的一个单词对应一行:
$ head -n 4 result/fil9.vec
218316 100
the -0.10363 -0.063669 0.032436 -0.040798 0.53749 0.00097867 0.10083 0.24829 ...
of -0.0083724 0.0059414 -0.046618 -0.072735 0.83007 0.038895 -0.13634 0.60063 ...
one 0.32731 0.044409 -0.46484 0.14716 0.7431 0.24684 -0.11301 0.51721 0.73262 ...
第一行说明了单词数量和向量维数。随后的行是词汇表中所有单词的词向量,按降序排列。
高级读者:skipgram 与 cbow 两种模型
fastText 提供了两种用于计算词表示的模型:skipgram 和 cbow ('continuous-bag-of-words')。
skipgram 模型是学习近邻的单词来预测目标单词。 另一方面, cbow 模型是根据目标词的上下文来预测目标词。上下文是指在目标词左边和右边的固定单词数和。
让我们用一个例子来说明这种差异:给出句子 'Poets have been mysteriously silent on the subject of cheese' 和目标单词 'silent',skipgram 模型随机取近邻词尝试预测目标词,如 'subject'或'mysteriously'。cbow 模型使用目标单词固定数量的左边和右边单词,,如 {been, mysteriously, on, the},并使用它们的向量和来预测目标单词。下图用另一个例子总结了这种差异。
![cbow vs skipgram ](https://img-blog.csdnimg.cn/aac5cfd395744234a19d0821e89b86a6.png#pic_center)
要使用 fastText 训练 cbow 模型,请运行下面这个命令:
./fasttext cbow -input data/fil9 -output result/fil9
通过这个练习,我们观察到 skipgram 模型会比 cbow 模型在 subword information 上效果更好 在实践中,我们观察到 skipgram 模型比 cbow 在子词信息方面效果更好。
高级读者:调整参数
到目前为止,我们使用默认参数运行 fastText,但根据数据,这些参数可能不是最优的。 让我们介绍一下词向量的一些关键参数。
模型的最重要的参数是维度和子词的大小范围。 维度(dim)控制向量的大小,维度越多,它们就需要学习更多的数据来获取越多的信息。 但是,如果它们太大,就会越来越难以训练。 默认情况下,我们使用 100个 维度,一般情况下使用 100 到 300 范围内中的值。 子词是包含在最小尺寸(minn)和最大尺寸(maxn)之间的字中的所有子字符串。 默认情况下,我们取 3 到 6 个字符的所有子词,但不同语言的适用范围可能不同:
$ ./fasttext skipgram -input data/fil9 -output result/fil9 -minn 2 -maxn 5 -dim 300
根据您已有的数据量,您可能需要更改训练参数。 epoch 参数控制将循环多少次的数据。 默认情况下,我们遍历数据集 5 次。 如果你的数据集非常庞大,你可能希望更少地循环它。另一个重要参数是学习率 -lr)。 学习率越高,模型收敛到最优解的速度越快,但过拟合数据集的风险也越高。 默认值是 0.05,这是一个很好的折中值。 如果你想调整它,我们建议留在 [0.01,1] 的范围内:
$ ./fasttext skipgram -input data/fil9 -output result/fil9 -epoch 1 -lr 0.5
最后,fastText 是多线程的,默认使用 12 个线程。 如果 CPU 核心数较少(只有 4 个),则可以使用 thread 参数轻松设置线程数:
$ ./fasttext skipgram -input data/fil9 -output result/fil9 -thread 4
更多的迭代和更快的学习速率
默认情况下,由于我们的训练集只有 12k 个训练样本,因此 fastText 在训练过程中仅看到每个训练样例五次,这太少了。 可以使用 -epoch 选项增加每个示例出现的次数(也称为迭代数):
>> ./fasttext supervised -input cooking.train -output model_cooking -epoch 25
Read 0M words
Number of words: 9012
Number of labels: 734
Progress: 100.0% words/sec/thread: 77633 lr: 0.000000 loss: 7.147976 eta: 0h0m
让我们测试一下新模型:
>> ./fasttext test model_cooking.bin cooking.valid
N 3000
P@1 0.501
R@1 0.218
Number of examples: 3000
这好多了! 另一种改变我们模型学习速度的方法是增加(或减少)算法的学习速率。 这对应于处理每个样本后模型变化的幅度。 学习率为 0 意味着模型根本不会改变,因此不会学到任何东西。好的学习速率在 0.1 - 1.0 范围内。
>> ./fasttext supervised -input cooking.train -output model_cooking -lr 1.0
Read 0M words
Number of words: 9012
Number of labels: 734
Progress: 100.0% words/sec/thread: 81469 lr: 0.000000 loss: 6.405640 eta: 0h0m
>> ./fasttext test model_cooking.bin cooking.valid
N 3000
P@1 0.563
R@1 0.245
Number of examples: 3000
更好了!我们试试学习速率和迭代次数两个参数一起变化:
>> ./fasttext supervised -input cooking.train -output model_cooking -lr 1.0 -epoch 25
Read 0M words
Number of words: 9012
Number of labels: 734
Progress: 100.0% words/sec/thread: 76394 lr: 0.000000 loss: 4.350277 eta: 0h0m
>> ./fasttext test model_cooking.bin cooking.valid
N 3000
P@1 0.585
R@1 0.255
Number of examples: 3000
现在让我们多添加一些功能来进一步提高我们的性能!
word n-grams
最后,我们可以通过使用 word bigrams 而不是 unigrams 来提高模型的性能。 这对于词序重要的分类问题尤其重要,例如情感分析。
>> ./fasttext supervised -input cooking.train -output model_cooking -lr 1.0 -epoch 25 -wordNgrams 2
Read 0M words
Number of words: 9012
Number of labels: 734
Progress: 100.0% words/sec/thread: 75366 lr: 0.000000 loss: 3.226064 eta: 0h0m
>> ./fasttext test model_cooking.bin cooking.valid
N 3000
P@1 0.599
R@1 0.261
Number of examples: 3000
只需几个步骤,我们就可以从 12.4% 到达 59.9% 的精度。 重要步骤包括:
预处理数据 ;
改变迭代次数 (使用选项 -epoch, 标准范围 [5 - 50]) ;
改变学习速率 (使用选项 -lr, 标准范围 [0.1 - 1.0]) ;
使用 word n-grams (使用选项 -wordNgrams, 标准范围 [1 - 5]).
高级读者: 什么是 Bigram?
'unigram' 指的是单个不可分割的单位或标记,通常用作模型的输入。 例如,根据模型的不同,'unigram' 可以是单词或字母。 在 fastText 中,我们在单词级别工作,因此 unigrams 是单词。
类似地,我们用 'bigram' 表示2个连续标记或单词的连接。 类似地,我们经常谈论 n-gram 来引用任意 n 个连续标记或单词的级联。
例如,在 'Last donut of the night' 这个句子中,unigrams是 'last','donut','of','the' 和 'night'。 bigrams 是 'Last donut', 'donut of', 'of the' 和 'the night'。
Bigrams 特别有趣,因为对于大多数句子,只需查看 n-gram 的集合即可重建句子中单词的顺序。
让我们通过一个简单的练习来说明这一点,给定以下 bigrams,试着重构原始的句子:'all out','I am','bubblegum','out of' 和 'all all'。 通常将一个单词称为一个 unigram。
扩大规模
由于我们正在通过几千个示例来训练我们的模型,所以训练只需几秒钟。但是在更大的数据集上训练模型,使用更多的标签可能会太慢。 使训练更快的潜在解决方案是使用hierarchical softmax,而不是 regular softmax [添加 hierarchical softmax 的快速解释]。 这可以通过选项 -loss hs 完成:
>> ./fasttext supervised -input cooking.train -output model_cooking -lr 1.0 -epoch 25 -wordNgrams 2 -bucket 200000 -dim 50 -loss hs
Read 0M words
Number of words: 9012
Number of labels: 734
Progress: 100.0% words/sec/thread: 2199406 lr: 0.000000 loss: 1.718807 eta: 0h0m
现在训练时间应该不到一秒。