Кейс 1. Классификация клиента по поведению
В этом кейсе мы разберём один из самых простых и наглядных сценариев применения алгоритма k-ближайших соседей – классификацию пользователя на основе его поведения на сайте. Пример намеренно упрощён, чтобы внимание было сосредоточено не на инфраструктуре, а на логике принятия решения.
Этот кейс хорошо иллюстрирует ключевую идею k-NN: мы не строим глобальную модель поведения всех пользователей, а принимаем решение локально – по тем, кто больше всего похож на текущего клиента.
Цель кейса
Цель этого кейса – показать:
как поведенческие признаки превращаются в точки в пространстве признаков
как считается расстояние между пользователями
как из ближайших соседей получается итоговое решение
почему k-NN легко реализовать вручную и почему он так полезен для обучения интуиции
Сценарий
Представим, что у нас есть сайт или онлайн‑сервис, и мы хотим грубо сегментировать пользователей по уровню вовлечённости. Для каждого пользователя мы знаем всего два признака:
количество посещений за месяц
среднее время, проведённое на сайте за одно посещение (в минутах)
На основе этих данных мы хотим отнести пользователя к одному из двух классов:
casual – заходит редко и ненадолго
engaged – заходит часто и проводит на сайте много времени.
Никакой сложной бизнес‑логики здесь нет – это учебный пример, в котором поведение пользователя описывается как точка на плоскости
Подготовка данных
Начнём с небольшого обучающего набора данных. Каждый элемент состоит из вектора признаков и метки класса.
Здесь:
каждый пользователь – это точка вида [visits, avgTime]
$query– пользователь, которого мы хотим классифицировать$k = 3означает, что мы будем учитывать трёх ближайших соседей
Если представить эти данные графически, то мы получим облако точек на плоскости, где одни точки помечены как casual, а другие как engaged.
Метрика расстояния
Чтобы определить, какие пользователи "похожи" друг на друга, нам нужна метрика расстояния. В этом кейсе используется классическое евклидово расстояние:
Математически это расстояние между двумя точками на плоскости. Интуитивно оно отвечает на вопрос: насколько далеко один пользователь находится от другого с учётом обоих признаков сразу.
Важно заметить, что в реальных задачах такие признаки почти всегда нужно нормализовать. В нашем примере масштабы признаков близки, поэтому искажение расстояний невелико. Поэтому здесь мы этого не делаем специально – чтобы код оставался максимально прозрачным.
Поиск k-ближайших соседей
Теперь для нового пользователя мы считаем расстояние до каждого элемента обучающего набора:
После сортировки по расстоянию в $neighbors остаются три пользователя, которые ближе всего к нашему запросу.
На этом этапе k-NN уже сделал почти всё: он сузил весь датасет до небольшой локальной окрестности.
Голосование соседей
Остаётся принять решение. Для классификации используется простое голосование:
В реальных задачах отдельно обрабатывают ситуацию равенства голосов, например с помощью взвешивания по расстоянию – в нашем примере мы этот этап пропускаем. Далее, каждый сосед "голосует" за свой класс. Побеждает тот класс, который встречается чаще всего среди ближайших соседей.
В нашем случае большинство (два из трёх) ближайших пользователей относятся к классу engaged, поэтому именно его мы и получаем в качестве предсказания.
Почему решение является локальным
Ключевой момент этого кейса в том, что:
мы не использовали все данные целиком (использовали только ближайших соседей)
мы не строили явную глобальную границу между классами
мы не делали предположений о форме распределения
Решение было принято строго локально – на основе трёх ближайших пользователей в пространстве признаков.
Если бы $query находился в другой области плоскости, даже при том же самом датасете результат мог бы быть другим.
Выводы
Этот кейс показывает, почему k-NN считается одним из самых честных алгоритмов машинного обучения:
его легко реализовать вручную
каждое вычисление можно объяснить
результат напрямую связан с данными, а не со скрытыми параметрами модели
Поняв этот пример, вы уже интуитивно сможете понять, как работают более сложные алгоритмы, которые тоже опираются на понятия близости, соседства и локальной структуры данных – просто делают это менее явно.
В следующих кейсах мы расширим эту идею на регрессию и посмотрим, как тот же самый принцип реализуется для неё.
Чтобы самостоятельно протестировать этот код, установите примеры из официального репозитория GitHub или воспользуйтесь онлайн-демонстрацией для его запуска.
Last updated