持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情
使用fastText构建单词向量
fastText
是 Facebook
研究团队提出的算法模型,用于有效学习单词表示和句子分类。fastText
与 word2vec
的不同之处在于 word2vec
将每个单词视为最小单位,学习其向量表示形式,但是 fastText
假定一个单词由 n-gram
组成。例如,sunny
由 [sun, sunn, sunny]
,[sunny, unny, nny]
等组成,在其中我们看到了大小为 n
的原始单词的子集,其中 n
的范围可以从 1
到原始单词的长度。
使用 fastText
的另一个原因是,可以解决单词不符合 skip-gram
或 CBOW
模型中的最小频率截止值的情况。例如,appended
一词与 append
本质上具有相同的意义。但是,如果 append
频率较高,但在新句子中使用了 append
这个单词而不是 append
,那么我们就无法获取准确的 appended
向量。在这种情况下,fastText
的 n-gram
就会派上用场了。
实际上,fastText
后续同样使用 skip-gram/CBOW
模型,但是,它增加了输入数据集,因此可以将没有见过的单词也考虑在内。
fastText 提取单词向量
我们基于 fastText
提取单词向量的策略如下:
- 在gensim库中使用fastText方法
- 预处理输入数据
- 将每个输入句子分解单词列表
- 根据上一步得到的分解结果构建词汇表
- 使用先前的输入数据训练模型
- 计算单词之间的相似度
使用 Keras 实现 fastText 生成单词向量
本节中,我们利用 Keras
实现使用 fastText
生成单词向量。 首先,导入相关包,并加载数据集:
from gensim.models.fasttext import FastText
import pandas as pd
data = pd.read_csv('archive/Tweets.csv')
print(data.head())
预处理数据集并将其转换为列表,其中每个元素是每个句子中的列表,此过程与我们在 word2vec
模型所进行的预处理和转换步骤相同:
stop = set(stopwords.words('english'))
def preprocess(text):
text=text.lower()
text=re.sub('[^0-9a-zA-Z]+',' ',text)
words = text.split()
words2 = [i for i in words if i not in stop]
words3=' '.join(words2)
return(words3)
data['text'] = data['text'].apply(preprocess)
list_words=[]
for i in range(len(data)):
list_words.append(data['text'][i].split())
定义模型,使用参数 vector_size
指定每个单词的向量维度,并构建词汇表:
ft_model = FastText(vector_size=50)
ft_model.build_vocab(list_words)
训练模型:
ft_model.train(list_words, total_examples=ft_model.corpus_count,epochs=100)
检查模型词汇表中不存在的单词的单词向量。例如,词汇中出现了单词 first
;但是,词汇中没有 firstly
这个词,在这种情况下,我们检查 first
和 firstly
的词向量之间的相似性:
print(ft_model.wv.similarity('first','firstly'))
计算的输出结果为 0.90
,表明两个单词之间的相似度非常高:
0.90227515
因此,我们可以看到 fastText
模型得到的单词向量可以帮助我们为词汇表中不存在的单词生成单词向量。
我们也可以使用该方法也来纠正数据集内的拼写错误,因为拼写错误的单词很可能很少出现,而出现频率较高的最相似的单词更可能是拼写错误单词的正确版本。因此,我们可以使用向量算法执行拼写校正,如下所示:
result = ft_model.wv.most_similar(positive=['exprience', 'prmise'], negative=['experience'], topn=1)
print(result)
在前面的代码中,positive
中有单词拼写错误,而 negative
中没有拼写错误,代码的输出是 promise
。因此,可以使用此方式纠正拼写错误:
[('promise', 0.6496826410293579)]
此外,还可以使用 most_similar
方法达到相同的效果:
print(ft_model.wv.most_similar('exprience', topn=1))
# [('experience',0.9027844071388245)]
但是,需要注意的是,当数据集中拼写错误频率较高时,该方法并不能得到预期结果。