用最新NLP库Flair作文本分类

摘要: Flair是一个基于PyTorch构建的NLP开发包,它在解决命名实体识别(NER)、部分语音标注(PoS)、语义消歧和文本分类等NLP问题达到了当前的最高水准。它是一个创建在PyTorch之上的NLP框架。本文将介绍如何使用已有的和构建自定义的文本分类器。

介绍

文本分类是一种监督机器学习方法,用于将句子或文本文档归类为一个或多个已定义好的类别。它是一个被普遍应用的天然语言处理方法,在垃圾邮件过滤、情感分析、新闻稿件分类以及与许多其它业务相关的问题中发挥着重要做用。html

目前绝大多数最早进的方法都依赖于一种被称为文本嵌入的技术。它将文本转换成高维空间中的数值表示方式。它能够将文档、语句、单词、字符(取决于咱们所嵌入的形式)表示为这个高维空间中的一个向量。python

Flair之因此对NLP来讲是一个使人兴奋的消息,是由于Zalando Research最近发表的一篇论文《Contextual String Embeddings for Sequence Labelling(用于序列标注的上下文相关字符串的嵌入)》,其中涵盖了一种始终优于之前最早进方案的方法。该算法在Flair中获得了完整的支持和实现,能够用来构建文本分类器。git

一、准备

安装Flair须要Python 3.6,若是你尚未,请点击这里查看安装向导。而后执行pip命令安装便可:github

pip install flair

上面的命令将安装运行Flair所需的全部依赖包,固然也包括了PyTorch。算法

二、使用一个预训练的分类模型

最新的0.4版本包含了两个预训练的模型,还有一个基于IMDB数据集上训练的情感分析模型和“攻击性语言检测”模型(当前仅支持德语)。网络

使用、下载和存储模型都被整合到了一个单一的方法中,这使得使用预训练模型的整个过程都很是简单。框架

要使用情感分析模型,只需执行如下代码片断:机器学习

fromflair.models import TextClassifier
from flair.data import Sentence

classifier = TextClassifier.load('en-sentiment')

sentence = Sentence('Flair is pretty neat!')
classifier.predict(sentence)

# print sentence with predicted labels
print('Sentence above is: ', sentence.labels)

当第一次运行时,Flair将下载情感分析模型,默认状况下将其存储到home目录下的.flair子目录中,这大概得须要几分钟。函数

上面的代码首先加载必需的库,而后将情感分析模型加载到内存中(必要时先进行下载),接下来能够预测句子“Flair is pretty neat!”的情感数值,按0到1的区间赋值。最后命令的输出结果是:性能

The sentence above is: [Positive (1.0)]

就是这么简单!例如,如今你能够将上述代码合并在一个REST API中,并提供一个与Google的云天然语言API的情感分析相似的服务,当在有大量请求的生产环境中使用时,这种分析的成本将会很是的高。

三、训练一个自定义文本分类器

要训练一个自定义的文本分类器,咱们首先须要一个标注过的数据集。Flair的分类数据集格式基于Facebook的FastText格式。格式要求在每行的开头定义一个或多个标签,之前缀__label__开头。格式以下:

__label__<class_1><text>
__label__<class_2><text>

在本文中,咱们将利用Kaggle的Spam Detection数据集经过Flair构建一个垃圾/非垃圾的分类器。这个数据集比较适合咱们的学习任务,由于它足够小,而且仅包含5572行的数据,能够在一个CPU上只花几分钟就能够完成一个模型的训练。

来自数据集中的标记为spam(垃圾邮件)或ham(非垃圾邮件)的SMS信息

3.1 预处理-构建数据集

咱们首先从Kaggle上的这个连接下载数据集来得到spam.csv文件。而后,在与数据集相同的目录中,咱们运行下面的预处理代码片断,该代码将执行一些预处理,并将数据集拆分为训练集、开发集和测试集三个部分。

确保安装了Pandas。若是尚未,请先运行命令:

pip install pandas

import pandas as pd
data = pd.read_csv("./spam.csv", encoding='latin-1').sample(frac=1).drop_duplicates()

data = data[['v1', 'v2']].rename(columns={"v1":"label", "v2":"text"})

data['label'] = '__label__' + data['label'].astype(str)

data.iloc[0:int(len(data)*0.8)].to_csv('train.csv', sep='\t', index = False, header = False)
data.iloc[int(len(data)*0.8):int(len(data)*0.9)].to_csv('test.csv', sep='\t', index = False, header = False)
data.iloc[int(len(data)*0.9):].to_csv('dev.csv', sep='\t', index = False, header = False);

上面的代码将从数据集中删除一些重复数据,并对其进行无序处理(随机化行),并按照80/10/10的比例将数据拆分为训练集、开发集和测试集。

若是运行成功,你将会获得FastText格式的三个数据文件:train.csv、test.csv和dev.csv,它们能够与Flair一块儿使用。

3.2 训练自定义文本分类模型

请在生成数据集的目录中运行如下代码片断用以训练模型:

fromflair.data_fetcher import NLPTaskDataFetcher
from flair.embeddings import WordEmbeddings, FlairEmbeddings, DocumentLSTMEmbeddings
from flair.models import TextClassifier
from flair.trainers import ModelTrainer
from pathlib import Path

corpus = NLPTaskDataFetcher.load_classification_corpus(Path('./'), test_file='test.csv', dev_file='dev.csv', train_file='train.csv')

word_embeddings = [WordEmbeddings('glove'), FlairEmbeddings('news-forward-fast'), FlairEmbeddings('news-backward-fast')]

document_embeddings = DocumentLSTMEmbeddings(word_embeddings, hidden_size=512, reproject_words=True, reproject_words_dimension=256)

classifier = TextClassifier(document_embeddings, label_dictionary=corpus.make_label_dictionary(), multi_label=False)

trainer = ModelTrainer(classifier, corpus)

trainer.train('./', max_epochs=10)

第一次运行上述代码时,Flair将会自动下载须要的全部嵌入模型,这可能须要几分钟,而后接下来的整个培训过程还须要大约5分钟。

程序首先将所需的库和数据集加载到一个corpus对象中。

接下来,咱们建立一个嵌入列表,包含两个Flair上下文的字符串嵌入和一个GloVe单词嵌入。而后将此列表做为文档嵌入对象的输入。堆叠和文档嵌入是Flair中最有趣的概念之一,提供了将不一样的嵌入整合在一块儿的方法。你能够同时使用传统的单词嵌入(如GloVe, word2vec, ELMo)和Flair上下文的字符串嵌入。在上面的例子中,咱们使用了一种基于LSTM(Long Short-Term Memory,长短时间记忆网络)的方法,将单词和上下文的字符串嵌入结合起来以生成文档嵌入。想要了解更多,请点击这里

最后,上述代码进行模型训练并生成了final-model.pt和best-model.pt两个文件,它们表示咱们存储的训练模型。

3.3 用训练过的模型进行预测

咱们如今能够从同一目录经过运行如下代码,使用导出的模型来生成预测结果:

fromflair.models import TextClassifier
from flair.data import Sentence

classifier = TextClassifier.load_from_file('./best-model.pt')

sentence = Sentence('Hi. Yes mum, I will...')

classifier.predict(sentence)

print(sentence.labels)

这段代码会输出“[ham(1.0)]”,这意味着该模型100%肯定咱们的示例消息不是垃圾邮件。

与其它框架相比表现如何?

与Facebook的FastText甚至谷歌的AutoML天然语言平台不一样,使用Flair进行文本分类仍然是一项底层的工做。咱们能够经过设置诸如学习率、批量大小、退火因子(anneal factor)、损失函数、优化选择等参数来彻底控制文本嵌入和训练的方式…为了得到最佳表现,须要调整这些超参数。Flair为咱们提供了一个有名的超参数调优库Hyperopt的封装器,咱们可使用它来对超参数进行调优以得到最佳的性能。

在本文中,为了简单起见,咱们使用了默认的超参数。在大多数默认参数下,咱们的Flair模型在10个训练周期后得到了0.973的f1-score。

为了进行对比,咱们使用FastText和AutoML天然语言平台训练了一个文本分类模型。首先咱们使用默认参数运行FastText,并得到了0.883的f1-score,这意味着模型在很大程度上优于FastText。然而,FastText只须要几秒钟的训练时间,而咱们训练的Flair模型则须要5分钟。

咱们将结果与在谷歌的AutoML天然语言平台上得到的结果进行了比较。平台首先须要20分钟来解析数据集。以后,咱们开始了训练过程,这几乎花了3个小时完成,但却得到了99.211的f1-score——这比咱们本身训练的模型稍微好一点。



本文做者:【方向】

阅读原文

本文为云栖社区原创内容,未经容许不得转载。

相关文章
相关标签/搜索