自然语言推理和数据集

自然语言推理和数据集

Natural Language Inference and the Dataset

情绪分析的问题。此任务旨在将单个文本序列分类为预定义的类别,例如一组情感极性。然而,当需要判断一个句子是否可以从另一个句子中推断出来,或者通过识别语义上等价的句子来消除冗余时,知道如何对一个文本序列进行分类是不够的。相反,需要能够对文本序列进行推理。

  1. Natural Language Inference

自然语言推理研究一个假设是否可以从一个前提中推断出来,前提和前提都是文本序列。换句话说,自然语言推理决定了一对文本序列之间的逻辑关系。这种关系通常分为三类:
蕴涵:假设可以从前提中推断出来。

矛盾:假设的否定可以从前提推断出来。

中立:所有其情况。

自然语言推理也被称为识别文本蕴涵任务。例如,下面的一对会被标记为蕴涵,因为假设中的“示爱”可以从前提中的“拥抱”中推断出来。

前提:两个女人互相拥抱。

假设:两个女人在表达爱意。

下面是一个矛盾的例子,因为“运行编码示例”表示“不睡觉”而不是“睡眠”。

前提:一个男人正在运行一个代码示例,该示例来自于深度学习。

假设:这个人正在睡觉。

第三个例子显示了一种中立关系,因为“为演出”的事实不能推断出“著名”和“不出名”。

前提:音乐家在为表演。

假设:音乐家是有名的。

自然语言推理一直是理解自然语言的中心话题。在信息检索、开放领域问答等领域有着广泛的应用。为了研究这个问题,将从研究一个流行的自然语言推理基准数据集开始。

  1. The Stanford Natural Language Inference (SNLI) Dataset

斯坦福自然语言推理(SNLI)语料库是一个50万标记英语句子对【Bowman等人,2015年】。将提取的SNLI数据集下载并存储在路径…/data/SNLI_1.0中。

import collections

from d2l import mxnet as d2l

from mxnet import gluon, np, npx

import os

import re

import zipfile

npx.set_np()

#@save

d2l.DATA_HUB[‘SNLI’] = (

'https://nlp.stanford.edu/projects/snli/snli_1.0.zip',

'9fcde07509c7e87ec61c640c1b2753d9041758e4')

data_dir = d2l.download_extract(‘SNLI’)

Downloading …/data/snli_1.0.zip from https://nlp.stanford.edu/projects/snli/snli_1.0.zip…

2.1. Reading the Dataset

原始的SNLI数据集包含了比在实验中真正需要的更丰富的信息。因此,定义了一个函数read_snli来只提取部分数据集,然后返回前提、假设及其标签的列表。

#@save

def read_snli(data_dir, is_train):

"""Read the SNLI dataset into premises, hypotheses, and

labels."""

def extract_text(s):

    # Remove information that will not be used by us

    s = re.sub('\\(', '', s)

    s = re.sub('\\)', '', s)

    # Substitute two or more consecutive whitespace with space

    s = re.sub('\\s{2,}', ' ', s)

    return s.strip()

label_set = {'entailment': 0, 'contradiction': 1, 'neutral': 2}

file_name = os.path.join(data_dir, 'snli_1.0_train.txt'

                         if is_train else 'snli_1.0_test.txt')

with open(file_name, 'r') as f:

    rows = [row.split('\t') for row in f.readlines()[1:]]

premises = [extract_text(row[1]) for row in rows if row[0] in label_set]

hypotheses = [extract_text(row[2]) for row in rows if row[0] in label_set]

labels = [label_set[row[0]] for row in rows if row[0] in label_set]

return premises, hypotheses, labels

现在让打印第一个3对前提和假设,以及标签(“0”、“1”和“2”分别对应于“蕴涵”、“矛盾”和“中性”)。

train_data = read_snli(data_dir, is_train=True)

for x0, x1, y in zip(train_data[0][:3], train_data[1][:3], train_data[2][:3]):

print('premise:', x0)

print('hypothesis:', x1)

print(‘label:’, y)

premise: A person on a horse jumps over a broken down airplane .

hypothesis: A person is training his horse for a competition .

label: 2

premise: A person on a horse jumps over a broken down airplane .

hypothesis: A person is at a diner , ordering an omelette .

label: 1

premise: A person on a horse jumps over a broken down airplane .

hypothesis: A person is outdoors , on a horse .

label: 0

test_data = read_snli(data_dir, is_train=False)

for data in [train_data, test_data]:

print([[row for row in data[2]].count(i) for i in range(3)])

训练集有大约55万组,测试集有大约10000组。结果表明,在训练集和测试集中,“蕴涵”、“矛盾”和“中性”三个标签是平衡的。

test_data = read_snli(data_dir, is_train=False)

for data in [train_data, test_data]:

print([[row for row in data[2]].count(i) for i in range(3)])

[183416, 183187, 182764]

[3368, 3237, 3219]

2.2. Defining a Class for Loading the Dataset

下面定义了一个类,通过继承Gluon中的dataset类来加载SNLI数据集。类构造函数中的num_steps参数指定文本序列的长度,以便每个序列的小批量都具有相同的形状。换言之,第一个num_steps后面的标记将被修剪,而特殊标记“”将被附加到较短的序列中,直到长度变为num_steps。通过实现the getitem function函数,可以任意访问前提、假设和索引idx的标签。

#@save

class SNLIDataset(gluon.data.Dataset):

"""A customized dataset to load the SNLI dataset."""

def __init__(self, dataset, num_steps, vocab=None):

    self.num_steps = num_steps

    all_premise_tokens = d2l.tokenize(dataset[0])

    all_hypothesis_tokens = d2l.tokenize(dataset[1])

    if vocab is None:

        self.vocab = d2l.Vocab(all_premise_tokens + all_hypothesis_tokens,

                               min_freq=5, reserved_tokens=['<pad>'])

    else:

        self.vocab = vocab

    self.premises = self._pad(all_premise_tokens)

    self.hypotheses = self._pad(all_hypothesis_tokens)

    self.labels = np.array(dataset[2])

    print('read ' + str(len(self.premises)) + ' examples')



def _pad(self, lines):

    return np.array([d2l.truncate_pad(

        self.vocab[line], self.num_steps, self.vocab['<pad>'])

                     for line in lines])

def __getitem__(self, idx):

    return (self.premises[idx], self.hypotheses[idx]), self.labels[idx]

def __len__(self):

    return len(self.premises)

2.3. Putting All Things Together

现在可以调用read_snli函数和SNLIDataset类来下载snli数据集,并返回训练集和测试集的DataLoader实例以及训练集的词汇表。值得注意的是,必须使用从测试中构建的词汇集。因此,来自测试集的任何新令牌对于训练集上训练的模型都是未知的。

#@save

def load_data_snli(batch_size, num_steps=50):

"""Download the SNLI dataset and return data iterators and

vocabulary."""

num_workers = d2l.get_dataloader_workers()

data_dir = d2l.download_extract('SNLI')

train_data = read_snli(data_dir, True)

test_data = read_snli(data_dir, False)

train_set = SNLIDataset(train_data, num_steps)

test_set = SNLIDataset(test_data, num_steps, train_set.vocab)

train_iter = gluon.data.DataLoader(train_set, batch_size, shuffle=True,

                                   num_workers=num_workers)

test_iter = gluon.data.DataLoader(test_set, batch_size, shuffle=False,

                                  num_workers=num_workers)

return train_iter, test_iter, train_set.vocab

这里将批量大小设置为128,序列长度为50,并调用load_data_snli函数来获取数据迭代器和词汇表。然后打印出词汇量。

train_iter, test_iter, vocab = load_data_snli(128, 50)

len(vocab)

read 549367 examples

read 9824 examples

18678

现在打印第一个小批量的形状。与情绪分析相反,输入X[0]和X[1]表示一对前提和假设。

for X, Y in train_iter:

print(X[0].shape)

print(X[1].shape)

print(Y.shape)

break

(128, 50)

(128, 50)

(128,)

  1. Summary

· Natural language inference studies whether a hypothesis can be inferred from a premise, where both are a text sequence.

· In natural language inference, relationships between premises and hypotheses include entailment, contradiction, and neutral.

· Stanford Natural Language Inference (SNLI) Corpus is a popular benchmark dataset of natural language inference.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章