FastText工具——简化word2vec训练、快速实现文本分类

📅 2026/6/24 5:32:50
FastText工具——简化word2vec训练、快速实现文本分类
问题与思考1. fasttext是如何将文本转换为向量的子词向量—词向量—文本向量1子词向量通过无监督的神经网络模型在训练过程中自动学习得到的是模型在预测上下文Skip-gram或预测中心词CBOW时通过反向传播算法不断调整优化出来的。子词向量的生成和更新过程如下①初始化与存储构建一个包含所有词汇及其子词片段的字典例如 “pla”、“lay”、“ing”都会被随机初始化为一个低维的实数向量。② 参与前向传播预测任务当模型处理一个目标单词例如 “playing”时提取该单词的所有子词片段。(pla,play,layi,ayin,ying,ing)将这些子词对应的向量从查找表中取出并进行相加或求平均组合成该单词的当前词向量表示。将这个组合后的词向量输入到神经网络的隐藏层去预测它的上下文单词Skip-gram 模式或者由上下文单词预测它CBOW 模式。③计算损失与反向传播模型会将预测结果与真实的上下文进行对比计算损失函数Loss。然后通过反向传播算法Backpropagation将误差从输出层逐层传回。④ 向量更新核心机制当误差传回时fastText 会更新参与计算的向量误差不仅会更新中心词的向量还会按比例分配并更新该词包含的所有子词向量。这意味着如果单词 “playing” 和 “played” 经常出现在相似的上下文中它们在反向传播时产生的梯度更新方向就会非常相似。由于它们共享了相同的子词片段如 “play”这个共同的子词向量就会在训练中被反复推向一个能够同时适应 “playing” 和 “played” 语义的向量空间位置。为什么不直接转换、而是要进行训练获得得到子词之间的相似性经过海量文本的训练那些经常出现在相似语境中的子词片段其向量在空间中的距离就会越来越近。最终这些子词向量就隐式地学到了词根、词缀等形态学信息例如 “ing” 向量可能带有“进行时”的语义特征“un” 向量可能带有“否定”的语义特征从而让组合出的词向量具备极强的泛化能力。2词向量一个单词的最终词向量是通过将其包含的所有子词向量进行相加或求平均得到的未登录词OOV处理由于这种基于子词的机制即使遇到训练集中从未出现过的新词fastText 也能通过组合其包含的子词向量来推断并生成大致的词向量表示具备极强的泛化能力3文本向量分词首先将输入的句子分割成单个单词Token例如将 “I love fastText” 分词为 [“I”, “love”, “fastText”]。检索根据上述的子词机制获取句子中每个单词对应的 fastText 词向量。求平均将句子中所有单词的向量进行相加然后除以单词的总数量得出平均值。这个平均向量即代表了整段文本句子的嵌入向量。2. fasttext是如何实现文本分类的① 文本向量化输入层:fastText 首先将输入的文本句子或段落转化为一个固定维度的稠密向量机制提取文本中所有的词利用子词Subword机制获取每个词的向量然后对这些词向量进行平均池化Averaging。结果无论原始文本有多长最终都会被压缩成一个固定大小的文本表示向量通常维度为 100~300。② 隐藏层特征提取线性映射:获得文本向量后将其输入到一个单层的隐藏层Hidden Layer中机制通过一个全连接层矩阵乘法将文本向量映射到一个新的特征空间。作用这一步相当于提取了文本的深层语义特征。在这个阶段fastText 还可以选择性地加入N-gram 特征如双词组合 bigram以捕获局部的词序和短语搭配信息弥补纯平均池化丢失词序的缺陷。③ 分类预测输出层:隐藏层输出的特征向量接着被送入输出层机制输出层同样是一个全连接层其神经元数量等于分类标签Categories的数量。激活函数对于多分类任务通常使用Softmax函数输出每个类别的概率分布。对于多标签任务一篇文章属于多个类别则使用多个独立的Sigmoid函数。④ 损失计算与训练优化过程损失函数模型使用交叉熵损失Cross-Entropy Loss来衡量预测概率与真实标签之间的差距。优化器采用随机梯度下降SGD及其变种如 ASGD来更新网络参数。层次 SoftmaxHierarchical Softmax为了解决类别数量极大时 Softmax 计算缓慢的问题fastText 在底层实现中通常使用层次 Softmax 技术将多分类问题转化为一系列的二分类问题从而大幅降低计算复杂度。3.层次softmax是如何减少复杂度提升效率的在传统的softmax中计算目标词的概率需要计算整个词汇表中所有词的概率这在词汇表非常大的情况下计算开销非常大。层次softmax通过构建一个二叉树将出现频次高的词放置到接近根节点使得每次预测时只需要计算沿路径的几个节点从而显著降低了计算量。4.什么是负采样负采样Negative Sampling是在word2id训练时使用选取正样本(目标值真实的上下文数据) 和负样本(从词表中随机取k个数据)每次反向传播更新时只更新k1个数据从而大大降低了计算复杂度、提升了计算效率。一、FastText工具介绍1. 什么是FastText?FastText是由Facebook AI Research (FAIR) 开发的一款高效文本表示和分类工具。它基于Word2Vec的思想但进行了扩展能够处理子词信息适用于多种自然语言处理任务如文本分类、词向量训练等2. FastText作用文本分类它通过将文本表示为词向量的平均值结合线性分类器如 softmax进行训练和预测。该方法非常快速能够在短时间内处理大量文本数据并生成分类模型。实现快速而准确的文本分类包括多分类和二分类词嵌入在word2vec训练时采用负采样、霍夫曼树每次更新时只设计少量样本可以大大调高训练的效率3. FastText特点子词信息 FastText不仅考虑整个词还考虑词的子结构这使得它能够更好地处理未登录词OOV, Out-of-Vocabulary和形态丰富的语言高效训练FastText使用了层次化softmax和负采样等技术使得训练速度非常快尤其适合大规模数据集。多任务支持FastText支持词向量训练和文本分类两种主要任务4. FastText核心概念字符级别的N-gramFastText的核心思想是将单词分解成字符级别的n-grams例如对于单词 apple当 n3 时其3-gram包括ap, app, ppl, ple, le单词的前后加和是为了区分前缀和后缀。子词信息Subword Representation将每个n-gram视为一个独立的单元学习它们的向量表示。单词的向量则由组成该单词的所有n-gram向量的平均值得到。基于负采样的skipgramSkipgram with Negative SamplingSGNS选取正样本(目标值真实的上下文数据) 和负样本(从词表中随机取k个数据)每次反向传播更新时只更新k1个数据从而大大降低了计算复杂度、提升了计算效率。分层softmaxSoftmax Classifier在传统的softmax中计算目标词的概率需要计算整个词汇表中所有词的概率这在词汇表非常大的情况下计算开销非常大。层次softmax通过构建一个二叉树将出现频次高的词放置到接近根节点使得每次预测时只需要计算沿路径的几个节点从而显著降低了计算量。5. FastText优缺点在保持较高精度的情况下, 快速的进行训练和预测是FastText的最大优势。优点FastText工具包中内含的FastText模型具有十分简单的网络结构相比其他NLP模型FastText在处理大规模文本数据时的速度更快。使用FastText模型训练词向量时使用层次softmax结构, 来提升超多类别下的模型性能。由于FastText模型过于简单无法捕捉词序特征, 因此会进行n-gram特征提取以弥补模型缺陷提升精度缺点对于非常短的文本效果可能不如深度学习的其他模型。需要大量数据才能训练出高质量的模型。6. FastText安装# 在python解析器中安装FastText包pip install fasttext验证二、FastText架构介绍1. FastText模型架构Skip-gram模型、CBOWContinuous Bag of Words模型将这些子词对应的向量从查找表中取出并进行相加或求平均组合成该单词的当前词向量表示。将这个组合后的词向量输入到神经网络的隐藏层去预测它的上下文单词Skip-gram 模式或者由上下文单词预测它CBOW 模式。模型会将预测结果与真实的上下文进行对比计算损失函数Loss。然后通过反向传播算法Backpropagation将误差从输出层逐层传回。当误差传回时fastText 会更新参与计算的向量2. 层次softmax层次softmax是如何减少复杂度提升效率的在传统的softmax中计算目标词的概率需要计算整个词汇表中所有词的概率这在词汇表非常大的情况下计算开销非常大。层次softmax通过构建一个二叉树将出现频次高的词放置到接近根节点使得每次预测时只需要计算沿路径的几个节点从而显著降低了计算量。2.1 霍夫曼树介绍概念霍夫曼树是一种带权路径长度最短的二叉树频率高的词在树中的路径较短频率低的词路径较长每个词通过霍夫曼编码映射到一条唯一的路径。路径是从根节点到叶子节点的节点序列路径的长度与词的出现频率成反比频率高的词路径短频率低的词路径长。作用作用在输出层层次化 SoftmaxHierarchical Softmax其核心作用是大幅降低计算复杂度显著提升模型的训练与预测速度将多分类转化为二分类路径选择模型在计算概率时只需遍历从根节点到目标节点的路径并将路径上所有二分类的概率相乘。每次都在做二分类任务且频次越高的词越靠近根节点使用的频率越高从而大大提升效率2.2 霍夫曼树相关概念二叉树:每个节点最多有2个子树的有序树, 两个子树分别称为左子树、右子树。有序的意思是: 树有左右之分, 不能颠倒。叶子节点:一棵树当中没有子节点的节点称为叶子节点。路径和路径长度:在一棵树中, 从一个节点往下可以到达孩子或孙子节点之间的通路, 称为路径。通路中分支的数目称为路径长度。节点的权及带权路径长度:若将树中节点赋予一个有某种含义的数值, 则这个数值称为该节点的权, 节点的带权路径长度为: 从根节点到该节点之间的路径长度与该节点的权的乘积。树的带权路径长度:树的带权路径长度规定为所有叶子节点的带权路径长度之和, 记为WPL(weighted path length)。WPL最小的二叉树就是霍夫曼树。2.3 构建霍夫曼树2.3.1 构建步骤初始化为每个词汇或符号创建一个叶子节点节点的权重为词频或概率。将所有节点放入一个优先队列按权重从小到大排序。合并节点从优先队列中取出权重最小的两个节点。创建一个新的内部节点其权重为这两个节点权重之和左子节点为权重较小的节点右子节点为权重较大的节点。删除从优先队列中取出权重最小的两个节点将新节点放回优先队列。重复合并重复步骤2合并节点直到优先队列中只剩一个节点。这个节点就是霍夫曼树的根节点。生成编码从根节点开始向左子树走记为0向右子树走记为1。每个叶子节点的路径即为该符号的霍夫曼编码。2.3.2 示例假设有以下词汇及其频率词汇频率A5B9C12D13E16F45步骤1初始化创建叶子节点A(5),B(9),C(12),D(13),E(16),F(45)。将所有节点放入优先队列按频率排序[A(5), B(9), C(12), D(13), E(16), F(45)]。步骤2第一次合并取出频率最小的两个节点A(5)和B(9)。创建新节点N1(14)左子节点为A(5)右子节点为B(9)。将N1(14)放回优先队列[C(12), D(13), N1(14), E(16), F(45)]。步骤3第二次合并取出频率最小的两个节点C(12)和D(13)。创建新节点N2(25)左子节点为C(12)右子节点为D(13)。将N2(25)放回优先队列[N1(14), E(16), N2(25), F(45)]。步骤4第三次合并取出频率最小的两个节点N1(14)和E(16)。创建新节点N3(30)左子节点为N1(14)右子节点为E(16)。将N3(30)放回优先队列[N2(25), N3(30), F(45)]。步骤5第四次合并取出频率最小的两个节点N2(25)和N3(30)。创建新节点N4(55)左子节点为N2(25)右子节点为N3(30)。将N4(55)放回优先队列[F(45), N4(55)]。步骤6第五次合并取出频率最小的两个节点F(45)和N4(55)。创建新节点N5(100)左子节点为F(45)右子节点为N4(55)。优先队列中只剩一个节点N5(100)构建完成。最终霍夫曼树结构霍夫曼编码从根节点到每个叶子节点的路径即为该词汇的霍夫曼编码词汇路径编码F左0C右 - 左100D右 - 右101A右 - 左1100B右 - 右1101E右 - 右1112.4 【了解】霍夫曼编码转化为梯度计算步骤 1定义霍夫曼树每个内部节点 v 有一个参数向量 θv。每个叶子节点对应一个词汇。步骤 2计算目标词的概率对于目标词 ww其概率 P(w∣context)$是通过霍夫曼树路径上的二分类器的概率乘积得到的其中Path(w) 是从根节点到目标词 ww 的路径。directionv是在节点 vv 的决策方向左或右。P(directionv∣context,θv)是节点 v 的二分类器概率。步骤 3定义二分类器概率在节点 v二分类器的概率通常使用逻辑回归其中hh 是上下文向量例如Word2Vec 中的隐藏层输出。σ 是 Sigmoid 函数。步骤 4计算损失函数损失函数为负对数似然将 P(w∣context)代入步骤 5计算梯度对每个节点 v 的参数 θv 和上下文向量 h 计算梯度:对 θv的梯度其中 I(⋅)是指示函数如果方向为左则为1否则为0。对 hh的梯度步骤 6更新参数使用梯度下降法更新参数其中 ηη是学习率。2.5 层次softmax工作原理霍夫曼树:每个叶子节点代表一个词每个非叶子节点代表一个二元分类问题。 词频高的词在树的较高层词频低的词在树的较低层。 这使得高频词的路径更短从而减少计算。路径编码:从根节点到叶子节点的路径可以被编码为一个二元码 (0 或 1)其中0代表左子树1代表右子树。概率计算:每个非叶子节点代表一个二元分类问题使用sigmoid函数计算概率。 从根节点到叶子节点的概率是路径上所有节点概率的乘积。2.6 层次softmax优势计算效率高层次Softmax将计算复杂度从O(V)降低到O(logV)其中V是词汇量的大小。内存效率高只需要存储树的结构和节点的参数不需要存储整个词汇表的参数。3. 负采样3.1 什么是负采样负采样Negative Sampling是在word2id训练时使用选取正样本(目标值真实的上下文数据) 和负样本(从词表中随机取k个数据)每次反向传播更新时只更新k1个数据从而大大降低了计算复杂度、提升了计算效率。3.2 负采样原理1. 解决的核心问题归一化常数计算极其耗时在传统的语言模型或 Skip-gram 模型中为了计算某个词作为上下文词的概率需要使用 Softmax 函数。Softmax 的分母需要对整个词汇表V中所有词的得分进行求和即计算归一化常数。当词汇表极大例如百万级别时每次更新参数都需要遍历整个词汇表导致计算复杂度高达 O(V)这在工程上是不可接受的。2. 负采样的作用与原理将全局问题转化为局部二分类负采样彻底抛弃了全局 Softmax 的计算将模型的目标函数从“在 V 个词中选出正确的词多分类”转化为了“区分正确的词(预测词的真实的上下文)和几个错误的词(随机取k个)二分类”。正样本当前中心词及其真实出现的上下文词。负样本从词汇表中按照特定分布通常是词频的 3/4 次方分布随机采样出 K 个没有在当前上下文出现的词。模型只需计算这 1 个正样本和 K 个负样本通常 K 取 5~20的 Sigmoid 概率并更新这些词的向量参数。3.3 负采样优势计算与更新更高效每次训练更新只涉及 1K 个词时间复杂度从 O(V) 降到了 O(K)。K 是一个极小的常数随机取的负样本的个数因此训练速度非常快。更适合并行计算霍夫曼树由于节点间存在依赖关系难以并行化而负采样每次采样的正负样本是相互独立的非常适合在 GPU 或多核 CPU 上进行大规模并行训练。对低频词更友好霍夫曼树将高频词放在浅层对高频词计算快但低频词路径长更新慢。负采样通过调整采样分布降低高频词被选为负样本的概率能够保证低频词也有足够的机会被采样到并得到充分训练。三、FastText文本分类1. 文本分类介绍文本分类是什么文本分类是给文档例如电子邮件帖子文本消息产品评论等分配一个或多个类别。当今文本分类的实现多是使用机器学习方法从训练数据中提取分类规则进行分类, 因此构建文本分类都是有监督的学习。核心思想词袋模型Bag of Words将文本表示为词向量的平均值。子词信息n-grams通过引入子词信息如字符级别的 n-gramsFastText能够捕捉到词的内部结构从而更好地处理未登录词OOV, Out-of-Vocabulary和形态丰富的语言。层次Softmax或负采样为了加速训练FastText使用层次Softmax或负采样来优化损失函数。种类二分类文本被分类是否两个类别中, 比如判断一句评论是好评还是差评。单标签多分类文本被分入到多个类别中, 且每条文本只能属于某一个类别(即被打上某一个标签), 比如: 输入一个人名, 判断它是来自哪个国家的人名。多标签多分类文本被分人到多个类别中, 但每条文本可以属于多个类别(即被打上多个标签), 比如: 输入一段描述, 判断可能是和哪些兴趣爱好有关, 一段描述中可能即讨论了美食, 又讨论了游戏爱好。2. 文本分类实现第一步: 获取数据第二步: 训练集与验证集的划分第三步: 训练模型第四步: 使用模型进行预测并评估第五步: 模型调优第六步: 模型保存与重加载1. 原始数据处理数据要求每一条数据(评论、邮件等) __label__类别名 text文本(词或字之间用空格隔开)原因fasttext 设计是用来处理英文的所以中文使用时 词或字之间应用空格隔开示例# 字__label__game 体 验 2 D 巅 峰 倚 天 屠 龙 记 十 大 创 新 概 览# 词__label__game 体验 2D 巅峰 倚天 屠龙记 十大 创新 概览2. 对处理好的数据进行训练、预测、评估import fasttext # 模型训练 model fasttext.train_supervised(inputdata/cooking.pre.train, epoch30, losshs, wordNgrams2, autotuneValidationFiledata/cooking.pre.valid, autotuneDuration300, verbose3 # 设置日志输出的详细程度方便观察自动参数调优的进度 ) # 保存模型 model.save_model(r./model/model_cooking.bin) # 加载模型 model fasttext.load_model(r./model/model_cooking.bin) # 模型预测 print(model.predict(Are egg whites generally available at the store?)) # 模型评估 print(model.test(r./data/cooking.valid))输出# 预测结果((__label__egg-whites,), array([0.43338978]))# 元组中的每项分别代表, 验证集样本数量, 精度以及召回率(3000, 0.567, 0.24520686175580222)3. 模型调优例如上边代码可以更改、增加轮次epoch30losshs,增加ngram特征wordNgrams2一般为2或3调整学习率lr0.2自动参数调优① 指定验证数据集所在路径autotuneValidationFiledata/cooking.pre.valid,② 参数可以控制随机搜索的时间autotuneDuration300()