文本分类-FastText
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文本分类-FastText相关的知识,希望对你有一定的参考价值。
参考技术A 一、预处理过程
①文本分字或分词
②构建字/词表
③每个文本的字/词表示为One_hotRepresentation词向量形式,每个文本表示为矩阵。
二、 模型介绍及核心思想
三、 模型架构
例如:
我 来到 达观数据 参观
相应的bigram特征为:我/来到 来到/达观数据 达观数据/参观
相应的trigram特征为:我/来到/达观数据 来到/达观数据/参观
例如:如[[4],[20]]->[[0.25,0.1],[0.6,-0.2]]。其中[4,20]表示“大家好”这个短文本,其中“大家”、“好”在词汇表中的索引分别是4、20。然后经过变换后就变成了[0.25,0.1]、[0.6,-0.2]。
③处理过程理解:
可以理解为先把词汇索引转为One_hot Representation词向量,然后再将One-Hot Encoder转化为Distributed Representation词向量形式(低维度的稠密向量),其中w为权值矩阵。
叠加构成这篇文档的所有词及n-gram的词向量,然后取平均。激活函数采用线性函数。
标准的Softmax回归中,要计算y=j时的Softmax概率:P(y=j),我们需要对所有的K个概率做归一化,这在|y|很大时非常耗时。而分层Softmax它的基本思想是使用树的层级结构替代扁平化的标准Softmax,使得在计算P(y=j) 时,只需计算一条路径上的所有节点的概率值,无需在意其它的节点。
下图是一个分层Softmax示例(假设有k个类别):
其中yj为P(y=j),树的结构是根据类标的频数构造的霍夫曼树。
于是,从根节点走到叶子节点 ,实际上是在做了3次二分类的逻辑回归。通过分层的Softmax,计算复杂度一下从|K|降低到log|K|。
4、模型优缺点
① fastText的分类效果常常不输于传统的非线性分类器
例如:
假设我们有两段文本:
文本一:我 来到 达观数据
文本二:俺 去了 达而观信息科技
这两段文本意思几乎一模一样,如果要分类,肯定要分到同一个类中去。但在传统的分类器中,用来表征这两段文本的向量可能差距非常大。传统的文本分类中,你需要计算出每个词的权重,比如tf-idf值, “我”和“俺” 算出的tf-idf值相差可能会比较大,于是,VSM(向量空间模型)中用来表征这两段文本的文本向量差别可能比较大。而fastText是用单词的embedding叠加获得的文档向量,词向量的重要特点就是向量的距离可以用来衡量单词间的语义相似程度,于是,在fastText模型中,这两段文本的向量应该是非常相似的,于是,它们很大概率会被分到同一个类中。
② 训练速度很快
fastText原理及实践
keras:Embedding层详解
word2vec 中的数学原理详解
史上最全词向量讲解(LSA/word2vec/Glove/FastText/ELMo/BERT)
自然语言处理 | FastText:快速的文本分类器
Datawhale-新闻文本分类-task4-基于深度学习的文本分类1-fastText
1. fasttext 参数含义
- input # training file path (required) 训练文件路径(必须)<br>
- lr # learning rate [0.1] 学习率 default 0.1<br>
- dim # size of word vectors [100] 词向量维度 default 100<br>
- ws # size of the context window [5] 上下文窗口大小 default 5<br>
- epoch # number of epochs [5] epochs 数量 default 5<br>
- minCount # minimal number of word occurences [1] 最低词频 default 5<br>
- minCountLabel # minimal number of label occurences [1] 最少出现标签的次数 default 1<br>
- minn # min length of char ngram [0] 最小字符长度 default 0<br>
- maxn # max length of char ngram [0] 最大字符长度 default 0<br>
- neg # number of negatives sampled [5] 负样本数量 default 5<br>
- wordNgrams # max length of word ngram [1] n-gram设置 default 1<br>
- loss # loss function {ns, hs, softmax, ova} [softmax] 损失函数 {ns,hs,softmax} default softmax<br>
- bucket # number of buckets [2000000] 桶数量 default 2000000<br>
- thread # number of threads [number of cpus] 线程数量<br>
- lrUpdateRate # change the rate of updates for the learning rate [100] 更改学习率的更新率<br>
- t # sampling threshold [0.0001] 采样阈值 default 0.0001<br>
- label # label prefix [‘__label__‘] 标签前缀 default __label__<br>
- verbose # verbose [2]<br>
- pretrainedVectors # pretrained word vectors (.vec file) for supervised learning [] 指定使用已有的词向量 .vec 文件 default None<br>
2. 本次fasttext的使用
不需要我们计算词向量后再训练。只需要将分好的词放入fasttext即可训练。
本次比赛,由于文本为匿名,无法分词,数据以单个字的编码形式出现。
因此无法认为分词,但是fasttext存在ngram参数,可通过调节该参数让fasttext帮我们分词同时还帮我们计算词向量。
因此训练时,直接将数据(csv格式)路径放入fasttext即可。
3. 参数优化1
让模型分得更好
使用默认参数运行 fastText 所获得的模型在分类新问题时非常糟糕。
可以尝试通过更改默认参数来提高性能。
- 1 预处理数据
- 剔除无用字符
- 2 增加迭代、学习速率调大
- 使用选项 -epoch, 标准范围 [5 - 50]
- 使用选项 -lr, 标准范围 [0.1 - 1.0]
- 3 增加词序的重要性:word n-grams
- 使用选项 -wordNgrams, 标准范围 [1 - 5]
4. 其他人参数优化经验
针对上述参数:
训练模式下涉及到的主要参数有
- 学习率(-lr)
- 隐层的维数(-dim)
- 最小词频(-minCount)
- 负采样个数(-neg)和n-grams的长度(-wordNgrams)等。
- word_ngrams 大于1时,模型的精度会提交很多,但是模型的大小也是很大不少,不建议设置太大,因为训练的复杂度和模型的大小会指数级增长
- 需要注意的是修改了 word_ngrams,需要相应的调整bucket,bucket设置的小一点,否则预留会预留太多bucket使模型太大
- lr 设置过大不容易收敛,太小容易过拟合,训练速度也会变慢
- loss 损失函数选用hs(hierarchical softmax)要比ns(negative sampling) 训练速度要快很多倍,并且准确率也更高
5. 总结其他人使用fasttext经验
fasttext不需要我们计算词向量后再训练。只需要将分好的词放入fasttext即可训练
- 剔除无用字符
- 使用选项 -epoch, 标准范围 [5 - 50]
- 使用选项 -lr, 标准范围 [0.1 - 1.0], 注意:lr 设置过大不容易收敛,太小容易过拟合,训练速度也会变慢
- 使用选项 -wordNgrams, 标准范围 [1 - 5], 注意:修改了 word_ngrams,需要相应的调整bucket,bucket设置的小一点,否则预留会预留太多bucket使模型太大
- 隐层的维数(-dim)
- 最小词频(-minCount)
- 损失函数选用hs(hierarchical softmax), 注意:hs(hierarchical softmax)要比ns(negative sampling) 训练速度要快很多倍,并且准确率也更高
6. 使用fasttext文本分类
- 代码
def no_n_kfold_fasttext(train,test):
# train转换为符合fasttext输入格式
train[‘label_ft‘] = ‘__label__‘ + train[‘label‘].astype(‘str‘)
# 全量train生成文件fasttext_train.csv
train[[‘text‘, ‘label_ft‘]].to_csv(‘fasttext_train.csv‘, index=False, header=None, sep=‘ ‘)
import fasttext
# lr=0.5, wordNgrams=2, epoch=25
model = fasttext.train_supervised(‘fasttext_train.csv‘, lr=0.75, wordNgrams=3,
verbose=2, minCount=1, epoch=25, loss=‘hs‘)
# 预测test_a数据
test_pre = [model.predict(x)[0][0].split(‘__‘)[-1] for x in test_a[‘text‘]]
#返回预测test_a的结果list
return test_pre
import pandas as pd
train = pd.read_csv(r‘./train_set.csv‘, sep=‘ ‘)
test_a = pd.read_csv(r‘./test_a.csv‘, sep=‘ ‘)
# 导出结果,提交
test_pre = no_n_kfold_fasttext(train,test_a)
pd.Series(test_pre, name=‘label‘).to_csv(‘result_1.csv‘, index=False)
预测分数:
7. 十折交叉验证的fasttext
暂时还没想到实现fasttext的十折交叉验证方法。 应该是对fasttext还不熟悉。 后面会做了再补上
以上是关于文本分类-FastText的主要内容,如果未能解决你的问题,请参考以下文章