子词嵌入-FastText介绍

 

我们之前学了很多词语言模型:
image
如果我们词独立的话有方法:One-hot、Bag of words、IF-IDF。
然后如果我们假设词与词之间是相互关联的话有方法:word2vec,FastText和Glove。

在英语中,“helps”“helped”和“helping”等单词都是同⼀个词“help”的变形形式。“dog”和“dogs”之间的关系与“cat”和“cats”之间的关系相同,“boy”和“boyfriend”之间的关系与“girl”和“girlfriend”之间的关系相同。在法语和西班⽛语等其他语⾔中,许多动词有40多种变形形式,⽽在芬兰语中,名词最多可能有15种变形。在语⾔学中,形态学研究单词形成和词汇关系。但是,word2vec和GloVe都没有对词的内部结构进⾏探讨。

fastText模型

结构

FastText在模型结构上采用了CBOW模型的结构,结构如下:
image
其中这里的x1,x2,,xN是输入的词,整个网络与CBOW都一样,不同之处主要有以下方面:

  1. CBOW预测的是中心词,FastText最后输出的是各个标签的概率;
  2. FastText 由于面向的是超多分类以及大量数据的情况,所以FastText 最后的输出采用了层级Softmax,大大优化了模型的运行速度

n-gram

首先要声明,在原论文中,n-gram并不是FastText必要的步骤,仅仅是一个锦上添花的步骤而已,没有n-gram它还是FastText。

引入n-gram首先是为了解决word2vec中的词序问题,比如两个句子"你礼貌吗"和"礼貌你吗"这两个句子仅仅词序不同,但是意思却天差地别,这种情况word2vec是检测不到词序的不同的,由此提出了n-gram。

注意,词分类模型的n-gram的是word级别的,并不是字符级别的,比如,有如下的句子

Ihaveanapple

如果n-gram中的n=2时,那么输入其中的句子经过n-gram后被分为以下部分 I Ihave,havean,anapple三个部分,输入也是这三个部分。

尽管如此,还是需要注意一下几个方面:

  1. 分类模型的n-gram是word级别的,并非字符级别
  2. n-gram并不是FastText模型中必须的,仅仅是锦上添花
  3. CBOW和 FastText都是用求和平均值来预测的
  4. 词向量初始化都是随机的,FastText 并没有在 word2vec 预训练词嵌入的基础上再训练

why 要提出FastText: Word2Vec的局限

1.不能处理训练中未出现的词(Out of Vocabulary, OOV)
例如: tensor,flow已在Word2Vec的词典出现过,但tensorflow未出现过->OOV error
image
2.无法处理形态相同的词(morphology),即词根相同的词
对于具有相同词根(eat)的词,eaten,eating,eats,他们之间较难同时出现,不能实现参数共享,即语义类似。因为实际中把他们都当作独一无二的词进行训练
image

FastText 词嵌入模型

FastText 模型中也引入了n-gram,n-gram的引入其实是为了解决word2vec忽略词型的问题。比如单词eat,eaten其实就是一个单词的不同时态,但是,在不同语境下,其词向量可能会相差特别大,而引入n-gram就是为了能够很好的解决词的形态学方面的问题。
例如一个单词normal,如果使用n-gram,当n=3时,可以将其分为nor,orm,rma,mal四个部分,在使用n-gram时一般会用一个尖括号将单词括起来,表示这个单词的开始和结束,如normal变为<normal>,相应的n-gram也就分为<no,nor,orm,rma,mal,al> 六个部分,其中每个部分又称为子词。
引入了n-gram后,接下来需要做的就是将n-gram后的部分输入模型,这里因为是根据word2vec改进的,所以依旧使用的是Skipgram模型,而这里输入的时候,因为我们有子词以及词,就又会有不同的选择了。

子词
词+子词
对于word2vec而言,其训练的有中心词以及周围词矩阵,设a为中心词矩阵,b为周围词矩阵,那么搭配就有很多种,这里FastText选择的是a3+b1,即对中心词使用子词+词的输入来预测周围词。

其实就是:

  • step1:给定一个词,在词的首尾加上<>表示开始与结束

image

  • step2:设定n-gram的滑动窗口大小h=3(可以为其它大小),对该词进行滑动
    image
  • step3: 得到该单词一系列n-grams
    image
  • step4:当n=3,4,5,6时所得到的n-grams列表
    image

案例理解FastText

以一个案例来理解训练过程,假设有这样一句话: eating是中心词,am与food是周围词,给定中心词预测周围词
image

  • step1: 获取中心词的embedding:将中心词与其产生的sub-words向量相加(其它合并方式会不会好一点?)获得中心词的向量Wcenter
    image
  • step2:step2获取实际周围词的嵌入(没有做sub-words生成)向量wam, WfoodWcenter
    image
  • step3:获取negative samples词:随机采样,对于一个中心词,采样5个nagatie samples,比如这里其中两个词为pairs,earth,即Wpairs, Wearth
    image
  • step4:根据loss更新参数:NEG=(wam,Wfood)POS=(WpairsWearth)Wcenter做内积运算并sigmoid,使得NEG词与center词距离越来越远,POS与center距离越来越近。
    image

FastText的实现

实现FastText的过程与word2vec相差不大,唯一的差距就是word2vec使用的是一个单词来预测上下文,而FastText使用的是word+gram后的结果来进行上下文的预测,由于二者的相似性,这里就不再一步步的给大家进行实现了,如果要训练FastText模型,可以安装fasttext库或者使用gensim.models中的Fasttext模型,gensim中的函数是生词词向量,fasttext中既含有词向量的生成,也含有文本分类,具体使用方法如下。

gensim

训练模型
训练模型直接调用构造函数即可,该构造函数的参数如下:

参数 描述 可选值
vector_size 词向量维度 整数
window 词向量窗口大小 整数
epochs 训练轮次 整数
negative 负采样个数 整数
sg 是否使用skipgram,1是使用,0是用cbow 0,1
hs 是否使用层化softmax,1是使用,0是不使用 0,1
alpha 学习率 0-1
from gensim.models import FastText
from gensim.models.word2vec import LineSentence

model=FastText(LineSentence(open(r'../GloVe/data/test.txt', 'r', encoding='utf8')),
               vector_size=150, window=5, min_count=5, epochs=10, min_n=3, max_n=6, word_ngrams=1,workers=4)

常用API

API 描述
model.wv[word] 得到 word 的词向量
"nights" in model.wv.vocab 判断词是否在词向量中
model.similarity("night", "nights") 计算两个词的相似度
model.most_similar(word, topn=n) 查找最相关的两个词
model.similarity("night", "nights") 计算两个词的相似度

保存模型

API 描述
model.wv.save_word2vec_format('fasttext.vector', binary=False) 保存词向量
model.save('fasttext_test.model') 保存模型
model = FastText.load('fasttext_test.model') 载入模型

fasttext

词向量训练

训练模型
这里我们以前面的预处理的文本做示例,文本处理如下。
image
训练词向量使用的函数为train_unsupervised,其常用参数如下:

参数 描述 可选参数 默认值
input 输入的文件
lr 学习率 0-1 0.1
dim 学习后词向量维度 整数 100
ws 背景词 整数 5
neg 负采样个数 整数 5
epoch 训练轮次 整数 5
model 训练的方式 skipgram,cbow skipgram
wordNgrams n-gram的值 整数 1
loss 损失函数 可选ns, hs, softmax, ova,hs为层化softmax,ova用于多标签分类 softmax

常用API

API 描述
model.get_word_vector(word) 得到 word 的词向量
model.get_nearest_neighbors(word) 得到距离 word 最近的10个词向量
model.get_analogies(a,b,c) 类比,类比 a 和 b 的关系,得到 c 对应该关系的词

保存和加载模型

使用model.save_model(filename)以及model.load_model(filename) 即可。

文本分类

训练模型

Fasttext用于分类使用的函数是train_unsupervised,该函数对传入的文本数据有一定的要求,其要求传入的数据标签在前,语句在后,且标签前加上 __label__ 前缀,格式示例如下:

__label__sauce __label__cheese How much does potato starch affect a cheese sauce recipe?
__label__food-safety __label__acidity Dangerous pathogens capable of growing in acidic environments
__label__cast-iron __label__stove How do I cover up the white spots on my cast iron stove?
__label__restaurant Michelin Three Star Restaurant; but if the chef is not there
__label__knife-skills __label__dicing Without knife skills, how can I quickly and accurately dice vegetables?
__label__storage-method __label__equipment __label__bread What's the purpose of a bread box?
__label__baking __label__food-safety __label__substitutions __label__peanuts how to seperate peanut oil from roasted peanuts at home?
__label__chocolate American equivalent for British chocolate terms

比如上述的第一行,其标签就为sauce, cheese,句子为 How much does potato starch affect a cheese sauce recipe?,该函数的API如下:

参数 描述 可选参数 默认值
input 输入的文件
lr 学习率 0-1 0.1
dim 学习后词向量维度 整数 100
ws 背景词 整数 5
neg 负采样个数 整数 5
epoch 训练轮次 整数 5
model 训练的方式 skipgram,cbow skipgram
wordNgrams n-gram的值 整数 1
loss 损失函数 可选ns, hs, softmax, ova,hs为层化softmax,ova用于多标签分类 softmax
label 标签的前缀 字符串 label

常用API

API 描述
model.test(file) 对文件进行测试集的测试,返回三个参数,分别是 样本数,准确率,召回率
model.pridict(sentence,k=-1) 预测句子所属的类别,返回各个标签及概率,k=-1 表示返回全部标签及其概率

保存和加载模型

使用model.save_model(filename)以及model.load_model(filename)即可。

参考文献:
https://blog.csdn.net/ifhuke/article/details/127944112

https://www.bilibili.com/video/BV1p44y1J7wk/?spm_id_from=333.337.search-card.all.click&vd_source=deecae4bbb8195cab39644b4de7b667e

posted @   lipu123  阅读(171)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示