#python #pytorch #nltk #torchtext
#python #pytorch #nltk #torchtext
Вопрос:
У меня есть список dicts следующим образом:
[{'text': ['The', 'Fulton', 'County', 'Grand', ...], 'tags': ['AT', 'NP-TL', 'NN-TL', 'JJ-TL', ...]},
{'text': ['The', 'jury', 'further', 'said', ...], 'tags': ['AT', 'NN', 'RBR', 'VBD', ...]},
...]
Каждое значение каждого dict представляет собой список предложений-слов / тегов. Это непосредственно из коричневого корпуса набора данных NLTK, загруженного с помощью:
from nltk.corpus import brown
data = brown.tagged_sents()
data = {'text': [[word for word, tag in sent] for sent in data], 'tags': [[tag for word, tag in sent] for sent in data]}
import pandas as pd
df = pd.DataFrame(training_data, columns=["text", "tags"])
from sklearn.model_selection import train_test_split
train, val = train_test_split(df, test_size=0.2)
train.to_json("train.json", orient='records')
val.to_json("val.json", orient='records')
Я хочу загрузить этот json в torchtext.data.TabularDataset с использованием:
TEXT = data.Field(lower=True)
TAGS = data.Field(unk_token=None)
data_fields = [('text', TEXT), ('tags', TAGS)]
train, val = data.TabularDataset.splits(path='./', train='train.json', validation='val.json', format='json', fields=data_fields)
Но это выдает мне эту ошибку:
/usr/local/lib/python3.6/dist-packages/torchtext/data/example.py in fromdict(cls, data, fields)
17 def fromdict(cls, data, fields):
18 ex = cls()
---> 19 for key, vals in fields.items():
20 if key not in data:
21 raise ValueError("Specified key {} was not found in "
AttributeError: 'list' object has no attribute 'items'
Обратите внимание, что я не хочу, чтобы TabularDataset маркировал предложение для меня, поскольку оно уже маркировано nltk. Как мне подойти к этому? (Я не могу переключить корпуса на то, что я могу напрямую загрузить из torchtext.dataset, я должен использовать корпус Brown)
Ответ №1:
Для тех, кто сейчас рассматривает этот вопрос, обратите внимание, что он использует устаревшую версию torchtext. Вы все еще можете использовать эту функциональность, но вам нужно добавить устаревший … например:
from torchtext import data
from torchtext import datasets
from torchtext import legacy
TEXT = legacy.data.Field()
TAGS = legacy.data.Field()
Затем я бы предложил форматировать data_fields следующим образом:
fields = {'text': ('text', TEXT), 'tag': ('tag', TAGS)}
Это должно сработать. Для всех, кто использует последнюю функциональность torchtext, способ сделать это:
Для создания повторяющегося набора данных вы можете использовать функцию _RawTextIterableDataset. Вот пример, который загружается из файла json:
def _create_data_from_json(data_path):
with open(data_path) as json_file:
raw_json_data = json.load(json_file)
for item in raw_json_data:
_label, _paragraph = item['tags'], item['text']
yield (_tag, _text)
#Load torchtext utilities needed to convert (label, paragraph) tuple into iterable dataset
from torchtext.data.datasets_utils import (
_RawTextIterableDataset,
_wrap_split_argument,
_add_docstring_header,
_create_dataset_directory,
)
#Dictionary of data sources. The train and test data JSON files have items consisting of paragraphs and labels
DATA_SOURCE = {
'train': 'data/train_data.json',
'test': 'data/test_data.json'
}
#This is the number of lines/items in each data set
NUM_LINES = {
'train': 200,
'test': 100,
}
#Naming the dataset
DATASET_NAME = "BAR"
#This function return the iterable dataset based on whatever split is passed in
@_add_docstring_header(num_lines=NUM_LINES, num_classes=2)
@_create_dataset_directory(dataset_name=DATASET_NAME)
@_wrap_split_argument(('train', 'test'))
def FOO(root, split):
return _RawTextIterableDataset(DATASET_NAME, NUM_LINES[split],
_create_data_from_json(DATA_SOURCE[split]))
Затем вы можете вызвать эту функцию, чтобы вернуть свой повторяющийся набор данных:
#Get iterable for train and test data sets
train_iter, test_iter = FOO(split=('train', 'test'))
Функцию _create_data_from_json можно заменить любой функцией, которая выдает кортеж из источника данных.