Всем привет! Меня зовут Дима Лунин, я аналитик в компании Авито. В этой статье я расскажу про критерий Манна-Уитни и проблемы при его использовании.  Этот критерий очень популярен. Во многих компаниях и на обучающих курсах рассказывают про два его важных преимущества: Манн-Уитни — непараметрический собрат T-test. Если данные в A/B-тесте не из нормального распределения, то T-test использовать нельзя. На помощь приходит Манн-Уитни. Манн-Уитни — робастный критерий. В данных часто бывает много шумов и выбросов, поэтому T-test неприменим по соображениям мощности, чувствительности или ненормальности данных. А Манн-Уитни в этот момент отлично срабатывает и более вероятно находит статистически значимый эффект. Если вы анализировали A/B-тест, где вас интересовал прирост или падение какой-то метрики, то наверняка использовали критерий Манна-Уитни. Я хочу рассказать про подводные камни этого критерия, и почему мы в компании его не используем. А в конце вы поймёте, откуда взялся такой холиварный заголовок :) План статьи такой: Я теоретически покажу, что проверяет Манн-Уитни и почему это не имеет ничего общего с ростом медиан и среднего значения. А ещё развею миф, что Манн-Уитни проверяет эту гипотезу: На примере искусственных и реальных данных продемонстрирую, что Манн-Уитни работает не так, как вы ожидаете. Его «преимущество» в большем числе прокрасов относительно T-test, и это — главный минус этого критерия, поскольку прокрасы ложные. Расскажу про логарифмирование метрики и продемонстрирую, почему это плохая идея. Покажу теоретические случаи, когда Манн-Уитни применим и его можно использовать для сравнения средних. Отвечу на вопрос: как тогда жить и какой критерий использовать для анализа A/B-тестов. Предлагаю ответить на вопрос: можем ли мы проверять равенство средних или медиан в тесте и в контроле с помощью критерия Манна-Уитни? Или проверять, что одна выборка «не сдвинута» относительно другой выборки? Или, если на языке математики: Например, у нас в A/B-тесте две выборки: U[−1, 1] — равномерное распределение от −1 до 1 U[−100, 100] — равномерное распределение от −100 до 100 Про эти два распределения мы знаем, что у них равны средние и медианы, и что они симметричны относительно 0. Кроме того, вероятность, что сгенерированное значение в первой выборке будет больше значения во второй выборке, равна 1/2. Или, если сформулировать математически, P(T > C) = 1/2, где T и C — выборки теста и контроля. Я хочу проверить, работает ли здесь корректно Манн-Уитни. Для этого запустим эксперимент 1000 раз и посмотрим на количество отвержений нулевой гипотезы у критерия. Подробнее про этот метод можно прочесть в моей статье про улучшение A/B тестов. Если бы критерий Манна-Уитни работал как надо и проверял одну из гипотез, то по определению уровня значимости он бы ошибался на этих тестах в 5% случаев, с некоторым разбросом из-за шума.   Проверим корректность примера на уровне значимости для T-test критерия: Результат: T-test здесь корректно работает: он ошибается в 5% случаев, как и заявлено. А значит, пример валиден. Манн-Уитни ошибается в 11% случаев. Если бы он проверял равенство средних, медиан или P(T > C) = 1/2, то должен был ошибиться только в 5%, как T-test. Но процент ошибок оказался в два раза больше. А значит, что эти гипотезы неверны для Манна-Уитни: Этот метод можно использовать для проверки только такой гипотезы: Этот критерий проверяет, что выборки теста и контроля взяты из одного распределения. Если он считает, что выборки из разных распределений — отвергает гипотезу. Это обычный критерий однородности. Для демонстрации корректности я предлагаю снова запустить 1000 раз тесты, но выборки теста и контроля в этот раз взяты из одного распределения: U[-100, 100] (равномерное распределение от -100 до 100). Результаты:  Манн-Уитни не может проверить ничего, кроме равенства распределений. Этот критерий не подходит для сравнения средних или медиан.  Разберёмся, почему Манна-Уитни нельзя применять для сравнения средних, медиан и P(T > C) = 1/2. Для начала посмотрим на статистику, которая считается внутри критерия: Для неё считаются те критические области, при попадании в которые статистики U критерий отвергнется. Отсюда видно, что: Манн-Уитни учитывает расположение элементов выборок относительно друг друга, а не значения элементов. Поэтому он не может сравнивать математические ожидания, если он даже не знает абсолютные значения элементов выборки. Гипотеза H_0: P(T > C) = 1/2 неверна для данного критерия. Если P(T > C) = 1/2, то мат. ожидание EU = (произведение размера выборок) / 2. Но при равенстве распределений мат ожидание статистики U будет точно таким же. Почему критерий не сработал на примере с 2 разными равномерными распределениями U[-1, 1] VS U[-100, 100], но сработал при сравнении распределений U[-100, 100] VS U[-100, 100]? Суть в том, что мы не знаем распределение статистики U. Когда тест и контроль из одного распределения, мы знаем, что статистика U распределена нормально. Но если это не так, то теорема перестаёт работать. Тогда мы не знаем, как распределена статистика U, и не можем посчитать p-value. По этой же причине критерий не может проверять равенство медиан. Мы рассмотрели, почему Манна-Уитни не следует применять для проверки равенства средних, медиан и смещённости распределений. Но на практике его все равно часто применяют для этих гипотез, особенно для равенства средних. Что плохого может случиться в этом случае? Правда ли, что в таком случае мы завысим ошибку 1 рода в 2 раза и будем ошибаться в 11% вместо 5%? На реальных задачах проблемы Манна-Уитни будут куда серьёзнее, чем завышение alpha в два раза. Все последующие примеры будут основаны на кейсах, которые встречаются на практике в Авито. Я продемонстрирую работу критерия Манна-Уитни на искусственно сгенерированных данных, моделирующих один из наших экспериментов, а потом продемонстрирую результаты на настоящих данных из Авито. Допустим, мы проводим A/B-тест с целью улучшить какую-то метрику. Тогда наше изменение чаще всего приводит к двум ситуациям: Части пользователей понравилось наше воздействие и нулей в выборке стало меньше. Например, мы дали скидки на услуги, платящих пользователей стало больше.  Другой части пользователей не понравилось наше изменение и они оттекли по метрике — стало больше нулей. В обоих этих случаях я покажу, как может работать критерий.  Я разберу этот кейс на примере выдачи скидки. Количество платящих пользователей увеличилось, но ARPPU упал. Наша ключевая метрика — выручка. Мы хотим понять: начнём ли мы больше зарабатывать со скидками. Или выросло ли ARPU, математическое ожидание выручки — что эквивалентно.  Сразу зафиксируем проверяемую гипотезу о равенстве средних: H0 — средний чек не изменился или упал vs. H1 — средний чек вырос. Мы уже знаем, что Манн-Уитни может ошибаться в этой задаче. Но насколько? Искусственно насимулируем эксперимент, который мог бы произойти в реальности. В этот раз это будут не два равномерных распределения, а что-то более приближенное к реальности, и что вы сможете проверить самостоятельно, запустив код. Пусть распределение ненулевой части метрики подчиняется экспоненциальному распределению. Для выручки это хорошее приближение. Пусть нашими скидками мы увеличили число платящих пользователей на 5%. Изначально в контроле было 50% нулей. Половина пользователей ничего не покупали на сайте. В тесте стало 55% платящих пользователей. Раньше пользователь в среднем платил 7 рублей, а сейчас из-за скидки он платит 6 ₽, скидка была примерно 15%. Тогда математическое ожидание выручки в контроле было 3.5 ₽ (7 * 0.5), а в тесте — 3.3 ₽ (6 * 0.55). То есть платящих пользователей стало больше, а средний чек упал. А значит, верна H0 и процент ложноположительных срабатываний не может быть больше 5% у корректного критерия. Для проверки мы снова запустим тест 1000 раз и проверим, что здесь покажут T-test с Манном-Уитни.  Демонстрация результатов: Результат: Процент принятий гипотезы H1: «средний чек вырос» у T-test около 0: это нормально, так как мы знаем, что на самом деле среднее в тесте упало, а не выросло — критерий корректен. А у Манна-Уитни процент отвержений 32%, что сильно больше 11%, которые были в первом, изначальном примере. Представим, что на ваших настоящих данных была примерно такая же картина. Только в реальности вы не симулировали эксперимент, поэтому не знаете, что ваш средний чек упал. У T-test околонулевой процент обнаружения статистически значимого эффекта. Используя его, вы видите, что он ничего не задетектировал, начинаете использовать критерий Манна-Уитни, и в одной трети случаев обнаруживаете эффект, что среднее увеличилось.  Увидев, что T-test не прокрасился, а Манн-Уитни даёт статистически значимый прирост, многие аналитики доверятся второму критерию и покатят на всех пользователей скидки. И выручка упадёт. Другой вариант: части пользователей не понравилось наше изменение и они ушли. Допустим, мы захотели нарастить количество сделок на Авито. Сделка у нас — событие, когда продавец нашёл покупателя на своё объявление. Для этого мы добавили новые обязательные параметры в объявление и процесс подачи стал сложнее. Часть продавцов отвалилась, зато остальным стало легче: теперь покупателям с помощью фильтров и поиска проще находить подходящие объявления. Осталось понять, нарастили ли мы количество сделок. Например, у нас было 100 продавцов и в среднем они совершали 2 сделки на Авито. После того как мы ввели новые параметры, продавцов стало 70. Оставшимся 30 продавцам наша инициатива не понравилась и они ушли. Теперь на одного продавца приходится по 3 сделки, так как пользователям стало легче находить релевантный товар. Раньше было 200 сделок, а теперь 210. В этот раз все распределения будут взяты не из теоретических соображений, а из реальных данных. Как это сделать, я подробно рассказывал в статье про улучшение A/B-тестов. Я собрал 1000 настоящих А/А-тестов на исторических данных в Авито: взял всех продавцов в разных категориях и регионах за разные промежутки времени и поделил случайно на тест и контроль. Повторил это 1000 раз.  Теперь я хочу простимулировать эффект от ввода новых обязательных параметров в тестовой группе: я моделирую отток пользователей и прирост числа сделок у оставшихся продавцов.  Как именно я это сделал: взял в качестве метрики количество сделок; обнулил число сделок 5 процентам случайных продавцов, как будто они ушли с площадки; у оставшихся пользователей в тестовой группе я домножил количество сделок на некий коэффициент больше единицы. В итоге среднее число сделок на продавца стало больше даже с учетом оттока. В примере выше этот коэффициент равнялся бы 1.5: 2 сделки → 3 сделки. На самом деле количество сделок выросло от введения новых параметров. Да, получились не совсем «реальные» AB-тесты, а лишь приближения к ним. Но в любом случае это наилучшее возможное приближение, где мы знаем реальный эффект. Теперь построим таблицу процента отвержений нулевой гипотезы в зависимости от альтернативы на этих 1000 A/B-тестах:  в тесте количество сделок больше, чем в контроле --//-- меньше, чем в контроле T-test 27% 0.1% Манн-Уитни 6% 80% 🤬 Мы видим, что T-test в 27% случаев отвергает гипотезу в нужную сторону. Манн-Уитни — только в 6% случаев. Как видим, тут мощность (или чувствительность) Манна-Уитни меньше, чем у T-test. Если бы мы поставили корректную гипотезу «количество сделок выросло» для проверки, то мощность Манна-Уитни была бы меньше, чем у T-test. Но если проверять, не уменьшили ли мы количество сделок новыми параметрами, то тут нас поджидает беда: в 80% случаев Манн-Уитни задетектирует эффект.  Если бы мы использовали этот критерий на практике, то Манн-Уитни увидел бы тут отток числа сделок. Тогда в 4 из 5 тестов мы бы не катили новые фильтры на Авито и сделали вывод, что новые параметры при подаче только отбирают у нас контент и не помогают покупателям находить интересующие товары.  Благодаря Манну-Уитни мы делаем неверный вывод о наших данных. 11% ложных прокрасов в 1 примере — это не предел. В реальных A/B-тестах их может быть сильно больше. Вспомним, почему критерий Манна-Уитни популярен: В данных часто бывает много шумов и выбросов, поэтому T-test неприменим по соображениям мощности, чувствительности или ненормальности данных. А Манн-Уитни в этот момент отлично срабатывает и более вероятно находит статистически значимый эффект.  Как видно, это предположение не соответствует действительности: T-test везде показал себе корректно и не делал больше ложноположительных прокрасов, чем должен был. А как это происходит и почему на самом деле критерий корректен, вы можете прочесть всё в той же статье про улучшение A/B-тестов. Манн-Уитни нас не спасает, а делает только больше ложноположительных прокрасов. С тем же успехом можно кидать монетку и отвергать гипотезу, если выпала решка. Во втором кейсе монетка ошиблась бы в 50% случаев, а Манн-Уитни ошибается в 80%. Здесь же кроется самая главная беда этого критерия: Манн-Уитни сильно чаще обнаруживает эффект, чем T-test. Именно поэтому этот критерий стал популярен у аналитиков. Когда есть выбор: проглотить «горькую» пилюлю и получить не статистически значимые результаты с помощью T-test; поверить критерию Манну-Уитни, что эффект на самом деле есть; то хочется верить последнему. И в этот момент аналитики ошибаются. Поэтому мы в Авито не используем критерий Манна-Уитни. Это, конечно, всё хорошо, но я рассмотрел два специфических случая, когда метрика конверсии не сонаправлена с финальной метрикой. Например, в примере со скидками: конверсия в покупку выросла, а среднее по выручке упало. Кажется, что более частая картина, когда конверсия выросла и ARPU выросло. В этом случае, вы могли бы вместо проверки прироста ARPU перейти к проверке роста конверсий — менее шумной метрике. Но, к сожалению, вы не знаете, так ли это на самом деле, поэтому вы не можете полагаться на это :( А значит два примера выше вполне могут иметь место в реальности. Ещё Манна-Уитни любят применять для медиан. Здесь также можно привести примеры, почему это невалидно. В этом случае я советую пользоваться Bootstrap, который корректно работает на больших выборках. Или реализовать критерий из этой статьи. Для работы с выбросами в данных часто советуют идею логарифмирования метрики. Алгоритм состоит из двух частей: применим y := log(x + 1); к новым логарифмированным метрикам «y» применим T-test.  Зачем используют этот метод? Когда в данных есть выбросы, метрика очень шумная и дисперсия в данных огромная. А при логарифмировании выбросы исчезают и все данные становятся примерно одинаковыми. Проверим критерий на том же искусственном примере что и ранее.  Результат лучше, чем у Манна-Уитни: количество отвержений не в ту сторону всего 15% вместо 38%. Но это всё ещё значит, что этой штукой пользоваться нельзя! Почему этот критерий неверен — рассмотрим на примере выборки из трёх элементов: a, b, c. Метрика, которая нас интересует — это среднее (a + b + c) / 3. Именно её рост или падение мы хотим задетектировать. При логарифмировании мы считаем метрику (abc) ^ 1/3, или среднее геометрическое. Среднее и среднее геометрическое — разные метрики, поэтому критерий ошибается.  С точки зрения бизнеса логика такая: прирост более мелких значений в такой метрике сильнее детектируется, чем прирост у больших значений. Например: Раньше значение метрики было 0, а сейчас 2. log(2 + 1) - log(1) ≈ 1.09 Раньше значение метрики было 1000, а сейчас 2000. log(2001) - log(1001) ≈ 0.69 То есть, прирост метрики на 2 даёт больший вклад, чем прирост метрики на 1000. Поэтому у нас и получается фигня при использовании критерия. Но все выбросы при этом становятся меньше и поэтому критерий имеет лучшую мощность. Если тестируемая фича полностью сдвигает выборку на некий коэффициент theta или масштабирует выборку на некий параметр theta (theta > 0), то критерий Манна-Уитни применим, и он будет верно оценивать направление сдвига математического ожидания. Попробуем рассуждать в более общем случае. Если вы знаете, что ваше тестируемое изменение полностью сдвинуло функцию распредления в тесте, то можно использовать критерий Манна-Уитни. То есть, если возможны только три варианта: Тогда вы можете использовать критерий Манна-Уитни. Что значит функция распределения F больше функции распределения G? Это верно, если в любой точке x: F(x) > G(x). Итого: если воздействие хоть как-то повлияло на юзеров и функция распределения полностью сдвигается, вы можете использовать критерий Манна-Уитни. То же самое вы можете сделать, если одно распределение будет доминировать над другим. Правда вот как вы будете уверены, что у вас именно такая ситуация? Я утверждаю, что если  F_T доминирует над F_C, то: P(C < T) <= 1/2, а значит статистика Манна-Уитни будет смещена от нормального состояния ET < EC Сначала покажем второй факт: Где первый переход следует из свойств мат. ождидания, а неравество следует из того, что в любой точке x: F_T(x) > F_C(x). А значит 1 - F_T(x) < 1 - F_C(x).  Так что если Манн-Уитни умеет верно детектировать, какое распределение доминирует над другим, то он умеет правильно детектировать рост или падение мат. ожидания. И здесь как раз нам поможет первый факт. Докажем, что P(C < T) <= 1/2. Тогда это значит, что статистика Манна-Уитни при таком доминировании всегда будет смещена только в одну сторону. А значит, если односторонний критерий Манна-Уитни отвергся => ET < EC. То есть Манн-Уитни умеет проверять прирост/падение средних при сдвиге распределений. А теперь одно из распределений будет доминировать над другим: когда вы сдвигаете распределение или масштабируете его, то у вас как раз один из случаев, описанных выше. Поэтому вы можете в этих случаях пользоваться критерием Манна-Уитни. Вопрос: каким образом вы будете уверены, что у вас именно такой эффект от воздействия? Если вы можете привести пример реальной задачи в бизнесе с таким эффектом от тестируемого изменения — жду вас в комментариях к статье :)  Даже если вы знаете, что у вас именно будет такой эффект, вместо Манна-Уитни я бы предложил использовать критерий однородности Колмогорова-Смирнова, который также может смотреть односторонние альтернативы и показывать направление сдвига мат. ожидания. Только в этот момент: мощность у Колмогорова-Смирнова при сдвиге или масштабировании метрики не меньше, чем у Манна-Уитни. А где-то даже больше. вы точно знаете, что изначальная гипотеза у вас — равенство распределений, а не странные интерпретации, присущие Манну-Уитни. А значит, у вас меньше шанс неправильно осознать результаты. На втором пункте я предлагаю остановиться: я сравню Манна-Уитни и Колмогорова-Смирнова по мощности — в случае сдвига выборки в тесте и в случае масштабирования.  Как видим, выиграл Колмогоров-Смирнов. А теперь посмотрим на случай, когда происходит масштабирование. На экспоненциальном распределении разницы в мощности не было обнаружено — можете сами провести эксперимент и убедиться. Поэтому ради интереса я взял исторические данные Авито, создал 1000 тестов и помножил выручку в тесте на коэффициент больше единицы. Примерно то же самое мы делали во втором кейсе ранее, но без обнуления метрики у части пользователей. И здесь Колмогоров-Смирнов победил. А поэтому вопрос к вам: зачем использовать критерий Манна-Уитни? Лучше попробуйте критерий Колмогорова-Смирнова. Итого, Манн-Уитни:  Это критерий однородности. Все остальные интерпретации нулевой гипотезы неверны. В реальных задачах этот критерий неприменим. Если вы начнете его использовать, то он обнаружит статистически значимый эффект в большем числе случаев, чем у T-test. Только после этого неверно говорить о приросте математического ожидания или медианы в тесте относительно контроля. И именно частые прокрасы критерия Манна-Уитни делают его самым опасным и таким популярным критерием для анализа A/B-тестов. Логарифмирование метрики при этом тоже не работает. Если вы точно знаете, что ваше воздействие сдвинуло вашу выборку или отмасштабировало её на некий параметр, то вы можете использовать Манна-Уитни. Но зачем, если есть критерий Колмогорова-Смирнова, который мощнее? И главное: в реальности такой ситуации не бывает в бизнесовых задачах. А если вы знаете такие примеры, то будет очень интересно пообщаться с вами. Если есть вопросы, желание обсудить статью, да и вообще любая реакция, то жду вас в комментариях! Предыдущая статья: Сколько нужно времени, чтобы переписать объявление?  Аналитик