fastText是由Facebook Research团队于2016年开源的一个词向量计算和文本分类工具。尽管在学术上并未带来巨大创新,但其在实际应用中的表现却非常出色,特别是在文本分类任务中,fastText往往能以浅层网络结构取得与深度网络相媲美的精度,同时在训练时间上远快于深度网络。
fasttext工具包
作为NLP工程领域常用的工具包, fasttext有两大作用💥
- 进行文本分类
- 训练词向量
fasttext工具包的优势
快速的进行训练和预测是fasttext的最大优势,fasttext工具包中内含的fasttext模型具有十分简单的网络结构,使用fasttext模型训练词向量时使用层次softmax结构, 来提升超多类别下的模型性能,由于fasttext模型过于简单无法捕捉词序特征, 因此会进行n-gram特征提取以弥补模型缺陷提升精度。
fasttext的安装
pip install fasttext
💯验证:
import fasttext
- 如果执行上述命令后没有报错,且Python解释器没有提示“ModuleNotFoundError: No module named 'fasttext'”等错误信息,则说明fasttext已经成功安装。
fasttext文本分类
文本分类的是将文档分配给一个或多个类别,当今文本分类的实现多是使用机器学习方法从训练数据中提取分类规则以进行分类, 因此构建文本分类器需要带标签的数据。
文本分类种类 :
- 二分类:
- 文本被分类两个类别中, 往往这两个类别是对立面, 比如: 判断一句评论是好评还是差评.
- 单标签多分类:
- 文本被分入到多个类别中, 且每条文本只能属于某一个类别(即被打上某一个标签)
- 多标签多分类:
- 文本被分人到多个类别中, 但每条文本可以属于多个类别(即被打上多个标签)
fastText 库常用方法 :
训练词向量模型
使用fastText可以训练词向量模型,这些词向量能够捕捉单词之间的语义关系。训练词向量的基本命令格式如下:
./fasttext skipgram -input input.txt -output model
这里,-input
参数指定输入文件,-output
参数指定输出模型文件的名称。skipgram
是训练词向量时使用的算法,类似于word2vec中的skip-gram算法。
2. 训练文本分类模型
fastText的主要用途之一是文本分类。它支持监督学习模式下的文本分类,训练命令的基本格式如下:
./fasttext supervised -input train.txt -output model
或者,在Python中,可以使用train_supervised
方法:
import fasttext
model = fasttext.train_supervised('train.csv', lr=1.0, wordNgrams=2, epoch=25, ...)
其中,train.txt
或train.csv
是包含训练数据的文件,每行文本前通常带有标签(例如__label__类别
)。lr
是学习率,wordNgrams
是n-gram的最大长度,epoch
是训练的轮数等。这些参数可以根据具体任务进行调整以优化模型性能。
3. 模型预测
训练完成后,可以使用fastText模型对新的文本数据进行分类预测。在命令行中,可以使用predict
命令:
在Python中,可以使用predict
方法:
predictions = model.predict(x) # x是待预测的文本
4. 模型评估
为了评估模型的性能,可以使用测试集数据,并计算准确率、召回率等指标。在Python中,虽然fastText库本身不直接提供评估函数,但你可以自己编写代码来计算这些指标,或者将预测结果与测试集的标签进行比较。
5. 模型保存与加载
训练好的模型可以保存为二进制文件,以便将来使用。在Python中,可以使用save_model
方法保存模型:
model.save_model("model_cooking.bin")
加载模型时,使用load_model
函数:
model = fasttext.load_model("model_cooking.bin")
文本分类实现
数据集介绍,本案例烹饪相关的数据集, 它是由facebook AI实验室提供的演示数据集
# 查看数据的前10条
$ head cooking.stackexchange.txt
#
__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
__label__baking __label__oven __label__convection Fan bake vs bake
__label__sauce __label__storage-lifetime __label__acidity __label__mayonnaise Regulation and balancing of readymade packed mayonnaise and other sauces
- fasttext工具支持多种格式的输入数据,包括这种以
__label__
前缀标记类别的格式。在这种格式中,每个样本的类别被前缀__label__
所标记,后跟实际的类别名称,然后是文本内容。这种格式使得fasttext能够轻松地识别每个样本的类别和对应的文本,从而进行文本分类任务。
训练集与验证集的划分
# 查看数据总数
$ wc cooking.stackexchange.txt
15404 169582 1401900 cooking.stackexchange.txt
# 12404条数据作为训练数据
$ head -n 12404 cooking.stackexchange.txt > cooking.train
# 3000条数据作为验证数据
$ tail -n 3000 cooking.stackexchange.txt > cooking.valid
- 使用
head
命令来获取cooking.stackexchange.txt
文件的前12404行,并将这部分内容重定向(>
)到cooking.train
文件中,作为训练数据。
训练模型
# 导入fasttext
import fasttext
# 使用train_supervised方法进行文本分类模型的训练
model = fasttext.train_supervised(input="cooking/cooking.train")
- 其中
input
参数是一个字符串,指定了训练数据文件的路径。
使用模型进行预测并评估
model.predict("Which baking dish is best to bake a banana bread ?")、
# 元组中的第一项代表标签, 第二项代表对应的概率
(('__label__baking',), array([0.06550845]))
通过我们常识可知预测是错误的
model.predict("Why not put knives in the dishwasher?")
(('__label__food-safety',), array([0.07541209]))
模型调优
通过查看数据, 我们发现数据中存在许多标点符号与单词相连以及大小写不统一,这些因素对我们最终的分类目标没有益处, 反是增加了模型提取分类规律的难度,因此我们选择将它们去除或转化。
# 处理前的部分数据
__label__fish Arctic char available in North-America
__label__pasta __label__salt __label__boiling When cooking pasta in salted water how much of the salt is absorbed?
__label__coffee Emergency Coffee via Chocolate Covered Coffee Beans?
__label__cake Non-beet alternatives to standard red food dye
__label__cheese __label__lentils Could cheese "halt" the tenderness of cooking lentils?
__label__asian-cuisine __label__chili-peppers __label__kimchi __label__korean-cuisine What kind of peppers are used in Gochugaru ()?
__label__consistency Pavlova Roll failure
__label__eggs __label__bread What qualities should I be looking for when making the best French Toast?
__label__meat __label__flour __label__stews __label__braising Coating meat in flour before browning, bad idea?
__label__food-safety Raw roast beef on the edge of safe?
__label__pork __label__food-identification How do I determine the cut of a pork steak prior to purchasing it?
cat cooking.stackexchange.txt | sed -e "s/\([.\!?,'/()]\)/ \1 /g" | tr "[:upper:]" "[:lower:]" > cooking.preprocessed.txt
处理后的部分数据:
__label__fish arctic char available in north-america
__label__pasta __label__salt __label__boiling when cooking pasta in salted water how much of the salt is absorbed ?
__label__coffee emergency coffee via chocolate covered coffee beans ?
__label__cake non-beet alternatives to standard red food dye
__label__cheese __label__lentils could cheese "halt" the tenderness of cooking lentils ?
__label__asian-cuisine __label__chili-peppers __label__kimchi __label__korean-cuisine what kind of peppers are used in gochugaru ( ) ?
__label__consistency pavlova roll failure
__label__eggs __label__bread what qualities should i be looking for when making the best french toast ?
__label__meat __label__flour __label__stews __label__braising coating meat in flour before browning , bad idea ?
__label__food-safety raw roast beef on the edge of safe ?
__label__pork __label__food-identification how do i determine the cut of a pork steak prior to purchasing it ?
然后重新训练,再增加训练轮数,增加n-gram特征...
模型保存与重加载
model.save_model("model/model_cooking.bin")