С начала 2018 года я пытался решать различные повседневные проблемы в своей работе, используя простые модели глубокого обучения (см. Глубокое обучение по структурированным данным Часть 1 и Часть 2).

Проблема, с которой я столкнулся, - прогнозирование времени до облегчения (TTR) для билетов в службу поддержки Db2 - имела преимущество в виде разумно сбалансированных этикеток. Входные данные распределились следующим образом:

  • 0 этикеток - TTR ≤ 1 день: 39%
  • 1 этикетка - TTR ›1 день: 61%

На меньшем наборе данных (~ 180 тыс. Записей) точность превысила 73% с матрицей недоразумений, которая выглядела так:

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

У меня возникли проблемы, когда я попытался применить тот же подход к проблеме с очень несбалансированными значениями меток: предсказать, вызовет ли билет поддержки Db2 вызов Duty Manager (DM).

Клиенты звонят дежурному менеджеру, когда у них есть билет, требующий дополнительного внимания. У нас есть дежурные менеджеры, работающие в режиме реального времени, круглосуточно каждый день в году. Когда поступает вызов DM, дежурный менеджер быстро проверяет состояние заявки с командой, работающей над ней, а затем перезванивает клиенту, чтобы просмотреть план заявки. Звонки в прямом эфире мешают клиентам и создают дополнительную работу для моей команды. Было бы здорово для всех, если бы мы могли предсказать, что для тикета будет поступать звонок DM, и предпринять активные действия (например, получить дополнительную помощь для аналитика, работающего над тикетом), чтобы не было необходимости в звонке DM в первый раз. место.

Лишь небольшая часть билетов генерирует вызовы Duty Manager, поэтому значения меток во входных данных для проекта прогнозирования DM искажены: более 98% имеют метку = 0 (без вызова DM).

Когда мы пытаемся запустить модель на этих входных данных, точность выглядит великолепно:

Однако матрица путаницы для набора проверки говорит о другом - модель никогда не предсказывает правильно вызов DM на наборе проверки:

Это серьезная проблема - ценность модели заключается в точном прогнозировании вызовов DM. Если модель никогда не предсказывает звонки DM правильно, она бесполезна.

Не имея четкого представления о том, как назвать проблему, с которой я столкнулся, я провел несколько наивных поисков и наткнулся на 8 тактик борьбы с несбалансированными классами в вашем наборе данных машинного обучения. Когда я прочитал эту прекрасную статью, я почувствовал себя немного подавленным - средства правовой защиты выглядели как много работы. По крайней мере, у моего заклятого врага было имя: Парадокс точности. Между прочим, я думаю, это было бы крутой подписью к фильму из франшизы Миссия невыполнима.

К счастью, более тщательный поиск позволил обнаружить то, что я искал - простой способ решить парадокс точности в Керасе.

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

zero_weight = 1.0
one_weight = 72.8

Затем обновите оператор компиляции, включив опцию weighted_metrics:

model.compile(loss="binary_crossentropy", optimizer=optimizer, metrics=["accuracy"], weighted_metrics=["accuracy"])

Наконец, обновите инструкцию fit, включив опцию class_weight со значениями для каждого значения метки:

modelfit = model.fit(X_train, dtrain.target, epochs=epochs, batch_size=BATCH_SIZE
         , validation_data=(X_valid, dvalid.target),class_weight = {0 : zero_weight, 1: one_weight}, verbose=1)

Повторно прогнав модель с этими изменениями, мы получим другую картину точности:

И матрица путаницы для набора проверки показывает, что модель на самом деле иногда правильно предсказывает вызовы DM:

Еще предстоит проделать большую работу, чтобы добиться адекватной точности предсказания вызовов DM, но, по крайней мере, теперь у меня есть достойная отправная точка и шанс получить модель, которая будет полезна.