Добавить в корзинуПозвонить
Найти в Дзене
Бит_01101

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

1)Первое, что нужно сделать это найти нужный нам датасет диалогов.
Есть сайт где можно найти множество любых датасетов - это Hugging Face
2)На главной странице в правом верхнем углу будет Datasets("Датасеты") жмём на неё на этой вкладке будут датасеты для разных нейросетей , но нам нужен датасет диалогов , поэтому слева в фильтрах выбираем Conversational("Разговорный, диалоговый") там будут разные языки , но если вы хотите выбрать нужный вам язык , то просто в фильтрах добавьте тот язык, который вам будет нужен. После скачивания датасета на компьютер надо перенести данные из нейросети я выбрал выборку от Den4ikAI датасет russian_dialogues
он записан в формате jsonl JSONL (JSON Lines) - это формат данных, который представляет отдельные объекты JSON, разделенные переводами строк. В отличие от формата JSON, где объекты обычно хранятся в виде массива или объекта, в формате JSONL каждый объект представлен отдельной строкой. Это делает формат JSONL более удобным для обработки больших объ

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)

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