Найти тему
Бит_01101

Подготовка диалоговых датасетов для рекуррентной нейросети на Python

1)Первое, что нужно сделать это найти нужный нам датасет диалогов.

Есть сайт где можно найти множество любых датасетов - это
Hugging Face

2)
На главной странице в правом верхнем углу будет Datasets("Датасеты") жмём на неё на этой вкладке будут датасеты для разных нейросетей , но нам нужен датасет диалогов , поэтому слева в фильтрах выбираем Conversational("Разговорный, диалоговый") там будут разные языки , но если вы хотите выбрать нужный вам язык , то просто в фильтрах добавьте тот язык, который вам будет нужен.

После скачивания датасета на компьютер надо перенести данные из нейросети я выбрал выборку от Den4ikAI датасет russian_dialogues
он записан в формате jsonl

JSONL (JSON Lines) - это формат данных, который представляет отдельные объекты JSON, разделенные переводами строк. В отличие от формата JSON, где объекты обычно хранятся в виде массива или объекта, в формате JSONL каждый объект представлен отдельной строкой. Это делает формат JSONL более удобным для обработки больших объемов данных потоковыми алгоритмами. JSONL можно использовать для хранения и передачи структурированных данных в форме записей, каждая из которых представлена отдельной строкой.

для чтения такого формата нужно использовать библиотеку "json_lines" , чтобы её скачать нужно в терминал ввести "pip install jsonlines"

после установки библиотеки мы должны написать такой код :

dialogs = []
with open('dataset.jsonl', 'rb') as f:
for item in json_lines.reader(f):
question = item.get("question")
answer = item.get("answer")
if question is not None and answer is not None:
dialogs.append((question, answer))

В данной части кода создается пустой список `dialogs`. Затем открывается файл с именем "dataset.jsonl" в режиме чтения бинарного файла (`'rb'`).

Затем для каждой строки в файле используется `json_lines` модуль, чтобы преобразовать строку с данными JSON в объект Python.

Затем из каждого объекта извлекаются значения для ключей "question" и "answer" и сохраняются в переменные `question` и `answer` соответственно.

Далее, проверяется условие: если значение `question` и `answer` не является `None`, то создается кортеж `(question, answer)` и добавляется в список `dialogs`.

Таким образом, код проходит через все строки в файле "dataset.jsonl" и сохраняет пары вопрос-ответ в список `dialogs`.

Далее нам нужно создать tokenizer

Tokenizer нужен для разделения текста на отдельные слова или токены. Это полезный инструмент при обработке естественного языка и анализе текста.

Я использую tokenizer от keras чтобы его получить надо сначала закачать библиотеку keras чтобы её закачать нужно в терминал ввести "pip install keras" и потом ввести это в код "from keras.preprocessing.text import Tokenizer"

Вот как примерно будет выглядеть tokenizer в python:

tokenizer = Tokenizer(num_words="максимальное количество слов", filters='!–"—#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n\r«»', lower=True, split=' ', char_level=False)

num_words: Это параметр, определяющий максимальное количество слов, которые будут участвовать в токенизации.

filters: Это строка, содержащая символы, которые будут удалены из текста перед токенизацией.

lower: Этот параметр определяет, должны ли слова конвертироваться в нижний регистр перед токенизацией.

split: Это строка, указывающая, как разделять текст на токены.

char_level: Этот параметр определяет, должны ли слова разделяться на символы.(Если установлено значение True, то каждый символ будет рассматриваться как отдельный токен)

3)Далее объединим question и answer преобразуя в список только тексты диалогов

dialogs_text = [question + ' ' + answer for question, answer in dialogs]

Потом пишем такой код

tokenizer.fit_on_texts(dialogs_text)

Метод `fit_on_texts()` вызывается на объекте Tokenizer и используется для адаптации (обучения) токенизатора на переданном тексте. В данном случае, текст `dialogs_text` используется для создания словаря, который будет использоваться для токенизации текста.

4)Теперь нам надо разбить выборку для этого мы пишем этот код

X_train, X_test, y_train, y_test = train_test_split(dialogs_text, dialogs, test_size=0.2, random_state=42)

Этот код использует функцию `train_test_split` из библиотеки `sklearn.model_selection` для разделения исходных данных на обучающий и тестовый наборы.Чтобы скачать библиотеку sklearn надо в терминал вписать "pip install scikit-learn" ,а потом в коде подключить библиотеку "from sklearn.model_selection import train_test_split"

После с данными нужно провести несколько манипуляций

from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import LabelBinarizer
y_train = da.from_array(y_train[:Number_words], chunks=("Ваши_размеры чанка", "Ваши_размеры чанка"))
y_test = da.from_array(y_test[:Number_words], chunks=("Ваши_размеры чанка", "Ваши_размеры чанка"))

X_train_sequences = tokenizer.texts_to_sequences(X_train)
X_test_sequences = tokenizer.texts_to_sequences(X_test)

label_encoder = LabelEncoder()

y_train_labels = [label for _, label in y_train[:Number_words].compute()]
y_test_labels = [label for _, label in y_test[:Number_words].compute()]

label_binarizer = LabelBinarizer()

y_train_encoded = label_binarizer.fit_transform(y_train_labels)
y_test_encoded = label_binarizer.fit_transform(y_test_labels)

max_sequence_length = 15

X_train_padded = pad_sequences(X_train_sequences, maxlen=max_sequence_length)
X_test_padded = pad_sequences(X_test_sequences, maxlen=max_sequence_length)

Этот код выполняет следующие действия:

1. Создает два Dask-массива "y_train" и "y_test" из оригинальных массивов "y_train" и "y_test" с ограничением на количество элементов, определенное переменной "Number_words". Каждый массив создается с размером чанка "Ваши_размеры чанка"x"Ваши_размеры чанка"для улучшения эффективности операций над массивами. .
Чтобы скачать библиотеку Dask в терминал вставьте "pip install dask"
2. Преобразует тексты `X_train` и `X_test` в последовательности целых чисел с использованием метода `texts_to_sequences` объекта `tokenizer`.
3. Инициализирует объект `label_encoder`.
4. Получает метки классов в виде списка `y_train_labels` и `y_test_labels` путем вычисления (выполнения) распределенных массивов `y_train[:Number_words]` и `y_test[:Number_words]`.
5. Инициализирует объект `label_binarizer`.
6. Кодирует метки классов с использованием метода `fit_transform` объекта `label_binarizer` в виде `y_train_encoded` и `y_test_encoded`.
7. Устанавливает максимальную длину последовательности в переменной `max_sequence_length`.
8. Дополняет последовательности `X_train_sequences` и `X_test_sequences` до максимальной длины `max_sequence_length` с использованием метода `pad_sequences`, сохраняя результаты в `X_train_padded` и `X_test_padded`.

Вот весь код:

from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from keras.preprocessing.text import Tokenizer
import json_lines
import dask.array as da
dialogs = []
with open('dataset.jsonl', 'rb') as f:
for item in json_lines.reader(f):
question = item.get("question")
answer = item.get("answer")
if question is not None and answer is not None:
dialogs.append((question, answer))

tokenizer = Tokenizer(num_words=maxWordsCount, filters='!–"—#$%&()*+,-./:;<=>?@[\\]^_`{|}~\t\n\r«»', lower=True, split=' ', char_level=False)

dialogs_text = [question + ' ' + answer for question, answer in dialogs]

tokenizer.fit_on_texts(dialogs_text)

X_train, X_test, y_train, y_test = train_test_split(dialogs_text, dialogs, test_size=0.2, random_state=42)

y_train = da.from_array(y_train[:Number_words], chunks=(
"Ваши_размеры чанка", "Ваши_размеры чанка"))
y_test = da.from_array(y_test[:Number_words], chunks=(
"Ваши_размеры чанка", "Ваши_размеры чанка"))

X_train_sequences = tokenizer.texts_to_sequences(X_train)
X_test_sequences = tokenizer.texts_to_sequences(X_test)

label_encoder = LabelEncoder()

y_train_labels = [label for _, label in y_train[:Number_words].compute()]
y_test_labels = [label for _, label in y_test[:Number_words].compute()]

label_binarizer = LabelBinarizer()

y_train_encoded = label_binarizer.fit_transform(y_train_labels)
y_test_encoded = label_binarizer.fit_transform(y_test_labels)

max_sequence_length = 15

X_train_padded = pad_sequences(X_train_sequences, maxlen=max_sequence_length)
X_test_padded = pad_sequences(X_test_sequences, maxlen=max_sequence_length)

После этих манипуляций вы отправляете обработанные данные в слои ,которые проводят нужные операции над данными.