https://qweme.dev
-
Автор темы
- #1
О чем статья?
В этом руководстве я буду fine-тюнить text-classification модель на датасете отзывов из лаунчера Melonity
Начнем с датасета
Я спарсил информацию с лаунчера
У нас есть массив с отзывами такого типа
Подготовим информацию
Датасет у нас не кристально чистый поэтому его нужно фильтровать ( столкнулся с тем что некоторые юзеры вставляли промокоды в поле текса, нам этого не нужно )
Дальше нужно убрать спец символы
Cохраним это в json файлик
Необходимо не забывать о нормализации данных, особенно если положительных отзывов значительно больше, чем отрицательных. В моем случае, я разделил датасет на две категории: BAD (отзывы с оценкой 1 или 2) и GOOD (отзывы с оценкой 3 и выше).
Однако, в моем датасете 88.9% отзывов были помечены как GOOD, поэтому я решил вручную обрезать датасет таким образом, чтобы количество отзывов в каждой категории было примерно равное - 50% / 50%.
Конечно, из-за этого обрезания, информации получилось не очень много (что не очень хорошо для обучения, так как чем больше данных, тем лучше модель), но я пропущу этот момент, так как это всего лишь гайд.
И снова в школу
Мы будем использовать уже готовую модель классификации под Русский язык -
Создаем токинайзер
Токенизер в NLP (Natural Language Processing) используется для разделения текста на отдельные токены или слова. Это первый шаг в обработке текста перед анализом и позволяет преобразовать непрерывный поток текста в структурированные единицы для более детального анализа.
Прогоним датасет через токинайзер
Создаем подборщик данных
Подготовим метрики
Этот код определяет функцию compute_metrics, которая используется для вычисления метрик оценки модели. Входными данными для этой функции является кортеж eval_pred, который содержит предсказания модели (predictions) и соответствующие метки (labels). Функция сначала преобразует предсказания модели в индексы классов с наибольшими значениями вероятности с помощью функции np.argmax(). Затем она вызывает какую функцию accuracy.compute(), передавая в неё предсказанные индексы классов и реальные метки. Эта функция вычисляет и возвращает значение точности модели на основе предсказаний и меток.
Определим метки
Начинаем учить
Проверим модель
Console
Спасибо за внимание, больше новостей в
В этом руководстве я буду fine-тюнить text-classification модель на датасете отзывов из лаунчера Melonity
Начнем с датасета
Я спарсил информацию с лаунчера
Пожалуйста, авторизуйтесь для просмотра ссылки.
( В нем есть кнопка оставить отзыв, пользователь пишет отзыв и ставит оценку от 1 до 5 )У нас есть массив с отзывами такого типа
JSON:
[
{
"text": "отзыв",
"label": "оценка от 0 до 4"
}
]
Датасет у нас не кристально чистый поэтому его нужно фильтровать ( столкнулся с тем что некоторые юзеры вставляли промокоды в поле текса, нам этого не нужно )
Python:
def callback(item) -> bool:
text: str = item["text"]
res = True
# Фильтруем по длине текста
if len(text) < 3 or len(text) > 128:
res = False
# Скипаем промокоды, они такого типа > 0000-0000-0000-0000
if text.count("-") == 3:
res = False
return res
res = list(filter(callback, data))
Python:
def callback(data):
# Тут я заменил html коды символов
data["text"] = unescape(data["text"])
# Удалим все кроме цифр и букв
data["text"] = sub('[^a-zA-Z0-9А-Яа-я \n\.]', '', data["text"])
return data
res = list(map(callback, res))
Необходимо не забывать о нормализации данных, особенно если положительных отзывов значительно больше, чем отрицательных. В моем случае, я разделил датасет на две категории: BAD (отзывы с оценкой 1 или 2) и GOOD (отзывы с оценкой 3 и выше).
Однако, в моем датасете 88.9% отзывов были помечены как GOOD, поэтому я решил вручную обрезать датасет таким образом, чтобы количество отзывов в каждой категории было примерно равное - 50% / 50%.
Конечно, из-за этого обрезания, информации получилось не очень много (что не очень хорошо для обучения, так как чем больше данных, тем лучше модель), но я пропущу этот момент, так как это всего лишь гайд.
И снова в школу
Python:
from datasets import load_dataset
dataset = load_dataset("json", data_files="dataset/melonity.json", split="train")
dataset = dataset.train_test_split(test_size=0.1) # режем датасет на трейн и тест
cointegrated/rubert-tiny2
Создаем токинайзер
Python:
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("cointegrated/rubert-tiny2")
Прогоним датасет через токинайзер
Python:
def preprocess_function(examples):
return tokenizer(examples["text"], truncation=True)
tokenized_dataset = dataset.map(preprocess_function, batched=True)
Python:
from transformers import DataCollatorWithPadding
data_collator = DataCollatorWithPadding(tokenizer=tokenizer)
Python:
import evaluate
import numpy as np
accuracy = evaluate.load("accuracy")
def compute_metrics(eval_pred):
predictions, labels = eval_pred
predictions = np.argmax(predictions, axis=1)
return accuracy.compute(predictions=predictions, references=labels)
Определим метки
Python:
id2label = {0: "BAD", 1: "GOOD" }
label2id = {"BAD": 0, "GOOD": 1}
Python:
from transformers import AutoModelForSequenceClassification, TrainingArguments, Trainer
model = AutoModelForSequenceClassification.from_pretrained(
"cointegrated/rubert-tiny2", num_labels=2, id2label=id2label, label2id=label2id, ignore_mismatched_sizes=True
)
# Подробнее о аргументах в моей прошлой статье https://qweme.dev/blog/image-classification
training_args = TrainingArguments(
output_dir="melonity-feedback",
learning_rate=5e-5,
per_device_train_batch_size=16,
gradient_accumulation_steps=4,
per_device_eval_batch_size=16,
num_train_epochs=5,
evaluation_strategy="epoch",
save_strategy="epoch",
load_best_model_at_end=True,
push_to_hub=False,
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_dataset["train"],
eval_dataset=tokenized_dataset["test"],
tokenizer=tokenizer,
data_collator=data_collator,
compute_metrics=compute_metrics,
)
trainer.train()
Python:
from transformers import pipeline
classify = pipeline("text-classification", "qweme-ai/melonity-feedback")
print(classify("я люблю играть с этим читом"))
print(classify("чит крутой но есть баги"))
print(classify("хуета"))
print(classify("мелонка как всегда топ"))
print(classify("крашит чит"))
Python:
[{'label': 'GOOD', 'score': 0.9711869955062866}]
[{'label': 'GOOD', 'score': 0.9603896737098694}]
[{'label': 'BAD', 'score': 0.9808063507080078}]
[{'label': 'GOOD', 'score': 0.9760079979896545}]
[{'label': 'BAD', 'score': 0.7551760673522949}]
Пожалуйста, авторизуйтесь для просмотра ссылки.