- BrainTools - https://www.braintools.ru -
Привет! Меня зовут Владислав Козлов, я тимлид аналитиков Business Security в Авито [1]. Хочу поделиться с вами интересным опытом [2] взаимодействия с LLM, который позволил мне дёшево и быстро проверить свою идею. А заодно — рассказать об интересном алгоритме кластеризации, который мы с моделью придумали и реализовали в виде библиотеки.
Статья не раскроет вам глубин вайбкодинга, не разверзнет бездну понимания ИИ и не явит Истину. Она не о мощных навыках использования LLM, а скорее о личном опыте дешёвого и быстрого прототипирования идеи. Главная её цель — вдохновить читателя не откладывать свои идеи в долгий ящик, а реализовывать и делиться ими с окружающими.
Надеюсь также, что сделанный нами с нейросетью алгоритм окажется полезным для вас.
• Придумал, посоветовался, реализовал — прелести быстрого прототипирования [3]
• Тестируем на игрушечном наборе данных или как много у вас шансов выжить на Титанике [4]
• К чему это я [5]

Вы бывали в ситуации, когда вас посещает очень интересная идея — с одновременным осознанием, что вы никогда её не реализуете? Потому что сейчас на это нет времени, а потом вы её просто забудете.
Именно в такой ситуации я обнаружил себя, когда читал код аналитика из своей команды.
📚 Задача
Нам нужно было выделить кластеры пользователей с характерным поведением [6] и, рассмотрев их внимательнее, сформировать список мошеннических схем. Набор данных — объёмный, с большим количеством самых разных признаков
Есть много способов обрабатывать эти признаки и отбирать те, что стоит использовать для кластеризации. Мысль о том, сколько времени потребует такой анализ, причиняла мне боль [7].
💡 Идея
Я подумал: «Было бы здорово, если б можно было хотя на первом шаге использовать подход, который работает из коробки с категориальными признаками и не чувствителен к выбросам» — и почувствовал, что это звучит знакомо. Звучит как задача для деревьев.
Мысль о деревьях в алгоритмах обучения [8] без учителя навела мой внутренний взгляд на Isolation Forest — алгоритм поиска аномалий, основанный на очень простой, но изящной идее: разбивать случайным образом набор данных на группы и смотреть, как часто каждое наблюдение оказывается отрезанным от большинства.
Те, что отделяются быстрее, скорее всего, сильно отличаются от остальных. Принцип работы Isolation Forest можно увидеть ниже. Я не очень хорош в рисовании, поэтому использовал Gemini. Простите за немногочисленные проблемы с подписями.
Но это — поиск аномалий, а нам нужно уметь находить расстояния между объектами для формирования кластеров. Количество разбиений тут не поможет: оно позволяет судить только о том, насколько объект похож на все остальные.
Но можно разбивать наблюдения на подмножества, случайным образом разделяя фичи. После чего — смотреть как часто два наблюдения оказываются в одном и том же подмножестве. Примерно так:
👨💻 Решение
С этой идеей наперевес я и отправился за советом к LLM. И модель изрядно развила мою идею, предложив интересный подход к решению проблемы оценки похожести объекта. Она посоветовала после получения случайных разбиений вычислять id ячеек как:
cell_id = Σ bj * Kj,
где:
j — номер фичи
b — номер бина
K — количество бинов, на которые бьются фичи
Таким образом, id никогда не повторяются. Эмбеддинг объекта (E) — это список таких id ячеек, в которые он попадал на разных итерациях.
Расстояние между объектами А и Б считается как Hamming Distance [10]. Или просто доля итераций, в которых два объекта попали в разные ячейки. Чем чаще объекты попадают в одну ячейку, тем меньше будет расстояние.
После чего матрицу расстояний может использовать любой алгоритм кластеризации.
5 минут обсуждений, и вуа-ля — я получаю библиотеку [11], которая вполне пригодна как MVP.
И она работает! Не сразу: пришлось исправить пару багов и пройти несколько итераций обсуждений — но работает, и я всё ещё не написал ни строчки кода.
Опробуем подход на датасете, который описывает пассажиров Титаника. Он небольшой и там есть фичи разных типов, что делает его идеальным кандидатом.
Вот какие поля можно анализировать:
PassengerId — уникальный порядковый номер пассажира.
Survived — бинарная целевая переменная: 0 — погиб, 1 — выжил.
Pclass — социально-экономический класс билета: 1-й, 2-й или 3-й. Часто выступает главным индикатором достатка.
Name — полное имя пассажира, включая титул или звание.
Sex — пол пассажира: male / female.
Age — возраст в годах. Для детей младше года указывается дробное значение, например: 0.75 или 1.5. Присутствуют пропуски.
SibSp — количество супругов (husband/wife) и братьев/сестёр (siblings), с которыми путешествует пассажир.
Parch — количество детей (children) и родителей (parents), которые путешествуют с ним.
Ticket — уникальный буквенно-цифровой номер билета.
Fare — стоимость проезда (тариф) в фунтах стерлингов.
Cabin — номер каюты пассажира. Встречается большое количество пропущенных значений.
Embarked — порт, где пассажир сел на корабль. Принимает три значения: C — Шербур (Cherbourg), Q — Куинстаун (Queenstown), S — Саутгемптон (Southampton).
В качестве фич будем использовать только Sex, Age, SibSP, Parch, Fare и Embarked. А Survived и Pclass возьмём, чтобы посмотреть, как они коррелируют с найденными кластерами.
Попробуем просто забросить их в алгоритм без всякой предварительной обработки — прямо рай, легко и удобно:
fc = ForestClusterer(
n_iterations=300,/
n_bins=3,
quantile_cuts=True,
n_clusters=3,
corr_threshold=0.9,
random_state=42,
)
labels = fit_predict(X)
И чудо свершилось, мы получили вполне понятные кластеры:
Кластер 1 состоит почти полностью из женщин, по большей части — с членами семьи. Чем и объясняется высокая доля выживших.
Кластер 2 — с наибольшей концентрацией пассажиров 1 класса. Это, вероятно, объясняет второй результат по доле выживших.
А Кластер 3 — мужчины из 2 и 3 классов, путешествующие в большинстве без близких родственников. У таких пассажиров шансов совсем мало.
Весьма любопытно, что KMeans, обученный на отмасштабированных данных с OneHotEncoding нашёл совсем другие кластеры:
🔵 Кластер 1 — в основном мужчины из 2-го и 3-го классов с ожидаемо малыми шансами на выживание.
🟠 Кластер 2 — более высокая доля женщин, больше пассажиров с членами семьи: более высокие шансы. Но это пассажиры 2-го и 3-го классов, что снижает вероятность выжить.
🟢 Кластер 3 — пассажиры 1 класса, да ещё в основном женщины. Самые высокие шансы.
В целом, датасет не очень хорошо разделён на группы, поэтому внутри относительно плотного облака объекты можно делить по-разному.
Но вот если мы подмешаем немного аномалий, выбросов, сильно отличающихся от остальных наблюдений, то на таком «испорченном» датасете наш алгоритм покажет себя особенно хорошо.
Посмотрим, как Forest Clustering и набор алгоритмов из sklearn выделяют связь кластеров с классом пассажиров.
Используем метрику ARI (Adjusted Rand Index) — она оценивает качество в машинном обучении: насколько алгоритм кластеризации согласуется с истинной разметкой данных — эталонными классами. Метрика устраняет случайные совпадения и позволяет объективно сравнивать разные алгоритмы. Узнать о ней подробнее [13].
Нас мало интересует, как сильно кластеры были связаны с классами до добавления выбросов, скорее — как метрика изменилась после.
Видим, что все алгоритмы, кроме Forest Clustering, показали снижение силы связи. Это говорит о том, что наш подход более устойчив к выбросам, и, следовательно, менее требователен к предварительной обработке данных.
Не воспринимайте эту статью как рекламу алгоритма или библиотеки, я прекрасно понимаю, что и алгоритм имеет аналоги, и библиотека сырая. Это только иллюстрация того, что имея пару часов времени и LLM, можно между делом проверить идею, не написав ни строчки кода.
Более того, можно получить пусть и сырой, но полезный инструмент. В рассмотренном случае он позволяет дёшево разбить данные с помощью нескольких алгоритмов, не думая о выбросах, пропусках и категориях.
Призываю вас не держать идеи в себе и смело экспериментировать!
Если хотите знать больше о работе со сложными продуктами, подписывайтесь на телеграм-канал «Коммуналка аналитиков [15]». Там интересно!
Автор: crazyjedi89
Источник [16]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/35053
URLs in this post:
[1] Авито: https://clc.to/LV3FBg
[2] опытом: http://www.braintools.ru/article/6952
[3] Придумал, посоветовался, реализовал — прелести быстрого прототипирования: #section1
[4] Тестируем на игрушечном наборе данных или как много у вас шансов выжить на Титанике: https://section2
[5] К чему это я: https://section3
[6] поведением: http://www.braintools.ru/article/9372
[7] боль: http://www.braintools.ru/article/9901
[8] обучения: http://www.braintools.ru/article/5125
[9] Тут еще больше контента: https://telegram.me/+ShQQPXymxoViNzFi
[10] Hamming Distance: https://www.ibm.com/think/topics/hamming-distance
[11] библиотеку: https://pypi.org/project/forest-clustering/
[12] Жми сюда!: https://clc.to/MDY_jw
[13] Узнать о ней подробнее: https://deepmachinelearning.ru/docs/Machine-learning/Clustering-evaluation/External-clustering-evaluation-measures
[14] Кликни здесь и узнаешь: https://clc.to/vtMlJg
[15] Коммуналка аналитиков: https://t.me/analyticsavitotech
[16] Источник: https://habr.com/ru/companies/avito/articles/1078084/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1078084
Нажмите здесь для печати.