FastText 总结:文本分类、词向量训练、参数详解

FastText:文本分类、词向量训练、参数详解

  • 前言 - FastText 简介
    • 一、FastText - 安装
      • 1.1 - Github下载安装
      • 1.2 - 编译器安装
    • 二、FastText - 文本分类任务
      • 2.1 - 什么是文本分类
      • 2.2 - 文本分类的种类
      • 2.3 - FastText文本分类的过程及代码实现
      • 2.4 - FastText训练词向量过程及代码实现
        • 2.4.1 - 了解词向量
        • 2.4.2 - FastText模型架构了解
        • 2.4.3 - 训练词向量模型
      • 2.5 - FastText参数详解
    • 三、总结


前言 - FastText 简介

FastText 总结:文本分类、词向量训练、参数详解_第1张图片

FastText是一种开源的快速文本分类和表示学习工具,一个高效的CPU上的分类模型,由Facebook的人工智能研究团队开发。可以用于对文本进行分类,例如将新闻文章分类为政治、科技、娱乐等不同的类别,也可以用于表示文本,即:将文本转换为数字向量,便于计算机处理。它使用了一种新的单词表示方法,可以让模型在大型语料库上训练的速度更快。它还支持使用 n-gram 特征来提升模型的效果,使得模型能够更好地处理未登录词。此外,fastText 还提供了一种高效的词向量学习方法,可以用于自然语言处理任务中的特征提取。FastText的优势在于它可以在较短的时间内训练出较高质量的模型,同时还支持在线学习。


一、FastText - 安装

1.1 - Github下载安装

1. git clone https://github.com/facebookresearch/fastText.git
2. cd fastText

# 使用pip安装python中的fasttext工具包
3. sudo pip install .


# 验证安装结果
Python 3.7.13 (default, Oct 18 2022, 18:57:03) 
[GCC 11.2.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import fasttext
>>> 

1.2 - 编译器安装

使用Pycharm编译器, 终端执行命令: pip install fasttext 如果有报错的话, 还需自行安装相关C++依赖项。

二、FastText - 文本分类任务

2.1 - 什么是文本分类

文本分类是自然语言处理中的一种任务,它的目的是将文本数据分配到一个或多个预定义的类别中。例如,对于一个新闻网站来说,文本分类可以用来将文章分配到不同的主题领域(如政治、体育、娱乐等)。又如,对于一个电子商务网站来说,文本分类可以用来将产品描述分配到不同的品类(如手机、电脑、家电等)。

文本分类通常使用机器学习技术来完成,包括训练分类器(如决策树、朴素贝叶斯分类器、支持向量机等)来预测新文本数据的类别。文本分类的输入通常是文本数据,输出是一个或多个类别的标签。

2.2 - 文本分类的种类

  1. 二分类
    通常这两个类别为对立面, 如: 情感分类中“正向情感”和“负向情感”。
  2. 单标签多分类
    文本被分入到多个类别中, 且每条文本只能属于某一个类别, 如: 手写体数字识别。
  3. 多标签多分类
    文本被分入到多个类别中, 且每条文本只能属于某一个类别, 如: 一篇文章内容描述所属类别既是科技又是军事。

2.3 - FastText文本分类的过程及代码实现

  1. 数据构建
    FastText独有的数据构建格式为: 数据每一行都包含一个 __label__ 标签列表,后跟相应的文档。文档可以按照词粒度构建, 也可以字粒度构建。数据格式如下:

    Text = "你的文本数据"
    Result = "__label__0\t" + ' '.join(Text)
    
    # 结果如下
    __label__1	面 积 不 大 的 水 塘 真 藏 货 , 阿 琪 抽 水 抗 旱 还 有 意 外 收 获 , 抓 鱼 抓 得 过 瘾
    __label__1	广 安 市 群 策 群 力 抗 旱
    __label__2	湖 北 省 《 开 发 性 金 融 支 持 县 域 垃 圾 污 水 处 理 设 施 建 设 实 施 细 则 》
    __label__2	旱 灾 究 竟 有 多 恐 怖 ? 很 多 人 都 不 理 解 为 何 路 边 的 树 都 没 了 皮
    __label__0	钱 铺 镇 多 措 并 举 抗 旱 情
    __label__2	夷 陵 消 防 获 赠 锦 旗 : 抗 旱 为 民 办 实 事 , 锦 旗 诠 释 “ 鱼 水 情 ”
    

    FastText独有的数据构建格式为: 数据每一行都包含一个标签列表,后跟相应的文档。例如

  2. 数据划分训练集与测试集

    from sklearn.model_selection import train_test_split
    
    trainData,testData = train_test_split(dataSets,test_size=0.3,random_state=66)
    
  3. 模型训练

    import fasttext
    # 使用fasttext的train_supervised方法进行有监督的文本分类模型训练
    model = fasttext.train_supervised(input="Datafilename.txt")
    # 保存模型至本地
    model.save_model("text2Class.bin")
    
  4. 测试集上评估模型好坏与模型单条数据预测

    modelPath = "text2Class.bin"
    testData = "testDataFileName.txt"
    model = fasttext.load_model(modelPath)
    testResult = model.test(testData)
    print("数据总量:",testResult[0])
    print("accuracy:",testResult[1])
    print("recall:",testResult[2])
    
    # 单条数据预测(注意预测样本的数据格式与fasttext训练数据格式一致,否则预测结果不准确)
    preText = " ".join("你的数据文本")
    preResult = model.predit(preText)
    
    # 元组中的第一项代表标签, 第二项代表对应的概率
    (('__label__0',), array([0.06550845]))
    
  5. 模型调优方法

    1. #可通过处理数据,噪声数据增加了模型提取分类规律的难度,可以对数据中的噪声进行剔除再训练。
    
    2. #增加训练epoch,保存模型后再进行测试集上评估与单条数据预测
       model = fasttext.train_supervised(input="Datafilename.txt", epoch=20)
    
    3. #调整学习率,默认的学习率为0.1,增大学习率意味着增大了梯度下降的步长使其在有限的迭代步骤下更接近最优点。
       model = fasttext.train_supervised(input="Datafilename.txt", epoch=20, lr=e-4)
    
    4. #增加n-gram特征,不设置默认ngram为1。
       #这里将其设置为2意味着添加2-gram特征, 这些特征帮助模型捕捉前后词汇之间的关联, 更好的提取分类规则用于模型分类, 当然这也会增加模型训时练占用的资源和时间。
       model = fasttext.train_supervised(input="Datafilename.txt", epoch=20, lr=e-4, wordNgrams=2)
    
    5. #修改损失计算方式,默认为softmax。这里将其设置为'hs', 代表层次softmax结构, 意味着输出层的结构(计算方式)发生了变化, 将以一种更低复杂度的方式来计算损失。
       model = fasttext.train_supervised(input="Datafilename.txt", epoch=20, lr=e-4, wordNgrams=2, loss='hs')
    
    6. #自动超参数调优
       #手动调节和寻找超参数是非常困难的, 因为参数之间可能相关, 并且不同数据集需要的超参数也不同。
       #因此可以使用fasttext的autotuneValidationFile参数进行自动超参数调优。
       #autotuneValidationFile参数需要指定验证数据集所在路径, 它将在验证集上使用随机搜索方法寻找可能最优的超参数。
       #使用autotuneDuration参数可以控制随机搜索的时间, 默认是300s, 根据不同的需求, 我们可以延长或缩短时间
       model = fasttext.train_supervised(input="Datafilename.txt", autotuneDuration=600)
    
  6. 实际生产中多标签多分类问题的损失计算方式
    针对多标签多分类问题, 使用'softmax'或者'hs'有时并不是最佳选择, 因为我们最终得到的应该是多个标签, 而softmax却只能最大化一个标签。所以我们往往会选择为每个标签使用独立的二分类器作为输出层结构,这种输出层的改变意味着我们在统一语料下同时训练多个二分类模型。对应的损失计算方式为'ova'表示one vs all。这种输出层的改变意味着我们在统一语料下同时训练多个二分类模型。如果多个二分类不够友好,可以参考苏神的这篇:将“softmax+交叉熵”推广到多标签分类问题自行修改损失函数计算方法。笔者亲测有效。

    model = fasttext.train_supervised(input="Datafilename.txt", epoch=20, lr=e-4, wordNgrams=2, loss='ova')
    
    # 我们使用模型进行单条样本的预测, 来看一下它的输出结果。
    # 参数k代表指定模型输出多少个标签, 默认为1, 这里设置为-1, 意味着尽可能多的输出。
    # 参数threshold代表显示的标签概率阈值, 设置为0.5, 意味着显示概率大于0.5的标签。
    model.predict("你的预测文本", k=-1, threshold=0.5)
     
    # 我看到根据输入文本, 输出了它的三个最有可能的标签
    (('__label__0', '__label__1', '__label__2'), array([1.00000, 0.939923, 0.592677]))
    

2.4 - FastText训练词向量过程及代码实现

2.4.1 - 了解词向量

词向量是将字、词语转换成向量矩阵的计算模型。最常用的词表示方法是 One-hot,这种方法把每个词表示为一个很长的向量。这个向量的维度是词表大小,其中绝大多数元素为 0,只有一个维度的值为 1,这个维度就代表了当前的词。还有 Google 团队的 Word2Vec等等。

2.4.2 - FastText模型架构了解

1. FastText的模型架构与Word2Vec中的CBOW语言模型很相似,不同之处是FastText预测标签而CBOW预测的是中间词,即模型架构类似,但是模型的任务不同。
2. FastText中的 N-Gram 是基于语言模型的算法,基本思想是将文本内容按照子节顺序进行大小为 N 的窗口滑动操作,最终形成窗口为 N 的字节片段序列, 其中 N 个词或字的相邻共现特征即N-Gram特征。而且需要额外注意一点是 N-Gram 可以根据粒度不同有不同的含义,有字粒度的 N-Gram 和词粒度的 N-Gram,下面分别给出了字粒度和词粒度的例子。

输入文本: 我来到阿里巴巴参观

相应的1-Gram特征为: 我 / 来 / 到 / 阿 / 里 / 巴 / 巴 / 参/ 观
相应的2-Gram特征为: 我来 / 来到 / 到阿 / 阿里 / 里巴 / 巴巴 / 巴参 / 参观
相应的3-Gram特征为: 我来到 / 来到阿 / 到阿里 / 阿里巴 / 里巴巴 / 巴巴参 / 巴参观

2.4.3 - 训练词向量模型

词向量模型的训练采用无监督的方式, 数据处理格式构建上参考 2.3 项第一条, 只是我们不再需要__label__格式的标签

def buildDataSets():
	# 数据构建
	text = " ".join("你的文本数据")
	with open("word2vecData-FastText.txt", "w", encoding="utf-8")as e:
		e.write(text + '\n')


def word2vecTrain():
	# 词向量模型训练
	filename = "word2vecData-FastText.txt"
	
	# 词嵌入维度dim: 默认为100, 但随着语料库的增大, 词嵌入的维度往往也要更大, 保存的模型文件也会越大
	# 无监督训练模式: 'skipgram' 或者 'cbow', 默认为'skipgram', 在实践中,skipgram模式在利用子词方面比cbow更好
	# 数据循环次数epoch: 默认为5, 如果你的数据集足够大, 可能不需要那么多次
	# 学习率lr: 默认为0.05, 根据经验, 建议选择[0.01,1]范围内
	model = fasttext.train_unsupervised(filename, 'skipgram', dim=150, epoch=10, thread=10, lr=0.1)
	
	model.save_model('fasttext-word2vector-Python.bin')


def getWord2Vec():
	
    modelPath = 'fasttext-word2vector-Python.bin'

	model = fasttext.load_model(modelPath )
	
	# 通过get_word_vector方法来获得指定词汇的词向量
    word = "兽药企业"
    word2Vector = model.get_word_vector(word)
    print(word2Vector)
	
		
	# 检查单词向量质量的一种简单方法就是查看其邻近单词, 通过我们主观来判断这些邻近单词是否与目标单词相关来粗略评定模型效果好坏
	neighborsWords = model.get_nearest_neighbors('兽药企业')
	print(neighborsWords )

2.5 - FastText参数详解

1. train_supervised 文本分类参数

		input: 		  训练数据文件路径
		lr:              学习率
		dim:             向量维度
		ws:              cbow模型时使用
		epoch:           批次数
		minCount:        词频阈值, 小于该值在初始化时会过滤掉
		minCountLabel:   类别阈值,类别小于该值初始化时会过滤掉
		minn:            构造subword时最小char个数
		maxn:            构造subword时最大char个数
		neg:             负采样
		wordNgrams:      n-gram个数
		loss:            损失函数类型, softmax, ns: 负采样, hs: 分层softmax
		bucket:          词扩充大小, [A, B]: A语料中包含的词向量, B不在语料中的词向量
		thread:          线程个数, 每个线程处理输入数据的一段, 0号线程负责loss输出
		lrUpdateRate:    学习率更新
		t:               负采样阈值
		label:           类别前缀
		verbose:         2
		pretrainedVectors: 预训练的词向量文件路径, 如果word出现在文件夹中初始化不再随机


2. train_unsupervised 词向量训练

		model: 模型类型,cbow/skipgram两种类型
        其他参数参考train_supervised()方法

3. 模型压缩 quantize

 		input:   训练数据文件路径
        qout:    是否修剪输出层
        cutoff:  重新训练的词和n-gram的个数
        retrain: 是否重新训练
        epoch:   次数
        lr:      学习率
        thread:  线程个数
        verbose: None
        dsub:    压缩方法将向量分成几块, 每块大小
        qnorm:   是否归一化(l2范数)

4. 模型存储 save_model

5. 模型单样本预测 predict

 		text:       字符串, 需要utf-8
        k:          返回标签的个数
        threshold   概率阈值, 大于该值才返回
        return 标签列表, 概率列表

6. 模型批量预测 test

		path: 测试数据路径
        k:    返回标签的个数
        return [样本个数, 准确率, 召回率]



三、总结

炼丹路漫漫 山高路远 看世界 找自己 -- LuoFan

你可能感兴趣的:(自然语言处理,分类,python)