Fasttext
Fasttext特点
- 模型简单,只有一层的隐层以及输出层,因此训练速度非常快
- 不需要训练词向量,Fasttext自己会训练
- 两个优化:Hierarchical Softmax、N-gram
Fasttext模型架构
fastText模型架构和word2vec中的CBOW很相似, 不同之处是fastText预测标签而CBOW预测的是中间词,即模型架构类似但是模型的任务不同。
CBOW架构
(1) word2vec将上下文关系转化为多分类任务,进而训练逻辑回归模型,这里的类别数量
V
V
V词库大小。
通常的文本数据中,词库少则数万,多则百万,在训练中直接训练多分类逻辑回归并不现实。
(2) word2vec中提供了两种针对大规模多分类问题的优化手段, negative sampling 和hierarchical softmax。在优化中,negative sampling 只更新少量负面类,从而减轻了计算量。hierarchical softmax 将词库表示成前缀树,从树根到叶子的路径可以表示为一系列二分类器,一次多分类计算的复杂度从|V|降低到了树的高度。整体的复杂度从。
Fasttext架构
fastText模型架构:其中
x
1
,
x
2
,
…
,
x
N
−
1
,
x
N
x_1,x_2,…,x_{N−1},x_N
x1,x2,…,xN−1,xN表示一个文本中的n-gram向量,每个特征是词向量的平均值。这和前文中提到的cbow相似,cbow用上下文去预测中心词,而此处用全部的n-gram去预测指定类别。
- x 1 , x 2 , … , x N − 1 , x N x_1,x_2,…,x_{N−1},x_N x1,x2,…,xN−1,xN一个句子的特征,初始值为随机生成也可以采用预训练的词向量
- hidden: X i X_i Xi 的平均值 x
- output: 样本标签
目标函数
N
N
N:样本个数
y
n
y_n
yn:第n个样本对应的类别
f
f
f:损失函数softmaxt
x
n
x_n
xn:第n个样本的归一化特征
A
A
A:权重矩阵(构建词,embedding)
B
B
B:权重矩阵(隐层到输出层)
词向量初始化
一个句子的embedding为
[
i
w
1
,
i
w
2
,
…
.
i
w
n
,
o
w
1
,
o
w
2
,
…
o
w
s
]
[iw_1,iw_2,….iw_n,ow_1,ow_2,…ow_s]
[iw1,iw2,….iwn,ow1,ow2,…ows]
i
w
i
iw_i
iwi:语料中出现的词,排在数组的前面
o
w
i
ow_i
owi:n-gram或n-char特征
初始化为随机数, 如果提供预训练的词向量,对应的词采用预训练的词向量
层次softmax
当语料类别较多时,使用hierarchical Softmax(hs)减轻计算量 hs利用Huffman 树实现,词生成词向量或label分类问题作为叶子节点 根据词或label的count构建Huffman树,则叶子到root一定存在一条路径利用逻辑回归二分类计算loss。
n-gram和n-char
Fasttext方法不同与word2vec方法,引入了两类特征并进行embedding。其中n-gram颗粒度是词与词之间,n-char是单个词之间。两类特征的存储均通过计算hash值的方法实现。
n-gram
示例: who am I? n-gram设置为2
n-gram特征有,who, who am, am, am I, I
n-char
示例: where, n=3, 设置起止符<, >
n-char特征有,<wh, whe, her, ere, er>
FastText词向量与word2vec对比
- 模型的输出层
- word2vec的输出层,对应下一个单词的概率最大值;fasttext的输出层是分类的label
- 模型的输入层:
- word2vec的输入层,是 context window 内的word;而fasttext 对应的整个sentence的内容,包括word,也包括 n-gram的内容;
代码
import fasttext
## 1 is positive, 0 is negative
f = open('train.txt', 'w')
f.write('__label__1 i love you\n')
f.write('__label__1 he loves me\n')
f.write('__label__1 she likes baseball\n')
f.write('__label__0 i hate you\n')
f.write('__label__0 sorry for that\n')
f.write('__label__0 this is awful')
f.close()
f = open('test.txt', 'w')
f.write('sorry hate you')
f.close()
## 训练
trainDataFile = 'train.txt'
classifier = fasttext.train_supervised(
input=trainDataFile, ## 文件输入
label_prefix='__label__', ## label前缀
dim=2,# 词向量维度
epoch=2, ## epoch次数
lr=1, # 学习率
lr_update_rate=50, # 多少步更新学习率
min_count=1, # 最少的单词出现次数
loss='softmax', ## loss function {ns, hs, softmax} [softmax]
word_ngrams=2, # n-gram 窗口大小
bucket=1000000) ## 叶子数
## 保存模型
classifier.save_model("Model.bin")
## 测试集测试
testDataFile = 'test.txt'
classifier = fasttext.load_model('Model.bin')
result = classifier.test(testDataFile)
print ('测试集上数据量', result[0])
print ('测试集上准确率', result[1])
print ('测试集上召回率', result[2])
res = classifier.predict(text=testDataFile)
print(res)
Fasttext 参数
The following arguments are mandatory:
-input training file path
-output output file path
The following arguments are optional:
-verbose verbosity level [2]
The following arguments for the dictionary are optional:
-minCount minimal number of word occurrences [1]
-minCountLabel minimal number of label occurrences [0]
-wordNgrams max length of word ngram [1]
-bucket number of buckets [2000000]
-minn min length of char ngram [0]
-maxn max length of char ngram [0]
-t sampling threshold [0.0001]
-label labels prefix [__label__]
The following arguments for training are optional:
-lr learning rate [0.1]
-lrUpdateRate change the rate of updates for the learning rate [100]
-dim size of word vectors [100]
-ws size of the context window [5]
-epoch number of epochs [5]
-neg number of negatives sampled [5]
-loss loss function {ns, hs, softmax} [softmax]
-thread number of threads [12]
-pretrainedVectors pretrained word vectors for supervised learning []
-saveOutput whether output params should be saved [0]
The following arguments for quantization are optional:
-cutoff number of words and ngrams to retain [0]
-retrain finetune embeddings if a cutoff is applied [0]
-qnorm quantizing the norm separately [0]
-qout quantizing the classifier [0]
-dsub size of each sub-vector [2]