PyTorch torchtext
Хотя экосистема PyTorch имеетtorchvisionобработку данных изображений,torchaudioобработку аудиоданных, но в области обработки текста официально предоставленнаяtorchtextбиблиотека претерпела некоторые изменения. В этом разделе рассказывается, как выполнять предварительную обработку текстовых данных, построение словаря, загрузку данных и другие операции с использованием различных методов.
Примечание: библиотека torchtext подверглась некоторому рефакторингу. Рекомендуется использоватьtorchtext.legacyили создать собственный конвейер обработки текста. Последняя версия torchtext вернулась и предоставляет более современный API.
1. Основы предварительной обработки текстовых данных
Предобработка текста — это первый шаг в задачах NLP, включая токенизацию, построение словаря, кодирование и другие операции.
1.1 Базовый конвейер обработки текста
Пример
from collections import Counter
class SimpleTokenizer:
"""
Простой токенизатор: токенизирует по пробелам и знакам препинания
"""
def __init__(self):
# Сопоставление знаков препинания
self.punctuation = str.maketrans('', '', '.,!?;:"\'-()[]{}')
def tokenize(self, text):
# Преобразовать в нижний регистр
text = text.lower()
# Удалить знаки препинания
text = text.translate(self.punctuation)
# Токенизировать
tokens = text.split()
return tokens
class Vocabulary:
"""
Построение словаря
"""
def __init__(self, min_freq=2, max_size=10000):
self.min_freq = min_freq
self.max_size = max_size
self.word2idx = {'<PAD>': 0, '<UNK>': 1}
self.idx2word = {0: '<PAD>', 1: '<UNK>'}
self.word_count = Counter()
def build_vocab(self, texts):
"""Построить словарь из списка текстов"""
tokenizer = SimpleTokenizer()
# Подсчет частот слов
for text in texts:
tokens = tokenizer.tokenize(text)
self.word_count.update(tokens)
# Построить словарь
for word, count in self.word_count.most_common(self.max_size):
if count < self.min_freq:
break
if word not in self.word2idx:
idx = len(self.word2idx)
self.word2idx[word] = idx
self.idx2word[idx] = word
print(f"Размер словаря: {len(self.word2idx)}")
def encode(self, text, max_len=50):
"""Закодировать текст как последовательность индексов"""
tokenizer = SimpleTokenizer()
tokens = tokenizer.tokenize(text)[:max_len]
# Кодирование
indices = [
self.word2idx.get(token, self.word2idx['<UNK>'])
for token in tokens
]
# Дополнить нулями
if len(indices) < max_len:
indices += [self.word2idx['<PAD>']] * (max_len - len(indices))
return indices
def decode(self, indices):
"""Декодировать последовательность индексов в текст"""
tokens = [self.idx2word.get(idx, '<UNK>') for idx in indices]
return ' '.join(tokens)
# Пример использования
texts = [
"Привет, мир",
"Это тест",
"PyTorch отлично подходит для глубокого обучения",
"Обработка естественного языка — это увлекательно",
"Глубокое обучение позволяет реализовать множество приложений",
]
vocab = Vocabulary(min_freq=1, max_size=100)
vocab.build_vocab(texts)
# Кодирование
encoded = vocab.encode("Привет, мир глубокого обучения!", max_len=10)
print(f"Закодированный результат: {encoded}")
# Декодирование
decoded = vocab.decode(encoded)
print(f"Результат декодирования: {decoded}")
2. Использование torchtext (Legacy)
Если torchtext установлен, можно использовать legacy-модуль для обработки текста.
2.1 Установка и импорт
Пример
# pip install torchtext
# Импорт legacy-модуля
try:
import torchtext
from torchtext.legacy import data
from torchtext.legacy import datasets
print(f"версия torchtext: {torchtext.__version__}")
TORCHTEXT_AVAILABLE = True
except ImportError:
print("torchtext не установлен, используется собственная реализация")
TORCHTEXT_AVAILABLE = False
# Или попробуйте новую версию
try:
from torchtext import transforms
from torchtext.datasets import AG_NEWS
print("Доступна новая версия torchtext")
except ImportError:
print("Новая версия torchtext недоступна")
2.2 Field и Dataset
Пример
from torchtext.legacy import data
from torchtext.legacy import datasets
from torchtext.legacy.data import Field, TabularDataset, BucketIterator
# Определите поля
TEXT = Field(
tokenize='spacy', # Использовать spacy для токенизации
tokenizer_language='en_core_web_sm',
lower=True, # Преобразовать в нижний регистр
include_lengths=True, # Вернуть длину последовательности
batch_first=True # Размер пакета первым
)
LABEL = Field(
sequential=False,
use_vocab=False,
dtype=torch.long
)
# Определить набор данных
# Предполагается формат CSV-файла: label,text
# 1,Это положительный отзыв
# 0,Это отрицательный отзыв
# Или используйте встроенный набор данных (например, IMDB)
# train_data, test_data = datasets.IMDB.splits(TEXT, LABEL)
print("Настройка Field и Dataset завершена")
2.3 Построение словаря и итераторы
Пример
# TEXT.build_vocab(train_data, vectors="glove.6B.100d", max_size=10000)
# Создать итератор
# train_iterator, test_iterator = BucketIterator.splits(
# (train_data, test_data),
# batch_size=32,
# sort_within_batch=True,
# device=torch.device('cuda')
# )
# Итерация обучения
# for batch in train_iterator:
# text, lengths = batch.text
# labels = batch.label
# # Код обучения
print("Настройка словаря и итератора завершена")
3. Пользовательский конвейер данных NLP
Рекомендуется использовать более гибкий пользовательский подход к обработке данных, не зависящий от torchtext.
3.1 Реализация класса Dataset
Пример
from torch.utils.data import Dataset, DataLoader
from collections import Counter
import re
class TextDataset(Dataset):
"""
Текстовый датасет
"""
def __init__(self, texts, labels, vocab=None, max_len=128, min_freq=2):
self.texts = texts
self.labels = labels
self.max_len = max_len
# Создайте или используйте существующий словарь
if vocab is None:
self.vocab = self._build_vocab(texts, min_freq)
else:
self.vocab = vocab
def _build_vocab(self, texts, min_freq):
"""Построить словарь"""
word_counts = Counter()
for text in texts:
tokens = self._tokenize(text)
word_counts.update(tokens)
# Создать словарь
word2idx = {'<PAD>': 0, '<UNK>': 1}
for word, count in word_counts.items():
if count >= min_freq:
word2idx[word] = len(word2idx)
return word2idx
def _tokenize(self, text):
"""Простая токенизация"""
# Преобразовать в нижний регистр
text = text.lower()
# Удалить специальные символы, оставить буквенно-цифровые символы и пробелы
text = re.sub(r'[^a-z0-9\s]', ' ', text)
# Токенизировать
tokens = text.split()
return tokens
def _encode(self, text):
"""Закодировать текст"""
tokens = self._tokenize(text)[:self.max_len]
indices = [
self.vocab.get(token, self.vocab['<UNK>'])
for token in tokens
]
# Дополнить нулями
if len(indices) < self.max_len:
indices += [self.vocab['<PAD>']] * (self.max_len - len(indices))
return indices
def __len__(self):
return len(self.texts)
def __getitem__(self, idx):
text = self.texts[idx]
label = self.labels[idx]
encoded = self._encode(text)
return torch.tensor(encoded, dtype=torch.long), torch.tensor(label, dtype=torch.long)
# Пример использования
texts = [
"Это отличный фильм",
"Я ненавидел этот фильм",
"Потрясающая игра",
"Ужасная игра",
"Настоятельно рекомендую",
]
labels = [1, 0, 1, 0, 1]
dataset = TextDataset(texts, labels, max_len=10)
print(f"Размер набора данных: {len(dataset)}")
print(f"Размер словаря: {len(dataset.vocab)}")
# Получить пример
text, label = dataset[0]
print(f"Кодировка текста: {text[:5]}...")
print(f"Метка: {label}")
3.2 Продвинутые токенизаторы
Пример
def tokenize_with_spacy(text):
"""Токенизировать с помощью spacy"""
try:
import spacy
nlp = spacy.load("en_core_web_sm")
doc = nlp(text)
return [token.text for token in doc]
except ImportError:
print("spacy не установлен, используется простая токенизация")
return text.lower().split()
# Использовать nltk для токенизации и стемминга
def tokenize_with_nltk(text):
"""Токенизировать с помощью nltk"""
try:
import nltk
from nltk.tokenize import word_tokenize
from nltk.stem import PorterStemmer
# Токенизировать
tokens = word_tokenize(text.lower())
# Необязательно: стемминг
stemmer = PorterStemmer()
tokens = [stemmer.stem(token) for token in tokens if token.isalnum()]
return tokens
except ImportError:
return text.lower().split()
# Используйте SentencePiece для субсловной токенизации
class SentencePieceTokenizer:
"""
Используйте SentencePiece для субсловной токенизации
"""
def __init__(self, model_path=None):
self.model_path = model_path
self.sp = None
def train(self, texts, vocab_size=10000):
"""Обучить модель SentencePiece"""
try:
import sentencepiece as spm
import tempfile
# Записать во временный файл
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.txt') as f:
for text in texts:
f.write(text + '\n')
temp_file = f.name
# Обучить
spm.SentencePieceTrainer.train(
input=temp_file,
model_prefix='spm_model',
vocab_size=vocab_size,
character_coverage=1.0,
model_type='unigram',
)
self.sp = spm.SentencePieceProcessor()
self.sp.load('spm_model.model')
except ImportError:
print("sentencepiece не установлен")
def encode(self, text):
if self.sp:
return self.sp.encode(text, out_type=str)
return text.split()
def decode(self, ids):
if self.sp:
return self.sp.decode(ids)
return ' '.join(ids)
3.3 Полный загрузчик данных
Пример
from torch.utils.data import Dataset, DataLoader
from collections import Counter
class NLPDataset(Dataset):
"""
Полный класс набора данных NLP
Поддерживает последовательности переменной длины, построение словаря и дополнение батчей
"""
def __init__(self, texts, labels, min_freq=2, max_vocab=30000):
self.texts = texts
self.labels = labels
self.min_freq = min_freq
# Построить словарь
self.word2idx, self.idx2word = self._build_vocab(texts, max_vocab)
self.pad_idx = self.word2idx['<PAD>']
self.unk_idx = self.word2idx['<UNK>']
def _tokenize(self, text):
text = text.lower()
text = re.sub(r'[^a-z0-9\s]', ' ', text)
return text.split()
def _build_vocab(self, texts, max_vocab):
"""Построить словарь"""
counter = Counter()
for text in texts:
tokens = self._tokenize(text)
counter.update(tokens)
# Построить словарь
word2idx = {'<PAD>': 0, '<UNK>': 1}
idx2word = {0: '<PAD>', 1: '<UNK>'}
for word, count in counter.most_common(max_vocab):
if count >= self.min_freq and word not in word2idx:
idx = len(word2idx)
word2idx[word] = idx
idx2word[idx] = word
return word2idx, idx2word
def __len__(self):
return len(self.texts)
def __getitem__(self, idx):
text = self.texts[idx]
tokens = self._tokenize(text)
indices = [self.word2idx.get(t, self.unk_idx) for t in tokens]
return {
'input': indices,
'label': self.labels[idx],
'length': len(indices)
}
def collate_fn(batch, pad_idx=0):
"""
Пользовательская collate-функция: обработка последовательностей переменной длины
"""
# Сортировать по длине в порядке убывания
batch.sort(key=lambda x: x['length'], reverse=True)
texts = [item['input'] for item in batch]
labels = [item['label'] for item in batch]
lengths = [item['length'] for item in batch]
# Дополнить до одинаковой длины
max_len = max(lengths)
padded = [text + [pad_idx] * (max_len - len(text)) for text in texts]
return {
'input': torch.tensor(padded, dtype=torch.long),
'labels': torch.tensor(labels, dtype=torch.long),
'lengths': torch.tensor(lengths, dtype=torch.long)
}
# Использовать DataLoader
def create_dataloader(texts, labels, batch_size=32, shuffle=True):
"""Создать загрузчик данных"""
dataset = NLPDataset(texts, labels)
pad_idx = dataset.pad_idx
dataloader = DataLoader(
dataset,
batch_size=batch_size,
shuffle=shuffle,
collate_fn=lambda b: collate_fn(b, pad_idx)
)
return dataloader, dataset
# Имитация данных
texts = [
"Я люблю этот фильм",
"Это плохой фильм",
"Отличный фильм",
"Ужасная игра",
"Рекомендую это",
"Не стоит смотреть",
]
labels = [1, 0, 1, 0, 1, 0]
dataloader, dataset = create_dataloader(texts, labels, batch_size=2)
for batch in dataloader:
print("Форма входных данных:", batch['input'].shape)
print("Метки:", batch['labels'])
print("Длины:", batch['lengths'])
print("---")
4. Загрузка предобученных векторов слов
Использование предобученных векторов слов может улучшить производительность модели.
4.1 Векторы слов GloVe
Пример
import numpy as np
def load_glove_vectors(filepath, word2idx, embedding_dim=300):
"""
Загрузить предобученные векторы слов GloVe
Параметры:
filepath: путь к файлу GloVe
word2idx: словарь
embedding_dim: размерность векторов слов
"""
print("Загрузка векторов слов GloVe...")
# Инициализация матрицы эмбеддингов
num_words = len(word2idx)
embeddings = np.random.randn(num_words, embedding_dim).astype(np.float32)
embeddings[word2idx['<PAD>']] = np.zeros(embedding_dim) # Установить вектор PAD в ноль
words_loaded = 0
with open(filepath, 'r', encoding='utf-8') as f:
for line in f:
values = line.strip().split()
word = values[0]
if word in word2idx:
idx = word2idx[word]
vector = np.asarray(values[1:], dtype=np.float32)
if len(vector) == embedding_dim:
embeddings[idx] = vector
words_loaded += 1
print(f"Загружено {words_loaded}/{num_words} векторов слов")
return torch.from_numpy(embeddings)
# Имитация загрузки
def create_pretrained_embedding(word2idx, embedding_dim=300, pretrained_path=Отсутствует):
"""
Создать слой предобученных эмбеддингов
"""
if pretrained_path and False: # Установите True и укажите допустимый путь
weights = load_glove_vectors(pretrained_path, word2idx, embedding_dim)
else:
# Использовать случайную инициализацию
num_words = len(word2idx)
weights = torch.randn(num_words, embedding_dim) * 0.1
embedding = torch.nn.Embedding.from_pretrained(weights, padding_idx=0)
return embedding
# Пример
word2idx = {'<PAD>': 0, '<UNK>': 1, 'hello': 2, 'world': 3, 'test': 4}
embedding = create_pretrained_embedding(word2idx, embedding_dim=100)
print(f"Форма слоя эмбеддингов: {embedding.weight.shape}")
4.2 Загрузка Word2Vec с помощью gensim
Пример
"""
Загрузка Word2Vec с помощью gensim
"""
try:
from gensim.models import KeyedVectors
# Загрузить модель
# model = KeyedVectors.load_word2vec_format(model_path, binary=True)
# Создать матрицу эмбеддингов
embedding_dim = 300
num_words = len(word2idx)
embeddings = np.random.randn(num_words, embedding_dim).astype(np.float32)
# Заполнить векторы слов
embeddings[word2idx['<PAD>']] = np.zeros(embedding_dim)
# Загрузить векторы слов
# for word, idx in word2idx.items():
# if word in model:
# embeddings[idx] = model[word]
return torch.from_numpy(embeddings)
except ImportError:
print("gensim не установлен")
return None
4.3 Пользовательские предобученные эмбеддинги
Пример
import torch.nn as nn
class PretrainedEmbedding(nn.Module):
"""
Слой эмбеддингов, поддерживающий загрузку предобученных векторов слов
"""
def __init__(self, vocab_size, embed_dim, pretrained_weights=Отсутствует,
padding_idx=0, freeze=False):
super().__init__()
self.embedding = nn.Embedding(
vocab_size,
embed_dim,
padding_idx=padding_idx
)
# Загрузить предобученные веса
if pretrained_weights is not None:
self.embedding.weight.data.copy_(pretrained_weights)
# Замораживать ли
if freeze:
self.embedding.weight.requires_grad = False
def forward(self, x):
return self.embedding(x)
# Пример использования
vocab_size = 10000
embed_dim = 300
pretrained = torch.randn(vocab_size, embed_dim) * 0.1
embedding_layer = PretrainedEmbedding(
vocab_size,
embed_dim,
pretrained_weights=pretrained,
padding_idx=0,
freeze=False # Установите True, чтобы заморозить слой эмбеддингов
)
#
x = torch.tensor([[1, 2, 3], [4, 5, 6]])
output = embedding_layer(x)
print(f"Форма входа: {x.shape}")
print(f"Форма вывода: {output.shape}")
5. Аугментация текстовых данных
Аугментация данных может улучшить способность модели к обобщению.
5.1 Аугментация обратным переводом
Пример
def back_translation_augment(text, translator):
"""
Аугментация обратным переводом: перевести текст на другой язык, а затем перевести его обратно
"""
# Перевести на целевой язык
translated = translator.translate(text, dest='fr')
# Перевести обратно на исходный язык
back_translated = translator.translate(translated.text, dest='en')
return back_translated.text
# Пример использования
# from googletrans import Translator
# translator = Translator()
# augmented_text = back_translation_augment("Я люблю этот фильм", translator)
5.2 Замена синонимов
Пример
def synonym_replacement(text, n=1, stop_words=None):
"""
Замена синонимами
"""
if stop_words is None:
stop_words = {'a', 'an', 'the', 'is', 'are', 'was', 'were'}
words = text.lower().split()
replaceable = [i for i, w in enumerate(words) if w not in stop_words]
if not replaceable:
return text
n = min(n, len(replaceable))
replace_idx = random.sample(replaceable, n)
# Упрощённое сопоставление синонимов (на самом деле следует использовать WordNet)
synonym_map = {
'good': ['great', 'excellent', 'nice'],
'bad': ['poor', 'terrible', 'awful'],
'фильм': ['кинофильм', 'кино'],
'любил': ['обожал', 'наслаждался'],
}
for idx in replace_idx:
word = words[idx]
if word in synonym_map:
words[idx] = random.choice(synonym_map[word])
return ' '.join(words)
# Пример использования
text = "Я любил этот хороший фильм"
augmented = synonym_replacement(text, n=2)
print(f"Исходное предложение: {text}")
print(f"Аугментированное: {augmented}")
5.3 Случайная вставка и удаление
Пример
def random_insertion(text, n=1):
"""
Случайная вставка: случайным образом вставлять слова в текст
"""
words = text.lower().split()
for _ in range(n):
if len(words) > 1:
idx = random.randint(0, len(words) - 1)
# Упрощённые вставляемые слова
insert_words = ['really', 'very', 'quite', 'actually']
words.insert(idx, random.choice(insert_words))
return ' '.join(words)
def random_deletion(text, p=0.1):
"""
Случайное удаление: удалять слова с вероятностью p
"""
words = text.lower().split()
if len(words) == 1:
return text
remaining = [w for w in words if random.random() > p]
if len(remaining) == 0:
return random.choice(words)
return ' '.join(remaining)
def random_swap(text, n=1):
"""
Случайная перестановка: случайным образом поменять местами позиции двух слов
"""
words = text.lower().split()
if len(words) < 2:
return text
for _ in range(n):
idx1, idx2 = random.sample(range(len(words)), 2)
words[idx1], words[idx2] = words[idx2], words[idx1]
return ' '.join(words)
# Пример использования
text = "Это отличный фильм о любви и счастье"
print("Original:", text)
print("Вставлено:", random_insertion(text, n=2))
print("Удалено:", random_deletion(text, p=0.2))
print("Переставлено:", random_swap(text, n=2))
6. Примеры распространённых задач NLP
6.1 Полный конвейер классификации текста
Пример
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader
# 1. Подготовка данных
texts = [
"Мне нравится этот продукт, он потрясающий!",
"Ужасное качество, пустая трата денег.",
"Отличное соотношение цены и качества.",
"Не удовлетворён покупкой.",
"Лучшая покупка в моей жизни!",
"Очень разочарован этим товаром.",
]
labels = [1, 0, 1, 0, 1, 0] # 1: положительный, 0: отрицательный
# 2. Набор данных
class TextClassificationDataset(Dataset):
def __init__(self, texts, labels, max_len=50):
self.texts = texts
self.labels = labels
self.max_len = max_len
self.vocab = self._build_vocab(texts)
def _build_vocab(self, texts):
vocab = {'<PAD>': 0, '<UNK>': 1}
for text in texts:
for word in text.lower().split():
if word not in vocab:
vocab[word] = len(vocab)
return vocab
def __len__(self):
return len(self.texts)
def __getitem__(self, idx):
text = self.texts[idx]
label = self.labels[idx]
# Простое кодирование
tokens = text.lower().split()[:self.max_len]
indices = [self.vocab.get(t, 1) for t in tokens]
# Дополнение
if len(indices) < self.max_len:
indices += [0] * (self.max_len - len(indices))
return torch.tensor(indices, dtype=torch.long), torch.tensor(label, dtype=torch.long)
# 3. Модель
class TextClassifier(nn.Module):
def __init__(self, vocab_size, embed_dim=128, hidden_dim=64, num_classes=2):
super().__init__()
self.embedding = nn.Embedding(vocab_size, embed_dim, padding_idx=0)
self.lstm = nn.LSTM(embed_dim, hidden_dim, batch_first=True)
self.fc = nn.Linear(hidden_dim, num_classes)
def forward(self, x):
embedded = self.embedding(x)
_, (hidden, _) = self.lstm(embedded)
output = self.fc(hidden.squeeze(0))
return output
# 4. Обучение
dataset = TextClassificationDataset(texts, labels)
dataloader = DataLoader(dataset, batch_size=2, shuffle=True)
model = TextClassifier(vocab_size=len(dataset.vocab))
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
# Обучение в течение нескольких эпох
model.train()
for epoch in range(10):
total_loss = 0
for texts_batch, labels_batch in dataloader:
optimizer.zero_grad()
outputs = model(texts_batch)
loss = criterion(outputs, labels_batch)
loss.backward()
optimizer.step()
total_loss += loss.item()
print(f"Epoch {epoch+1}, Loss: {total_loss/len(dataloader):.4f}")
print("Обучение завершено!")
6.2 Пример разметки последовательностей (NER)
Пример
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader
# Набор данных для разметки последовательностей
class NERDataset(Dataset):
"""
Набор данных для распознавания именованных сущностей
Формат: [(word, tag), ...]
"""
def __init__(self, sentences_tags, word2idx, tag2idx, max_len=50):
self.sentences_tags = sentences_tags
self.word2idx = word2idx
self.tag2idx = tag2idx
self.max_len = max_len
def __len__(self):
return len(self.sentences_tags)
def __getitem__(self, idx):
sentence_tags = self.sentences_tags[idx]
words = [wt[0] for wt in sentence_tags]
tags = [wt[1] for wt in sentence_tags]
# Кодирование
word_ids = [self.word2idx.get(w.lower(), 1) for w in words[:self.max_len]]
tag_ids = [self.tag2idx[t] for t in tags[:self.max_len]]
# Дополнение
if len(word_ids) < self.max_len:
word_ids += [0] * (self.max_len - len(word_ids))
tag_ids += [0] * (self.max_len - len(tag_ids))
return {
'words': torch.tensor(word_ids, dtype=torch.long),
'tags': torch.tensor(tag_ids, dtype=torch.long)
}
# NER-модель
class NERModel(nn.Module):
def __init__(self, vocab_size, tag_size, embed_dim=128, hidden_dim=256):
super().__init__()
self.embedding = nn.Embedding(vocab_size, embed_dim, padding_idx=0)
self.lstm = nn.LSTM(embed_dim, hidden_dim, batch_first=True, bidirectional=True)
self.fc = nn.Linear(hidden_dim * 2, tag_size)
def forward(self, x):
embedded = self.embedding(x)
lstm_out, _ = self.lstm(embedded)
logits = self.fc(lstm_out)
return logits
# Пример данных
data = [
[("John", "B-PER"), ("lives", "O"), ("in", "O"), ("New", "B-LOC"), ("York", "I-LOC"), (".", "O")],
[("Apple", "B-ORG"), ("is", "O"), ("a", "O"), ("company", "O"), (".", "O")],
]
# Построить словарь слов и таблицу тегов
word2idx = {'<PAD>': 0, '<UNK>': 1}
tag2idx = {'O': 0, 'B-PER': 1, 'I-PER': 2, 'B-LOC': 3, 'I-LOC': 4, 'B-ORG': 5, 'I-ORG': 6}
for sent in data:
for word, tag in sent:
if word.lower() not in word2idx:
word2idx[word.lower()] = len(word2idx)
print(f"Размер словаря: {len(word2idx)}")
print(f"Количество тегов: {len(tag2idx)}")
7. Рекомендуемые альтернативы
7.1 Другие библиотеки обработки текста
| Имя библиотеки | Особенности | Применимые сценарии |
|---|---|---|
| HuggingFace Datasets | Загрузка и обработка данных | Общие задачи NLP |
| spacy | Продвинутые инструменты NLP | Токенизация, NER, синтаксический анализ зависимостей |
| NLTK | Классические инструменты NLP | Обучение, прототипирование |
| textblob | Простота и удобство использования | Быстрая обработка текста |
7.2 Использование HuggingFace Datasets
Пример
# pip install datasets
from datasets import load_dataset
# Загрузка набора данных
# dataset = load_dataset("imdb")
# dataset = load_dataset("squad")
# Предварительная обработка данных
# def preprocess_function(examples):
# return tokenizer(examples['text'], truncation=True, padding='max_length')
# tokenized_dataset = dataset.map(preprocess_function, batched=True)
print("Пример использования HuggingFace Datasets:")
print("from datasets import load_dataset")
print("dataset = load_dataset('imdb')")
8. Краткий справочник по API
8.1 Общие операции обработки текста
| Действие | Метод |
|---|---|
| Токенизация | text.split(), spacy, nltk, jieba |
| Построение словаря | Counter, vocab.build_vocab() |
| Кодирование | vocab.encode(), tokenizer.encode() |
| Декодирование | vocab.decode(), tokenizer.decode() |
| Внутренний отступ | pad_sequence, collate_fn |
| Загрузка векторов слов | Прямая загрузка Gensim, GloVe |
8.2 Методы аугментации данных
| Метод | Описание |
|---|---|
| Замена синонимами | Случайная замена слов синонимами |
| Случайная вставка | Случайная вставка слов |
| Случайное удаление | Случайное удаление слов |
| Случайная перестановка | Случайная перестановка позиций слов |
| Обратный перевод | Перевести и затем перевести обратно |
8.3 Рекомендуемый конвейер обработки данных
1. 数据清洗 - 去除 HTML 标签、特殊字符 - 统一编码、大小写 2. 分词 - 英文: spaCy / NLTK - 中文: jieba / pkuseg 3. 词表构建 - 过滤低频词 - 设定最大词表大小 4. 序列化 - 编码为索引 - 统一长度(填充/截断) 5. 数据增强(可选) - 同义词替换、回译 6. 批量加载 - DataLoader + 自定义 collate_fnДругие расширения