Пороговая классификация и выбор порога

Основы пороговой классификации

Пороговая классификация применяется в задачах бинарной классификации, где модель выдаёт вероятность принадлежности объекта к определённому классу. На практике модель возвращает значение в диапазоне [0, 1], которое интерпретируется как вероятность. Для получения итоговой метки класса используется порог — фиксированное значение, сравнение с которым определяет класс:

if (prediction >= threshold) {
    classLabel = 1;
} else {
    classLabel = 0;
}

Значение threshold по умолчанию часто выбирается равным 0.5, однако этот выбор может быть не оптимальным для задач с несбалансированными классами или различными затратами на ошибки первого и второго рода.

Загрузка и использование моделей в Keras.js

Keras.js позволяет запускать модели Keras прямо в браузере. Для бинарной классификации важно корректно загружать веса и архитектуру модели, чтобы получить предсказания в виде вероятностей.

const KerasJS = require('keras-js');

const model = new KerasJS.Model({
  filepath: 'model.bin',
  gpu: true
});

await model.ready();

model.ready() гарантирует, что все веса загружены и модель готова к инференсу.

Получение предсказаний

После подготовки модели входные данные передаются в формате TypedArray. Для одной выборки:

const inputData = new Float32Array([0.2, 0.5, 0.1, 0.9]);
const input = { input: inputData };

const outputData = await model.predict(input);
const probability = outputData.output[0];

probability — это значение в диапазоне [0, 1], которое нужно интерпретировать через порог.

Настройка и выбор порога

Выбор порога зависит от конкретной задачи:

  • Классический порог 0.5 подходит для сбалансированных данных и одинаковых затрат на ошибки.

  • Смещение порога используется для повышения чувствительности или точности:

    • Для уменьшения ложных отрицаний выбирается порог ниже 0.5.
    • Для уменьшения ложных срабатываний выбирается порог выше 0.5.

Подбор порога может быть автоматизирован с использованием метрик:

function findOptimalThreshold(yTrue, yProb) {
  let bestThreshold = 0.5;
  let bestF1 = 0;
  for (let t = 0.1; t <= 0.9; t += 0.01) {
    const predictions = yProb.map(p => p >= t ? 1 : 0);
    const f1 = f1Score(yTrue, predictions);
    if (f1 > bestF1) {
      bestF1 = f1;
      bestThreshold = t;
    }
  }
  return bestThreshold;
}

Функция f1Score вычисляет F1-метрику для конкретного порога, позволяя выбрать оптимальный баланс между точностью и полнотой.

Визуализация зависимости метрик от порога

Для анализа можно построить графики precision–recall или ROC-кривые, чтобы увидеть влияние изменения порога на показатели модели.

const thresholds = [];
const precisions = [];
const recalls = [];

for (let t = 0.1; t <= 0.9; t += 0.01) {
  const predictions = yProb.map(p => p >= t ? 1 : 0);
  const { precision, recall } = precisionRecall(yTrue, predictions);
  thresholds.push(t);
  precisions.push(precision);
  recalls.push(recall);
}

Такой подход позволяет определить порог, при котором достигается желаемый компромисс между точностью и полнотой.

Практическая интеграция в фронтенд

После выбора порога модель можно интегрировать в браузерное приложение. Важные моменты:

  • Использовать TypedArray для передачи данных.
  • Поддерживать асинхронные вызовы await model.predict().
  • Применять выбранный порог для преобразования вероятностей в метки классов.
const finalLabel = probability >= optimalThreshold ? 1 : 0;

Особенности работы с несбалансированными классами

При сильном дисбалансе классов стандартный порог 0.5 часто приводит к смещению в сторону доминирующего класса. Для коррекции применяются:

  • Сдвиг порога в пользу меньшего класса.
  • Взвешивание ошибок при расчёте метрик для подбора оптимального порога.

Использование пороговой классификации в Keras.js позволяет гибко управлять результатами модели в браузере и обеспечивает адаптивность под различные бизнес- и исследовательские задачи.