Имея две выборки данных D1 и D2, мы хотим проверить, взяты ли они из одного и того же распределения P или нет. Если они не из одного и того же дистрибутива, мы обнаружили дрейф между D1 и D2.

Приложения в конвейере машинного обучения:

  • Набор данных поезда и теста взят из одного и того же дистрибутива?
  • Есть ли дрейф этикетки? (метки, наблюдаемые в тестовом наборе по сравнению с рабочим трафиком)
  • Есть ли дрейф модели? (прогнозы, наблюдаемые в тестовом наборе по сравнению с рабочим трафиком)
  • Есть ли дрейф характеристик? (значения функций, наблюдаемые в тестовом наборе по сравнению с трафиком)

Алгоритмы обнаружения дрейфа:

Мы рассмотрим 3 популярных алгоритма:

  • Выборочный тест Колмогорова-Смирнова (КС) 2
  • Индекс стабильности населения
  • Тест на основе модели

Первые два статистических теста KS test и PSI предназначены для одномерных данных (по одному столбцу признаков за раз). Тест на основе модели позволяет нам вычислить дрейф на многомерных данных.

Выборочный тест Колмогорова-Смирнова (КС) 2

Тест KS — это непараметрический тест без распределения: он не делает предположений о распределении данных.

Критерий KS можно использовать для сравнения двух выборок (D1 и D2) одномерных распределений независимо от того, принадлежат ли они к одному и тому же распределению вероятностей (нулевая гипотеза) или нет (альтернативная гипотеза).

Сделано

Шаги :

  • Объединить значения в D1 и D2 в один отсортированный массив
  • Вычислите наблюдаемые кумулятивные функции распределения двух выборок
  • Вычислите их максимальную абсолютную разность. (дрейф)
  • Сравните дрейф › D_crit. [D_crit составляет 95% критического значения]. Если дрейф меньше критического значения, нам не удалось отвергнуть нулевую гипотезу.
  • drift_detected = True, если дрейф › D_crit, иначе False
def cdf(D1):
    return [np.round(st.percentileofscore(D1, value)/100, 1) for value in samp_conc]
def critical_diff(D1, D2):
    return 1.36*np.sqrt(len(D1)**-1 + len(D2)**-1)
def detect_drift(D1, D2) -> bool:
    samp_concat = np.sort(np.concatenate((D1, D2)))
    samp_a_cdf = cdf(D1)
    samp_b_cdf = cdf(D2)
    #compute absolute difference 
    samp_diff = np.abs(np.subtract(samp_a_cdf, samp_b_cdf))
    drift = max(samp_diff) > critical_diff(D1, D2)
    drift_detected = True if drift > critical_diff(D1, D2) else False
    return drift_detected

Индекс стабильности населения (PSI)

PSI — это широко используемая одночисловая статистика, которая измеряет, насколько переменная сместилась между двумя распределениями.

Он делает это, объединяя два распределения в группы и сравнивая процент элементов в каждой из групп, в результате чего получается одно число, которое вы можете использовать, чтобы понять, насколько разные совокупности.

Шаги:

  1. Имея образцы D1 и D2 и переменную (характеристику) feat, мы хотели бы измерить сдвиг.
  2. Отсортируйте значения умений для D1 и D2.
  3. Разделите переменный feat на 10 групп.
  4. Рассчитайте % записей подвига в каждой 10-й группе на образце D1. (Исходный процент или контрольный процент)
  5. Рассчитайте % записей подвига в каждой 10-й группе на образце D2. (Новый процент)
  6. Вычислите разницу между шагом 3 и шагом 4. (Исходный%-Новый%)
  7. Возьмем натуральный журнал (шаг 3 / шаг 4) log(Initial%/New%)
  8. Умножьте Step5 и Step6 = PSI для этой группы.
  9. Суммируйте PSI по всем группам для общего PSI.

PSI будет одним числом с плавающей запятой. Например, 10-процентное изменение во всех 10 сегментах приведет к тому, что PSI превысит 0,2. Пороги зависят от домена.

Обычно используемые интерпретации PSI в финансовой индустрии:

  • PSI ‹ 0,1: существенных изменений нет.
  • PSI ‹ 0,2: умеренное изменение
  • PSI ›= 0,2: значительное изменение

Движение функций:

PSI можно использовать для измерения дрейфа входных признаков (числовых или категориальных).

  • Допустим, f1 — важная функция, которая является входной для развернутой модели M.
  • Произвольная выборка тестовых данных, на которых оценивалась модель M перед развертыванием. Это наш эталонный образец D1.
  • Ежедневно случайным образом проверяйте производственный трафик. (скажем, 10 тысяч образцов). Это Д2.
  • Вычисляйте PSI каждый день и наносите его на график. Каждый раз, когда PSI пересекает пороговое значение (скажем, ≥0,2), срабатывает предупреждение.

Тест на основе модели

Тесты на основе модели используют модель для определения сходства между двумя распределениями данных, скажем, set1 и set2. Он делает это, обучая классификатор отличать примеры от set1 и set2. Если модель имеет высокий ROC-AUC, мы успешно обучили модель, которая подразумевает, что распределения данных значительно различаются.

Шаги :

  • Дан образец D1 и D2, каждый из которых состоит из одного и того же набора атрибутов.
    Если f1, …fk являются атрибутами, пример выглядит как карта f1: v1, f2: v2, …., fk: vk}
    Обратите внимание, что вы можете добавить другие атрибуты в качестве функций, таких как прогнозы, метки и т. д. .
  • Добавьте столбец меток в примеры. Значением метки является источник набора данных: в нашем случае D1 или D2.
  • Объедините D1 и D2, чтобы создать единый набор данных D’. Разделите D’ на разделы обучения/тестирования (например: разделение 90–10).
  • Обучите классификатор на этих данных (скажем, модель M). (Предпочтительны объяснимые простые модели: Random Forest, XGBoost, LR).
  • Сообщите показатели ROC-AUC для тестового раздела.
  • Если показатели ROC-AUC хорошие, например ≥0,9, в наборах данных D1 и D2 наблюдается значительный дрейф.
  • Наиболее важные признаки модели М являются наиболее отличительными признаками и могут помочь в построении дальнейшей интуиции относительно того, почему произошел дрейф.

Что произойдет, если будет обнаружен дрейф?

  • Модель необходимо переобучить или повторно откалибровать, если обнаруживается дрейф модели/дрейф меток/функции.
  • Обнаружение дрейфа является важной частью наблюдаемости и мониторинга машинного обучения.

Подведение итогов:

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