fastText细节及实践

2021-05-11  本文已影响0人  Jarkata

fastText是Facebook于2016年开源的一个词向量计算和文本分类工具,在学术上并没有太大创新。但是它的优点也非常明显,在文本分类任务中,fastText(浅层网络)往往能取得和深度网络相媲美的精度,却在训练时间上比深度网络快许多数量级。在标准的多核CPU上, 能够训练10亿词级别语料库的词向量在10分钟之内,能够分类有着30万多类别的50多万句子在1分钟之内。

fastText 将每个中心词视为子词(subword)的集合,并学习子词的词向量。

fastText 模型是类似 CBOW 的三层结构,关于这个结构的介绍,很多博客都讲了,这里我不多赘述,我主要叙述一下其中的部分细节

N-gram

输入层是文档中所有词的词向量和文档中各个单词的n-gram向量。隐藏层是这些向量的叠加平均

从输入开始,fastText 和 CBOW 就不一样,主要在于 fastText 的输入还包括每个单词的 n-gram。举个例子,假设某个文档中只有三个词 I like apple,N-gram 的 N 取 3,那么隐藏层可表示为

这样做有什么好处?我们知道,"apple" 和 "apples" 在通常情况下几乎是同一个意思,但是如果仅使用传统的方法,以词为单位作为输入,输入的是每个词的 one-hot 编码,而 "apple" 和 "apples" 的 one-hot 可能并没有任何关系。但如果考虑 n-gram,它俩在字符级别是非常相似的,这样最终训练出来的词向量相比传统方法会更好

Hash

由于n-gram的量远比word大得多,完全存下所有的n-gram不太现实。fastText采用的是Hash桶的方式,把所有的n-gram映射到buckets个桶中,而映射到相同桶的n-gram共享同一个embedding vector,如下图所示


图中 Win 代表整个 Embedding 矩阵,其中前 V 行是 word Embedding,后 Buckets 行是 n-gram Embedding,每个 n-gram 通过 hash 函数之后映射到 0~Bucket-1 位置,得到对应的 embedding 向量。用哈希的方式既能保证查找时 O (1) 的效率,又可能把内存消耗控制在 O (buckets * dim) 范围内。不过这种方法潜在的问题是存在哈希冲突,不同的 n-gram 可能会共享同一个 embedding。如果桶大小取的足够大,这种影响会很小

实战

安装fasttext

安装非常简单,可以使用pip进行安装。

pip install fasttext

情感分析任务

训练数据train.txt:

__label__1 i love you
__label__1 he loves me
__label__1 she likes baseball
__label__0 i hate you
__label__0 sorry for that
__label__0 this is awful

测试数据test.txt

__label__1 i like you
__label__0 sorry hate you

加载并训练模型

import fasttext
model = fasttext.train_supervised('train.txt')
print(model.words)
print(model.labels)

预测:

print(model.predict('sorry hate you'))
print(model.predict('i like you'))

测试集验证PR:

def print_result(N,p,r):
    print('N\t'+str(N))
    print("P@{}\t{:.3f}".format(1, p))
    print("R@{}\t{:.3f}".format(1, r))

print_result(*model.test('test.txt'))

参考

python——Fasttext新手学习笔记

上一篇下一篇

猜你喜欢

热点阅读