Class weight balanced: веса классов и проверка модели

Когда классы несбалансированы, веса меняют обучение. Рассчитайте веса по train и сравните precision и recall двух моделей на одной неизменённой валидации.

Программа курса «Классическое машинное обучение: алгоритмы и практика на Python».

Расчёт сбалансированных весов и оценка моделей на неизменённой валидации

Что уже дано

Проверяющая система выполняет решение в среде Python 3.12 с предустановленными библиотеками numpy и scikit-learn. Вспомогательные глобальные объекты или файлы заранее не создаются. Проверяющие тесты напрямую вызывают функцию compare_class_weight_pipelines с аргументами в виде массивов numpy.ndarray.

Что нужно сделать

Реализуйте функцию compare_class_weight_pipelines(X_train, y_train, X_val, y_val).

Функция принимает:

  • X_train: двумерный числовой массив np.ndarray формы (n_train, n_features) — матрица признаков обучающей выборки;
  • y_train: одномерный целочисленный массив np.ndarray длины n_train с бинарными метками классов 0 и 1 (гарантируется наличие обоих классов);
  • X_val: двумерный числовой массив np.ndarray формы (n_val, n_features) — матрица признаков валидационной выборки;
  • y_val: одномерный целочисленный массив np.ndarray длины n_val с бинарными метками классов 0 и 1 (гарантируется наличие обоих классов).

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

  1. Расчёт весов классов:
    Вычислите сбалансированные веса классов строго по обучающей выборке y_train по формуле:

    где , , а — число объектов класса в y_train.
    Сформируйте одномерный массив sample_weights длины n_train типа float64, в котором -й элемент равен весу класса соответствующей метки .

  2. Обучение двух конвейеров:
    Постройте два независимых конвейера sklearn.pipeline.Pipeline со стандартным шагом масштабирования ('scaler', StandardScaler()) и классификатором ('clf', LogisticRegression(max_iter=2000, random_state=34)):

  • конвейер без весов: LogisticRegression(class_weight=None, max_iter=2000, random_state=34);
  • конвейер со сбалансированными весами: LogisticRegression(class_weight='balanced', max_iter=2000, random_state=34).
    Оба конвейера обучаются методом fit(X_train, y_train) строго на обучающей выборке без изменения валидационных данных.
  1. Оценка на неизменённой валидации:
    Для каждого обученного конвейера получите вероятности принадлежности к положительному классу на X_val (через predict_proba), сформируйте бинарные предсказания по фиксированному порогу (predictions = (probabilities >= 0.5).astype(int)) и рассчитайте метрики качества:
  • точность precision_score(y_val, predictions, zero_division=0);
  • полноту recall_score(y_val, predictions, zero_division=0).
  1. Формат возвращаемого значения:
    Функция возвращает словарь следующей структуры:
    {
        "class_weights": {0: float, 1: float},
        "sample_weights": np.ndarray,  # одномерный массив float64 формы (n_train,)
        "unweighted": {
            "precision": float,
            "recall": float,
            "val_probabilities": np.ndarray  # одномерный массив float64 формы (n_val,) с P(y=1)
        },
        "balanced": {
            "precision": float,
            "recall": float,
            "val_probabilities": np.ndarray  # одномерный массив float64 формы (n_val,) с P(y=1)
        }
    }
    

Ввод и вывод

Стандартный ввод stdin не используется. Печатать через print в stdout ничего не нужно. Проверяющая система вызывает функцию compare_class_weight_pipelines напрямую и сверяет ключи словаря, типы и числовые значения возвращённых объектов.

Пример использования

import numpy as np

X_train = np.array([[1.0, 2.0], [2.0, 1.0], [1.5, 2.5], [8.0, 9.0]])
y_train = np.array([0, 0, 0, 1])
X_val = np.array([[1.2, 1.8], [7.5, 8.5]])
y_val = np.array([0, 1])

res = compare_class_weight_pipelines(X_train, y_train, X_val, y_val)
print("Weights:", res["class_weights"])
print("Unweighted recall:", res["unweighted"]["recall"])
print("Balanced recall:", res["balanced"]["recall"])

Результат:

Weights: {0: 0.6666666666666666, 1: 2.0}
Unweighted recall: 1.0
Balanced recall: 1.0
РешениеPython

Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.

Отправьте решение, чтобы увидеть результаты тестов.

Связанные задачи