От «когда-нибудь» к работающему прототипу: как LLM дала идее шанс. ari.. ari. data science.. ari. data science. Isolation Forest.. ari. data science. Isolation Forest. llm.. ari. data science. Isolation Forest. llm. алгоритм.. ari. data science. Isolation Forest. llm. алгоритм. Алгоритмы.. ari. data science. Isolation Forest. llm. алгоритм. Алгоритмы. Блог компании AvitoTech.. ari. data science. Isolation Forest. llm. алгоритм. Алгоритмы. Блог компании AvitoTech. вайбкодинг.. ari. data science. Isolation Forest. llm. алгоритм. Алгоритмы. Блог компании AvitoTech. вайбкодинг. искусственный интеллект.. ari. data science. Isolation Forest. llm. алгоритм. Алгоритмы. Блог компании AvitoTech. вайбкодинг. искусственный интеллект. кластеризация.. ari. data science. Isolation Forest. llm. алгоритм. Алгоритмы. Блог компании AvitoTech. вайбкодинг. искусственный интеллект. кластеризация. Машинное обучение.. ari. data science. Isolation Forest. llm. алгоритм. Алгоритмы. Блог компании AvitoTech. вайбкодинг. искусственный интеллект. кластеризация. Машинное обучение. прототип.. ari. data science. Isolation Forest. llm. алгоритм. Алгоритмы. Блог компании AvitoTech. вайбкодинг. искусственный интеллект. кластеризация. Машинное обучение. прототип. Прототипирование.

Привет! Меня зовут Владислав Козлов, я тимлид аналитиков Business Security в Авито. Хочу поделиться с вами интересным опытом взаимодействия с LLM, который позволил мне дёшево и быстро проверить свою идею. А заодно — рассказать об интересном алгоритме кластеризации, который мы с моделью придумали и реализовали в виде библиотеки.

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

Надеюсь также, что сделанный нами с нейросетью алгоритм окажется полезным для вас.

Придумал, посоветовался, реализовал — прелести быстрого прототипирования
Тестируем на игрушечном наборе данных или как много у вас шансов выжить на Титанике
К чему это я

От «когда-нибудь» к работающему прототипу: как LLM дала идее шанс - 1

Придумал, посоветовался, реализовал — прелести быстрого прототипирования

Вы бывали в ситуации, когда вас посещает очень интересная идея — с одновременным осознанием, что вы никогда её не реализуете? Потому что сейчас на это нет времени, а потом вы её просто забудете. 

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

📚 Задача

Нам нужно было выделить кластеры пользователей с характерным поведением и, рассмотрев их внимательнее, сформировать список мошеннических схем. Набор данных — объёмный, с большим количеством самых разных признаков 

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

💡 Идея

Я подумал: «Было бы здорово, если б можно было хотя на первом шаге использовать подход, который работает из коробки с категориальными признаками и не чувствителен к выбросам» — и почувствовал, что это звучит знакомо. Звучит как задача для деревьев.

Мысль о деревьях в алгоритмах обучения без учителя навела мой внутренний взгляд на Isolation Forest — алгоритм поиска аномалий, основанный на очень простой, но изящной идее: разбивать случайным образом набор данных на группы и смотреть, как часто каждое наблюдение оказывается отрезанным от большинства. 

Те, что отделяются быстрее, скорее всего, сильно отличаются от остальных. Принцип работы Isolation Forest можно увидеть ниже. Я не очень хорош в рисовании, поэтому использовал Gemini. Простите за немногочисленные проблемы с подписями.

Экстремальные значения роста сразу «бросаются в глаза» алгоритму, а обычные дети сливаются в длинные ветки дерева.
Экстремальные значения роста сразу «бросаются в глаза» алгоритму, а обычные дети сливаются в длинные ветки дерева.

Но это — поиск аномалий, а нам нужно уметь находить расстояния между объектами для формирования кластеров. Количество разбиений тут не поможет: оно позволяет судить только о том, насколько объект похож на все остальные. 

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

Постоянное совместное попадание точек в одни и те же случайные подмножества уменьшает их дистанционный счётчик

Постоянное совместное попадание точек в одни и те же случайные подмножества уменьшает их дистанционный счётчик

👨‍💻 Решение

С этой идеей наперевес я и отправился за советом к LLM. И модель изрядно развила мою идею, предложив интересный подход к решению проблемы оценки похожести объекта. Она посоветовала после получения случайных разбиений вычислять id ячеек как: 

cell_id = Σ bj * Kj

где:

  • j — номер фичи

  • b — номер бина

  • K — количество бинов, на которые бьются фичи

Таким образом, id никогда не повторяются. Эмбеддинг объекта (E) — это список таких id ячеек, в которые он попадал на разных итерациях.

Расстояние между объектами А и Б считается как Hamming Distance. Или просто доля итераций, в которых два объекта попали в разные ячейки. Чем чаще объекты попадают в одну ячейку, тем меньше будет расстояние.

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

5 минут обсуждений, и вуа-ля — я получаю библиотеку, которая вполне пригодна как 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) — она оценивает качество в машинном обучении: насколько алгоритм кластеризации согласуется с истинной разметкой данных — эталонными классами. Метрика устраняет случайные совпадения и позволяет объективно сравнивать разные алгоритмы. Узнать о ней подробнее.

Кликни здесь и узнаешь

Нас мало интересует, как сильно кластеры были связаны с классами до добавления выбросов, скорее — как метрика изменилась после. 

Видим, что все алгоритмы, кроме Forest Clustering, показали снижение силы связи. Это говорит о том, что наш подход более устойчив к выбросам, и, следовательно, менее требователен к предварительной обработке данных.

Слева — абсолютные значения метрики до и после зашумления, справа — изменение ARI

Слева — абсолютные значения метрики до и после зашумления, справа — изменение ARI

К чему это я

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

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

Призываю вас не держать идеи в себе и смело экспериментировать!

Если хотите знать больше о работе со сложными продуктами, подписывайтесь на телеграм-канал «Коммуналка аналитиков». Там интересно!

Автор: crazyjedi89

Источник