1:简介
FastText是Facebook开发的一款快速文本分类器,提供简单而高效的文本分类和表征学习的方法。
本文素材来源于https://pypi.org/project/fasttext/,增加一些个人理解。
2:安装要求
只可以安装在Mac OS和Linux系统上,依赖于C++11编译器,同时需要python版本2.7或者3.4及以上,以及numpy&scipy&pybind11。
pip install fasttext即可,https://fasttext.cc/docs/en/support.html中所述安装方法在106机器上会有c编译的错误
3: Word representation
NLP中一个很流行的方法是词向量化,这些词语经过向量化,可以高效的捕捉每个词语的相似词及其语义信息,这也有助于提高文本分类的准确性。
教程给的俩个数据集https://dumps.wikimedia.org/enwiki/latest/enwiki-latest-pages-articles.xml.bz2、http://mattmahoney.net/dc/enwik9.zip,第一个12G,过大,
enwik9.zip 954M,
import fasttext # 使用默认的参数训练词向量 model = fasttext.train_unsupervised('data/fil9') # 降序返回语料库中的所有单词 model.words # 获取某一个单词的词向量 model.get_word_vector("the") # 保存模型 model.save_model("result/fil9.bin") # reload模型 model = fasttext.load_model("result/fil9.bin")
3.1: 模型 skipgram VS cbow(continuous-bag-of-words)
skipgram模型输入是目标词的词向量,而输出是目标词的上下文词向量,而cbow利用目标词汇的上下文进行预测目标侧,上下文是指“目标词汇左右若干个词,不包含目标词汇”
# 使用cbow模型 model = fasttext.train_unsupervised('data/fil9', "cbow") # 控制词向量维度的参数dim(默认100),控制subword长度范围的参数minn,maxn(默认3,6) model = fasttext.train_unsupervised('data/fil9', minn=2, maxn=5, dim=300) # 模型在数据集中遍历的次数epoch(默认5),学习率lr(默认0.05),线程数量threads(默认12) model = fasttext.train_unsupervised('data/fil9', epoch=1, lr=0.5,threads=4)
利用上文文生成词向量,可以带来的一个好处是,即使某个词没有出现在语料库里,但是只要该词的片段曾经出现过,模型依旧可以给出其向量化的表示,
另外,还可以查询某个词的最近邻向量(通过俩个词之前的向量夹角的余弦来判断):
# 获取某个未在语料库中出现过的单词(拼错的单词)的词向量 model.get_word_vector("enviroment") # 默认查询输入词的10个最近邻向量 model.get_nearest_neighbors('asparagus') # 用类推的方法寻找同义词:berlin之于germany,则france之于"巴黎" model.get_analogies("berlin", "germany", "france") # 如果不利用上下文生成词向量,则上述方法会失效,返回一些无关的词 model_without_subwords = fasttext.train_unsupervised('data/fil9', maxn=0)
4:Text classification
文本分类工作,在垃圾邮件检测,情感分析和智能回复中都是一项重要的技术。其目标是为一段文本分配一个或者多个类别,这些类别可能是对一段文本的评分,也可能是指该文本的语言类别。如今,主流的文本分类器运用了机器学习的算法,利用有标签的数据来构建这样的一个分类器。
经常使用的一个方法是train_supervised,返回的模型可以利用test和predict方法。
这里的示例使用的数据是一个烹饪问答网站中有关于烹饪的语料。
每一行文件都由标签和对应的语句组成,每个标签的前缀都是“__label__”,这是fastText约定俗称的区分标签和语句的符号。
该语料库共有15404条数据,将前12404条数据划分为训练数据集cooking.train,后3000条数据为验证数据集cooking.valid。
# 使用默认参数进行监督学习,epoch=5 model = fasttext.train_supervised(input="cooking.train") # 使用模型对语句的标签进行预测 model.predict("Which baking dish is best to bake a banana bread ?") # 在验证集上的表现,输出三个参数:验证集的数据量,以及在验证集上的精确率和召回率 model.test("cooking.valid") # 在验证集上的top-5精确率和召回率 model.test("cooking.valid", k=5)
4.1 文本预处理
教程中只是简单的将文本统统换为小写: tr "[:upper:]" "[:lower:]"
4.2 超参调整
# 调整epoch,学习率lr,wordNgrams model = fasttext.train_supervised(input="cooking.train", epoch=25,lr=1.0) # word n-grams model = fasttext.train_supervised(input="cooking.train", lr=1.0, epoch=25, wordNgrams=2)
4.3 损失函数
https://www.cnblogs.com/xiaoxiaomajinjiebiji/p/14077212.html
5:参数自动调优
# 在实现模型参数的自动调优的时候,需要提供autotuneValidationFile参数指定模型的验证集,最终模型会返回在验证集上F1 score值最高的参数,默认情况下,在验证集上的搜索耗时5min,如果想要进行调整,可以通过autotuneDuration参数,单位为秒,如果在训练过程中想提早停止,可以直接ctrl-c结束当前训练,使用目前找到的最佳参数再训练. model = fasttext.train_supervised(input='cooking.train', autotuneValidationFile='cooking.valid', autotuneDuration=600) # autotuneModelSize参数限制模型大小,fastText可以实现模型的压缩和量化,同时也有相应的参数来调整所保存的模型精度和大小,而该参数可以实现这些参数的自动调优 model = fasttext.train_supervised(input='cooking.train', autotuneValidationFile='cooking.valid', autotuneModelSize="2M") # 输出模型大小 os.stat("model_cooking.ftz").st_size # 相比较autotuneValidationFile,fastText也可以实现在特定标签上模型的优化,此时利用的参数为:autotuneMetric,还可以同时在多个标签上实现对模型的调优,此时利用的参数为:autotunePredictions model = fasttext.train_supervised(input='cooking.train', autotuneValidationFile='cooking.valid', autotuneMetric="f1:__label__baking")
6:一些坑
a:数据预处理
标签以"__label__"开头,中文需要先进行分词,分词后,每个词之间用空格分隔,每一行以\n结尾,标签和语句之间可以用空格分隔,也可以用“\t”或者“,”等分隔,因为,“\t”等同于4个空格,用“,”分隔,则语料库中会多一个“,”,从实验结果来看,并没有很大的影响,猜测是因为每条语料都加的话,基本可以消除影响。训练数据必须是utf-8编码。
model.get_line(text)函数可以获取一条文本的标签和语句,可以加以验证。
b:多标签分类
多标签分类损失函数:各个类别的交叉熵之和
https://github.com/facebookresearch/fastText/commit/8850c51b972ed68642a15c17fbcd4dd58766291d
c:精确率和召回率的计算方式
model.test_label(valid_data_fpath,k=1)可以返回1个结果的时候,各个类别的精确率和召回率以及f1score
model.test(valid_data_fpath,k=1)可以返回1个结果的时候,整个验证数据集上的精确率和召回率以及f1score
详细:类别a在语料中出现的次数即为TP+FN,FP是指预测错误的数据量(在整个验证集上遍历预测结果,预测结果为a,但标签不是a的总量),TP是指预测正确的数据量,由此可以计算类别a的精确率和召回率以及f1score
而整个数据集的计算方式采取的是micro的方式,详情见:https://zhuanlan.zhihu.com/p/59862986