FastText在文本分类上要优于TF-IDF,主要表现在:
FastText用单词的Embedding叠加获得的文档向量,将相似的句子分为一类;
FastText利用层序softmax快速的进行训练。
与word2vec不同的是,word2vec使用独立的单词作为基本单元来进行训练,它有两个主要问题:
低频词,罕见词,由于在语料库中出现的次数少,导致这类词得不到足够的训练,训练出的词向量效果不佳;
未登录词,如果出现词典中未出现的词,那么word2vec是无能为力的。
FastText引入subword n-gram的概念,解决词性变化的问题,它将一个单词打散到字符级别,并利用字符级别的n-gram信息来捕捉字符间的顺序关系,从而丰富单词内部更细微的语义,如单词的前缀、后缀以及字根的语义。在训练过程中,每个subword n-gram都会对应训练一个词向量,而完整单词的词向量就由它对应的所有的subword n-gram向量求和得到,从而可以解决未登录词的问题。
详细的内容参考论文 "Bag of Tricks for Efficient Text Classification"。https://arxiv.org/abs/1607.01759
FastText可以快速的在CPU上进行训练,最好的实践方法就是官方开源的版本:https://github.com/facebookresearch/fastText/tree/master/python
使用FastText可以方便的进行文本分类任务,首先需要安装FastText,安装方法为:
pip install fasttext
FastText训练模型时,需要指定待训练的文本文件,文件的label属性值格式如下: '__label__' + '类别',因此我们需要先使用训练文件生成指定的文件并保存到新的文件中。对于文本分类任务,需要使用train_supervised()方法,该方法需要指定几个重要的参数:
input # training file path (required)lr # learning rate [0.1]dim # size of word vectors [100]ws # size of the context window [5]epoch # number of epochs [5]minCount # minimal number of word occurences [1]minCountLabel # minimal number of label occurences [1]minn # min length of char ngram [0]maxn # max length of char ngram [0]neg # number of negatives sampled [5]wordNgrams # max length of word ngram [1]loss # loss function {ns, hs, softmax, ova} [softmax]bucket # number of buckets [2000000]thread # number of threads [number of cpus]lrUpdateRate # change the rate of updates for the learning rate [100]t # sampling threshold [0.0001]label # label prefix ['__label__']verbose # verbose [2]pretrainedVectors # pretrained word vectors (.vec file) for supervised learning []
详细的使用方法参考:
https://fasttext.cc/docs/en/supervised-tutorial.html
import pandas as pdfrom sklearn.metrics import f1_score
# 转换为FastText需要的格式train_df = pd.read_csv('../data/train_set.csv', sep='\t', nrows=15000)train_df['label_ft'] = '__label__' + train_df['label'].astype(str)train_df[['text','label_ft']].iloc[:-5000].to_csv('train.csv', index=None, header=None, sep='\t')
import fasttextmodel = fasttext.train_supervised('train.csv', lr=1.0, wordNgrams=2,verbose=2, minCount=1, epoch=25, loss="hs")
val_pred = [model.predict(x)[0][0].split('__')[-1] for x in train_df.iloc[-5000:]['text']]print(f1_score(train_df['label'].values[-5000:].astype(str), val_pred, average='macro'))# 0.82
关注公众号,回复"文本分类"获取数据集和代码。