更多实时更新的个人学习笔记分享,请关注:
知乎:https://www.zhihu.com/people/yuquanle/columns
微信订阅号:AI小白入门
ID: StudyForAI
Flair工具使用教程之如何加载自己的语料库
- 本教程的展示了如何加载自己的语料库,以便训练自己的模型。
- 教程地址:https://github.com/zalandoresearch/flair/blob/master/resources/docs/TUTORIAL_6_CORPUS.md
读取序列标记数据集
NLP中的大多数序列标记数据集使用某种列格式,其中每一行都是一个单词,每列都是一级语言标注。 比如说这句话:
George N B-PER
Washington N I-PER
went V O
to P O
Washington N B-LOC
- 第一列是单词本身;
- 第二列是词性(POS)标签;
- 第三列是用BIO注释的命名实体(NER)标签,B表示实体的开始,O表示其他;
要读取此类数据集,需要将列结构定义为字典并使用辅助方法。
from flair.data import TaggedCorpus
from flair.data_fetcher import NLPTaskDataFetcher
# define columns
columns = {0: 'text', 1: 'pos', 2: 'np'}
# this is the folder in which train, test and dev files reside
data_folder = '/path/to/data/folder'
# retrieve corpus using column format, data folder and the names of the train, dev and test files
corpus: TaggedCorpus = NLPTaskDataFetcher.load_column_corpus(data_folder, columns,
train_file='train.txt',
test_file='test.txt',
dev_file='dev.txt')
这将为您提供TaggedCorpus对象,其中包含train,dev和test 集,每个对象都有一个Sentence列表。 因此,要检查训练分组中有多少句子,请执行:
len(corpus.train)
您还可以访问句子并查看注释。 让我们假设训练集中的第一个句子是上面的例句,然后使用下面代码:
print(corpus.train[0].to_tagged_string('pos'))
print(corpus.train[0].to_tagged_string('ner'))
输出具有不同注释层的句子:
George <N> Washington <N> went <V> to <P> Washington <N>
George <B-PER> Washington <I-PER> went to Washington <B-LOC> .
读取文本分类数据集
Flair使用的文本分类数据格式基于FastText格式,其中文件中的每一行代表一个文本文档。 一个文档可以有一个或多个标签,这些标签在以#_label__前缀开头的行的开头定义。 这看起来像这样:
__label__<label_1> <text>
__label__<label_1> __label__<label_2> <text>
要为文本分类任务创建TaggedCorpus,您需要以上述格式将三个文件(train,dev和test)放在一个文件夹中。 例如,对于IMDB任务,此数据文件夹结构可能如下所示:
/resources/tasks/imdb/train.txt
/resources/tasks/imdb/dev.txt
/resources/tasks/imdb/test.txt
如果您现在将NLPTaskDataFetcher指向此文件夹(/ resources / tasks / imdb),它将从三个不同的文件中创建TaggedCorpus。 因此,文件中的每一行都被转换为用标签注释的Sentence对象。代码如下:
from flair.data_fetcher import NLPTaskDataFetcher
from pathlib import Path
# use your own data path
data_folder = Path('/resources/tasks/imdb')
# load corpus containing training, test and dev data
corpus: TaggedCorpus = NLPTaskDataFetcher.load_classification_corpus(data_folder,
test_file='test.txt',
dev_file='dev.txt',
train_file='train.txt')
注意:一行中的文本可以有多个句子。 因此,Sentence对象实际上可以包含多个句子。
如果您只想读取单个文件,可以使用NLPTaskDataFetcher.read_text_classification_file('path / to / file.txt),它返回Sentence对象的列表。
下载数据集
Flair还支持开箱即用的几个数据集。 例如,您可以通过调用加载这些数据集:
corpus = NLPTaskDataFetcher.load_corpus(NLPTask.UD_ENGLISH)
这行代码将下载UD_ENGLISH数据集并将其放入〜/ .flair / datasets / ud_english。 该方法返回TaggedCorpus,可直接用于训练您的模型。
目前Flair支持以下数据集:
TaggedCorpus对象
TaggedCorpus代表您的整个数据集。 TaggedCorpus由测试集句子列表,开发集句子列表和测试集句子列表组成。
TaggedCorpus包含许多有用的辅助函数。 例如,您可以通过调用downsample()并传递比率来对数据进行下采样。 所以,如果你通常得到这样的语料库:
original_corpus = NLPTaskDataFetcher.load_corpus(NLPTask.UD_ENGLISH)
然后你可以对语料库进行下采样,就像这样:
downsampled_corpus = NLPTaskDataFetcher.load_corpus(NLPTask.UD_ENGLISH).downsample(0.1)
如果您打印两个语料库,您会看到第二个语料库已被下采样到10%的数据。
print("--- 1 Original ---")
print(original_corpus)
print("--- 2 Downsampled ---")
print(downsampled_corpus)
输出:
--- 1 Original ---
TaggedCorpus: 12543 train + 2002 dev + 2077 test sentences
--- 2 Downsampled ---
TaggedCorpus: 1255 train + 201 dev + 208 test sentences
对于许多学习任务,您需要创建目标字典。 因此,TaggedCorpus使您可以创建标签或标签字典,具体取决于您要学习的任务。例如:
# create tag dictionary for a PoS task
corpus = NLPTaskDataFetcher.load_corpus(NLPTask.UD_ENGLISH)
print(corpus.make_tag_dictionary('upos'))
# create tag dictionary for an NER task
corpus = NLPTaskDataFetcher.load_corpus(NLPTask.CONLL_03_DUTCH)
print(corpus.make_tag_dictionary('ner'))
# create label dictionary for a text classification task
corpus = NLPTaskDataFetcher.load_corpus(NLPTask.IMDB, base_path='path/to/data/folder')
print(corpus.make_label_dictionary())
另一个有用的函数是obtain_statistics(),它返回一个python字典,其中包含有关数据集的有用统计信息。 例如,在像这样的IMDB数据集上使用它:
from flair.data_fetcher import NLPTaskDataFetcher, NLPTask
corpus = NLPTaskDataFetcher.load_corpus(NLPTask.IMDB, base_path='path/to/data/folder')
stats = corpus.obtain_statistics()
print(stats)
输出:
{
'TRAIN': {
'dataset': 'TRAIN',
'total_number_of_documents': 25000,
'number_of_documents_per_class': {'POSITIVE': 12500, 'NEGATIVE': 12500},
'number_of_tokens': {'total': 6868314, 'min': 10, 'max': 2786, 'avg': 274.73256}
},
'TEST': {
'dataset': 'TEST',
'total_number_of_documents': 12500,
'number_of_documents_per_class': {'NEGATIVE': 6245, 'POSITIVE': 6255},
'number_of_tokens': {'total': 3379510, 'min': 8, 'max': 2768, 'avg': 270.3608}
}, 'DEV': {
'dataset': 'DEV',
'total_number_of_documents': 12500,
'number_of_documents_per_class': {'POSITIVE': 6245, 'NEGATIVE': 6255},
'number_of_tokens': {'total': 3334898, 'min': 7, 'max': 2574, 'avg': 266.79184}
}
}
MultiCorpus对象
如果需要一次训练多个任务,可以使用MultiCorpus对象。 要启动MultiCorpus,首先需要创建任意数量的TaggedCorpus对象。 之后,您可以将TaggedCorpus列表传递给MultiCorpus对象。
english_corpus = NLPTaskDataFetcher.load_corpus(NLPTask.UD_ENGLISH)
german_corpus = NLPTaskDataFetcher.load_corpus(NLPTask.UD_GERMAN)
dutch_corpus = NLPTaskDataFetcher.load_corpus(NLPTask.UD_DUTCH)
multi_corpus = MultiCorpus([english_corpus, german_corpus, dutch_corpus])
MultiCorpus对象具有与TaggedCorpus相同的接口。 您可以简单地将MultiCorpus传递给训练函数而不是TaggedCorpus,训练函数不会知道差异,训练将照常运作。