KNNClassifier
KNNClassifier — модель классификации, основанная на идее ближайших соседей.
Она не строит формулу и не проводит разделяющую прямую. Вместо этого модель запоминает обучающие объекты, а для нового объекта ищет самые похожие на него примеры.
Если среди ближайших соседей больше объектов одного класса, этот класс и становится предсказанием модели.
Что делает модель
Заголовок раздела «Что делает модель»KNN расшифровывается как k-nearest neighbors — k ближайших соседей.
Например, если нужно определить породу собаки по весу и высоте в холке, модель смотрит, рядом с какими обучающими примерами находится новая собака:
- если рядом больше бульдогов, модель предсказывает
бульдог; - если рядом больше спаниелей, модель предсказывает
спаниель.
Число k задаёт, сколько ближайших соседей учитывается при голосовании.
Пример обучения
Заголовок раздела «Пример обучения»В этом примере модель получает таблицу с двумя признаками: весом и высотой в холке. Целевая переменная — порода собаки.
После обучения мы передаём новый объект: собака весом 20 кг и высотой 38 см. Модель находит пять ближайших соседей и выбирает класс большинством голосов.
uses MLABC;
begin var df := DataFrame.FromCsvText(''' Вес,ВысотаВХолке,Порода 20,33,бульдог 22,34,бульдог 24,35,бульдог 25,36,бульдог 19,35,бульдог 21,35,бульдог 26,34,бульдог 20,36,бульдог 14,39,спаниель 15,40,спаниель 16,41,спаниель 18,42,спаниель 17,43,спаниель 15,38,спаниель 19,40,спаниель 16,40,спаниель ''');
var X := df.ToMatrix(['Вес', 'ВысотаВХолке']); var target := df.EncodeTarget('Порода'); var y := target.Labels;
var model := new KNNClassifier(5); model.Fit(X, y);
var example := Vector([20.0, 38.0]); var pred := model.PredictOne(example);
Println('Предсказанная порода:', target.ClassNames[pred]); Println('Ближайшие соседи:');
var neigh := model.GetNearestNeighbors(example); foreach var n in neigh do Println(target.ClassName(n.Index):10, n.Distance:0:2);end.Вывод:
Предсказанная порода: бульдогБлижайшие соседи: бульдог 2.00 спаниель 2.24 бульдог 3.16 бульдог 3.16 спаниель 4.47Здесь GetNearestNeighbors возвращает ближайшие обучающие объекты. Для каждого соседа хранится:
Index— номер строки в обучающей таблице;Distance— расстояние от нового объекта до этого соседа.
Метод target.ClassName(n.Index) позволяет получить исходное название класса для строки с номером n.Index.
Как принимается решение
Заголовок раздела «Как принимается решение»В примере используется KNNClassifier(5), значит модель смотрит на пять ближайших объектов.
Среди них:
- три бульдога;
- два спаниеля.
Поэтому большинство голосов получает класс бульдог, и модель предсказывает именно его.
Визуализация соседей
Заголовок раздела «Визуализация соседей»Чтобы увидеть работу KNN на графике, можно подключить PlotML и нарисовать обучающие точки, новый объект и линии к ближайшим соседям.
uses MLABC, PlotML;
begin var df := DataFrame.FromCsvText(''' Вес,ВысотаВХолке,Порода 20,33,бульдог 22,34,бульдог 24,35,бульдог 25,36,бульдог 19,35,бульдог 21,35,бульдог 26,34,бульдог 20,36,бульдог 14,39,спаниель 15,40,спаниель 16,41,спаниель 18,42,спаниель 17,43,спаниель 15,38,спаниель 19,40,спаниель 16,40,спаниель ''');
var X := df.ToMatrix(['Вес', 'ВысотаВХолке']); var target := df.EncodeTarget('Порода'); var y := target.Labels;
var model := new KNNClassifier(5); model.Fit(X, y);
var example := Vector([20.0, 38.0]); var neigh := model.GetNearestNeighbors(example);
Plot.XLabel := df.ColumnNames[0]; Plot.YLabel := df.ColumnNames[1]; Plot.Title := 'Бульдоги и спаниели';
Plot.Points(X.Col(0), X.Col(1), y);
var (x0, y0) := (example[0], example[1]);
foreach var n in neigh do begin var (x1, y1) := (X[n.Index, 0], X[n.Index, 1]); var color := Plot.PaletteColor(y[n.Index]); Plot.Point(x1, y1, color); Plot.LineGraph([x0, x1], [y0, y1], color); end;
Plot.Point(x0, y0);end.
На графике цветные точки — обучающие данные, чёрная точка — новый объект. Линии показывают пять ближайших соседей, которые участвуют в голосовании.
Основной гиперпараметр
Заголовок раздела «Основной гиперпараметр»Главный гиперпараметр KNN — количество соседей k.
var model := new KNNClassifier(5);Если k слишком маленькое, модель может слишком сильно реагировать на случайные отдельные точки. Если k слишком большое, модель начинает усреднять слишком много объектов и может хуже различать локальные группы.
Масштаб признаков
Заголовок раздела «Масштаб признаков»KNN использует расстояния между объектами, поэтому масштаб признаков очень важен.
Если один признак измеряется в миллионах, а другой в единицах, большой признак будет почти полностью определять расстояние. В таких случаях перед KNN обычно применяют StandardScaler.
В этом примере оба признака имеют близкие масштабы: вес измеряется десятками килограммов, высота — десятками сантиметров. Поэтому пример можно читать без дополнительного масштабирования.
- Очень простая идея: класс выбирается по ближайшим похожим объектам.
- Хорошо подходит для первых учебных примеров.
- Можно посмотреть, какие соседи повлияли на решение.
- Чувствителен к масштабу признаков.
- Может работать медленнее на больших наборах данных.
- Лишние или шумные признаки могут заметно ухудшать качество.