赞
踩
fasttext理论知识
• 参考文献
○ https://heleifz.github.io/14732610572844.html
• fasttext官方文档,上面有很多的已经训练好的词向量
• embedding其实是fasttext用于分类任务时产生的副产物
• fasttest主要思想
○ (1)字符级别的n-gram
word2vec把语料库中的每个单词当成原子的,它会为每个单词生成一个向量。这忽略了单词内部的形态特征,比如:“apple” 和“apples”,“达观数据”和“达观”,这两个例子中,两个单词都有较多公共字符,即它们的内部形态类似,但是在传统的word2vec中,这种单词内部形态信息因为它们被转换成不同的id丢失了。
为了克服这个问题,fastText使用了字符级别的n-grams来表示一个单词。对于单词“apple”,假设n的取值为3,则它的trigram有
“<ap”, “app”, “ppl”, “ple”, “le>”
其中,<表示前缀,>表示后缀。于是,我们可以用这些trigram来表示“apple”这个单词,进一步,我们可以用这5个trigram的向量叠加来表示“apple”的词向量。
这带来两点好处:
1. 对于低频词生成的词向量效果会更好。因为它们的n-gram可以和其它词共享。
2. 对于训练词库之外的单词,仍然可以构建它们的词向量。我们可以叠加它们的字符级n-gram向量。
来自 https://blog.csdn.net/u010417185/article/details/80649009
○ (2)模型架构
之前提到过,fastText模型架构和word2vec的CBOW模型架构非常相似。下面是fastText模型架构图:
注意:此架构图没有展示词向量的训练过程。可以看到,和CBOW一样,fastText模型也只有三层:输入层、隐含层、输出层(Hierarchical Softmax),输入都是多个经向量表示的单词,输出都是一个特定的target,隐含层都是对多个词向量的叠加平均。不同的是,CBOW的输入是目标单词的上下文,fastText的输入是多个单词及其n-gram特征,这些特征用来表示单个文档;CBOW的输入单词被onehot编码过,fastText的输入特征是被embedding过;CBOW的输出是目标词汇,fastText的输出是文档对应的类标。
值得注意的是,fastText在输入时,将单词的字符级别的n-gram向量作为额外的特征;在输出时,fastText采用了分层Softmax,大大降低了模型训练时间。这两个知识点在前文中已经讲过,这里不再赘述。
来自 https://blog.csdn.net/u010417185/article/details/80649009
○ 3)核心思想
现在抛开那些不是很讨人喜欢的公式推导,来想一想fastText文本分类的核心思想是什么?
仔细观察模型的后半部分,即从隐含层输出到输出层输出,会发现它就是一个softmax线性多类别分类器,分类器的输入是一个用来表征当前文档的向量;模型的前半部分,即从输入层输入到隐含层输出部分,主要在做一件事情:生成用来表征文档的向量。那么它是如何做的呢?叠加构成这篇文档的所有词及n-gram的词向量,然后取平均。叠加词向量背后的思想就是传统的词袋法,即将文档看成一个由词构成的集合。
于是fastText的核心思想就是:将整篇文档的词及n-gram向量叠加平均得到文档向量,然后使用文档向量做softmax多分类。这中间涉及到两个技巧:字符级n-gram特征的引入以及分层Softmax分类。
来自 https://blog.csdn.net/u010417185/article/details/80649009
○ (4)关于分类效果
还有个问题,就是为何fastText的分类效果常常不输于传统的非线性分类器?
假设我们有两段文本:
我 来到 达观数据
俺 去了 达而观信息科技
这两段文本意思几乎一模一样,如果要分类,肯定要分到同一个类中去。但在传统的分类器中,用来表征这两段文本的向量可能差距非常大。传统的文本分类中,你需要计算出每个词的权重,比如tfidf值, “我”和“俺” 算出的tfidf值相差可能会比较大,其它词类似,于是,VSM(向量空间模型)中用来表征这两段文本的文本向量差别可能比较大。但是fastText就不一样了,它是用单词的embedding叠加获得的文档向量,词向量的重要特点就是向量的距离可以用来衡量单词间的语义相似程度,于是,在fastText模型中,这两段文本的向量应该是非常相似的,于是,它们很大概率会被分到同一个类中。
使用词embedding而非词本身作为特征,这是fastText效果好的一个原因;另一个原因就是字符级n-gram特征的引入对分类效果会有一些提升 。
来自 https://blog.csdn.net/u010417185/article/details/80649009
• fasttext主要步骤
○ 得到每个单词的词位置
○ 得到各个文档中单词的位置向量,将一个文档表示成一个向量[10, 30, 80, 1000] 可能表示“我 昨天 来到 达观数据”这个短文本,其中“我”、“昨天”、“来到”、“达观数据”在词汇表中的索引分别是10、30、80、1000;(正常的还应该添加了n-gram处理)
○ 对文档中每个单词进行embedding处理
○ 对多个词向量的叠加平均,使得一个文档变成一个词向量
来自 https://blog.csdn.net/u010417185/article/details/80649009
○ 对单个文档合成的词向量进行softmax多分类
• fasttext和word2vec的区别
○ Word2vec使用一个词的上下文的所有词向量之和来预测词本身(CBOW 模型),fasttext改为用一段短文本的词向量之和来对文本进行分类。
来自 https://heleifz.github.io/14732610572844.html
○ fastText的embedding是通过supervised的方式来训练一个文本分类器并同时学习embedding的话,那么这个embedding的学习过程就是有监督的,与word2vec等无监督的模型是有一定区别的;第二是fastText还会学习n-gram(这里的n-gram其实有两种,分别是char-n-gram和word-n-gram,就不展开说了,真正有兴趣的话可以读读源码)的embedding,这使得它可以在一定程度上捕捉词序信息。为了节省空间,fastText在原作者的实现中并不是每一个n-gram都学习一个单独的embedding,而是首先将n-gram进行hash,hash到同一个位置的多个n-gram是会共享一个embedding的。
来自 https://zhuanlan.zhihu.com/p/32965521
○ 模型的输出层:word2vec的输出层,对应的是每一个term,计算某term的概率最大;而fasttext的输出层对应的是 分类的label。不过不管输出层对应的是什么内容,起对应的vector都不会被保留和使用;
○ 模型的输入层:word2vec的输出层,是 context window 内的term;而fasttext 对应的整个sentence的内容,包括term,也包括 n-gram的内容;
○ 两者本质的不同,体现在 h-softmax的使用。
Wordvec的目的是得到词向量,该词向量 最终是在输入层得到,输出层对应的 h-softmax 也会生成一系列的向量,但最终都被抛弃,不会使用。
fasttext则充分利用了h-softmax的分类功能,遍历分类树的所有叶节点,找到概率最大的label(一个或者N个)
fasttext实战
gensim中的fasttext教程
fasttext JAVA版本API
• 在github上找的fasttext的重新训练的方法
○ c++:
./fasttext [supervised | skipgram | cbow] -input train.data -inputModel trained.model.bin -output re-trained [other options] -incr
来自 https://github.com/facebookresearch/fastText/pull/423
-incr stands for incremental training. When training word embedding, one could do it from scratch with all data at each time, or just on the new data. For classification, one could train it from scratch with pre-trained word embedding with all data, or only the new one, with no changing of the word embedding. Incremental training actually means, having finished training model with data we got before, and retrain the model with newer data we get, not from scratch. • python import fastText as ft # train the model with the first document: model = ft.train_unsupervised( input="my-first-document.txt", ... incr=False inputModel="" ) # save the model: model.save_model("my-model.bin") # then, later... update the model with the new documents: model = ft.train_unsupervised( input="my-second-document.txt", ... incr=True inputModel="my-model.bin" ) # and save the model over the previous: model.save_model("my-model.bin")
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。