Студия разработки сайтов и приложений

Netspark.ru

Платформа для ботов в Telegram

Ботопотамы

Да что такое этот ваш процентиль

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

Для начала немного определений и полезного матана.

Процентиль P — это такое число, что P% значений в наборе данных меньше или равны этому числу. Например, в наборе [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] число 8 — это 90й процентиль, т.к. 90% чисел в этом наборе меньше или равны 8. Из других примеров, 0й процентиль — может быть вам известен как минимум, 100й процентиль — максимум, а 50й процентиль вы можете знать под именем медиана.

Процентили — это, кстати, частный случай квантилей. Квантили — примерно то же самое, только выражены не в процентах, а в долях от 0 до 1 (ну или в вероятностях, если так удобнее). Процентиль — это квантиль*100%.

Численный показатель (не)годности статьи или заметки в блог можно было бы назвать (не)адеквантилем.

Итак, нафига нам эти процентили.

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

Очевидно, эти частные случаи, если их мало, не имеют особого отношения к нашему исследованию. Однако если мы добавим их в базу данных как 10 минут и 0 минут, они во-первых испортят нам график, во-вторых если мы захотим посчитать среднее время, эти маленькие и нулевые значения будут влиять на показатель. Тогда как они явно не получены в нормальных условиях.

Другой пример — тот, что я упомянул в начале. Мы измеряем пинг, а конкретно в данном случае — время, с которым у нас загружается заданная страница наблюдаемого сайта. И здесь нас ждет такая же проблема: иногда может икнуть сеть, иногда пинг может попасть в момент, когда на сервере бэкап делается. Тогда при среднем пинге в 500мс пики в 10 секунд нам испортят весь график:

no-percentile.png

Хотя при этом они аномальны и значения для нашей оценки нормальной работы сервера не имеют. Хорошо бы их отбросить поэтому.

Усреднение по какому-то окошку с таким набором данных работать будет не очень хорошо: сглаживающая фильтрация и пики не до конца уберет, и полезные значения «размоет» (попробуйте сглаживающий фильтр к фото применить — резкость сразу снизится).

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

Когда-то для удаления дефектов с видеопотока кое-каких устройств мы применяли медианную фильтрацию. Брали для каждого пикселя окошко 3x3, находили медиану — то есть центральный элемент в отсортированном массиве — и заменяли им. Это позволило прибить помехи площадью меньше половины окна и в то же время не уменьшало резкость, поскольку медиана — настоящее значение в изображении, а не среднее. Ну и, как мы выше уточнили, медиана — это есть 50й процентиль.

Ну а в данном случае мы берем допустимый (с нашей точки зрения) процентиль, например 97й, и соответственно, исключаем из набора значения, которые больше. Для набора в 2000 чисел это будет, очевидно, 60 значений (3%). Уберем их и график станет более наглядным:

percentile.png

Конкретно в моем случае монитор написан на Ларавеле. Вот так можно отфильтровать коллекцию $ping (в которой ключ это дата измерения, а значение — собственно, пинг) по 97му процентилю:

$percentile_index = intval(0.97 * ($ping->count() - 1));
$percentile = $ping->sort()->values()->get($percentile_index);
$ping = $ping->filter(fn($item) => $item <= $percentile);

И да, это совсем не оптимальное решение: теоретически для процентилей P > 50% частичная сортировка, то есть получение 100% - P отсортированных максимумов, будет работать быстрее полной сортировки массива. А для P > 90% и на достаточно больших массивах — быстрее на порядки. Но в моем случае выборка не очень большая и происходит не очень часто, так что я для простоты оставил такой код.

В анализе метрик всякого там хайлоада — типа на каком RPS наши серверы убьются — процентили применяются довольно часто. Запомните это понятие, чтобы не зависнуть вдруг при встрече с ним.

Обсуждение

Чтобы обсудить заметку, написать комментарий, или просто связаться, заходите в Телеграм-канал. У нас весело и всем рады!

Также меня можно найти в Хвиттере, VC.ru, Дзене, или Тенчате.