Имея две выборки данных 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 — это широко используемая одночисловая статистика, которая измеряет, насколько переменная сместилась между двумя распределениями.
Он делает это, объединяя два распределения в группы и сравнивая процент элементов в каждой из групп, в результате чего получается одно число, которое вы можете использовать, чтобы понять, насколько разные совокупности.
Шаги:
- Имея образцы D1 и D2 и переменную (характеристику) feat, мы хотели бы измерить сдвиг.
- Отсортируйте значения умений для D1 и D2.
- Разделите переменный feat на 10 групп.
- Рассчитайте % записей подвига в каждой 10-й группе на образце D1. (Исходный процент или контрольный процент)
- Рассчитайте % записей подвига в каждой 10-й группе на образце D2. (Новый процент)
- Вычислите разницу между шагом 3 и шагом 4. (Исходный%-Новый%)
- Возьмем натуральный журнал (шаг 3 / шаг 4) log(Initial%/New%)
- Умножьте Step5 и Step6 = PSI для этой группы.
- Суммируйте 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, чтобы обнаружить дрейф между выборками одномерного наблюдения, например: дрейф признаков.
- Используйте тест на основе модели, чтобы обнаружить дрейф между выборками набора данных, состоящими из нескольких функций.