Теперь пора попробовать сэмплировать данные для задачи мультиклассовой классификации. Распределение классов:

Распределение данных в датасете с музыкой четырёх жанров. Число объектов класса Rock — 3000, класса Electronic — 2000, класса Classical — 1000, класса Blues — 500.

Создайте и обучите LogisticRegression и получите предсказания на тестовых данных, не учитывая проблему дисбаланса классов.

Подождите, но ведь логистическая регрессия не может проводить мультиклассовую классификацию!

Сама по себе — не может. Но её реализация sklearn включает дополнительные алгоритмы, которые позволяют обходить ограничение. За это отвечает настройка модели multi_class, вот её значения:

  • auto — по умолчанию, автоматически выбирает метод работы по количеству классов в целевом признаке.
  • ovr — для мультиклассовой классификации, обучает сразу несколько моделей и сопоставляет их по методу «Один против всех». С ним вы знакомились в прошлом курсе.
  • multinomial — для мультиклассовой классификации, использует функцию softmax(). Она формирует оценки вероятностей принадлежности объекта к одному из классов.

В задаче ниже не выбирайте метод классификации, доверьтесь автоматическому выбору модели.

Оцените качество модели метриками F1-мера и ROC-AUC. Постройте матрицу ошибок.

import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.metrics import ConfusionMatrixDisplay

# импортируйте класс для модели классификации LogisticRegression
from sklearn.linear_model import LogisticRegression

# импортируйте функции для вычисления ROC-AUC и F1-меры
from sklearn.metrics import roc_auc_score, f1_score

# создание константы RANDOM_STATE
RANDOM_STATE = 42

# добавляем данные из CSV-файла в датафрейм pandas, делим датасет на выборки
df = pd.read_csv('music_genre_4_classes_imbalanced.csv')
X = df.drop(columns='music_genre')
y = df.music_genre

# разделите данные на тренировочную и тестовую выборки 
# зафиксируйте random_state и используйте стратификацию
X_train, X_test, y_train, y_test = train_test_split(
    X, 
    y, 
    random_state=RANDOM_STATE, 
    stratify=y
)

# выполняем подготовку данных функцией, все операции в скрытом прекоде
X_train, X_test = prepare_data(X_train, X_test)

# создайте и обучите модель LogisticRegression на тренировочных данных
# укажите константу random_state
# выполните предсказание на тестовых данных
model = LogisticRegression(random_state=RANDOM_STATE)
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
probas = model.predict_proba(X_test)#[:,1]

# посчитайте и выведите ROC-AUC с усреднением 'ovo'
roc = roc_auc_score(y_test, probas, multi_class='ovo')
print('ROC-AUC =', round(roc,2))

# посчитайте и выведите F1-меру с усреднением 'macro'
f1 = f1_score(y_test, y_pred, average='macro')
print('F1-score =', round(f1,2))

# постройте матрицу ошибок методом from_estimator()
ConfusionMatrixDisplay.from_estimator(model, X_test, y_test)
plt.show()

Результат
ROC-AUC = 0.88
F1-score = 0.61

p1

Модель лучше всего классифицирует рок-музыку. Оно и понятно — она лучше всего представлена в датасете. При этом практически не может определить блюз — наименьший класс по количеству объектов в датасете.