自然語言推理和數據集

自然語言推理和數據集

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.

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