K-найближчий-сусід з безперервними та бінарними змінними


10

У мене є набір даних із стовпцями a b c(3 атрибути). aє чисельною і безперервним в той час як bі cкатегорично кожен з двома рівнями. Я використовую метод K-Найближчих сусідів для класифікації aта bввімкнення c. Отже, щоб можна було виміряти відстані, я перетворюю свій набір даних, видаляючи bта додаючи b.level1і b.level2. Якщо спостереження iмає перший рівень у bкатегоріях, b.level1[i]=1та b.level2[i]=0.

Тепер я можу вимірювати відстані у своєму новому наборі даних: a b.level1 b.level2

З теоретичної / математичної точки зору: Чи можете ви виконати K-найближчий сусід (KNN) як з двійковими, так і безперервними даними?

Я використовую FNNпакунок у R та функціюknn()


У мене поруч немає досвіду KNN, але я не бачу, як двійкова змінна може бути корисною для встановлення відстаней. Мені цікаво, чому ви схиляєтесь до такого підходу.
rolando2

Тому що я не бачу кращого способу порівняння числової змінної з категоріальною змінною. Не соромтеся запропонувати кращий підхід :)
k.dkhk

Відповіді:


11

Це добре, поєднуючи категоричні та безперервні змінні (функції).

Так чи інакше, теоретичного підґрунтя для такого методу, як k-NN, не так багато. Евристичний полягає в тому, що якщо дві точки близькі один до одного (за деякою відстані), то вони мають щось спільне з точки зору виходу. Може так, може, ні. І це залежить від відстані, яку ви використовуєте.

У вашому прикладі ви визначаєте відстань між двома точками (a,b,c) і (а',б',c') як от :

  • візьміть відстань у квадраті між а і а' : (а-а')2
  • Додати +2, якщо б і б' різні, +0 якщо рівні (тому що ви рахуєте різницю 1 для кожної категорії)
  • Додати +2, якщо c і c' різні, +0 дорівнює (однаково)

Це відповідає даванню ваг неявно кожній особливості.

Зауважте, що якщо а приймає великі значення (наприклад, 1000, 2000 ...) з великою дисперсією, тоді ваги двійкових ознак будуть незначними порівняно з вагою а. Тільки відстань між нимиа і а'дійсно матиме значення. І навпаки: якщоа приймає невеликі значення, наприклад 0,001: враховуватимуться лише бінарні функції.

Ви можете нормалізувати поведінку за допомогою зважування: ділення кожної ознаки на її стандартне відхилення. Це стосується як безперервних, так і двійкових змінних. Ви також можете надати власні переважні ваги.

Зауважте, що функція R kNN () робить це за вас: https://www.rdocumentation.org/packages/DMwR/versions/0.4.1/topics/kNN

В якості першої спроби просто використовуйте в основному норма = істина (нормалізація). Це дозволить уникнути більшості почуттів, які можуть з’явитися при поєднанні безперервних і категоричних рис.


хороша відповідь (+1), проте ви можете згадати, якщо розмірність висока, і є багато дискретних змінних, knn з евклідовою відстані може не працювати добре.
Haitao Du

6

Так, ви, звичайно, можете використовувати KNN як із двійковими, так і безперервними даними, але є деякі важливі міркування, про які слід пам’ятати, роблячи це.

Результати будуть сильно інформовані двійковими розщепленнями щодо дисперсії серед реальних цінностей (для 0-1 масштабованих, невагомих векторів), як показано нижче:

Поділ дійсних і бінарних змінних

Ви можете бачити на цьому прикладі, що найближчі сусіди спостереження за окремими відстанями будуть набагато сильніше інформовані бінарною змінною, ніж шкалою змінної реальної величини.

Крім того, це поширюється на декілька бінарних змінних - якщо ми змінимо одну з реально оцінених змінних на двійкові, ми можемо побачити, що відстані будуть набагато більш поінформованими шляхом узгодження всіх бінарних змінних, ніж у близьких до реальних значень:

Поділ дійсних і бінарних змінних

Ви хочете включити лише критичні бінарні змінні - ви насправді запитуєте "про всі спостереження, які відповідають цій конфігурації бінарних змінних (якщо такі є), які мають найближчі реальні значення?" Це розумна постановка багатьох проблем, які можна було б вирішити з KNN, і дуже погана постановка інших проблем.

#code to reproduce plots:
library(scatterplot3d) 

scalevector <- function(x){(x-min(x))/(max(x)-min(x))}

x <- scalevector(rnorm(100))
y <- scalevector(rnorm(100))
z <- ifelse(sign(rnorm(100))==-1, 0, 1)
df <- data.frame(cbind(x,y,z))

scatterplot3d(df$x, df$z, df$y, pch=16, highlight.3d=FALSE,
              type="h", angle =235, xlab='', ylab='', zlab='')

x <- scalevector(rnorm(100))
y <- ifelse(sign(rnorm(100))==-1, 0, 1)
z <- ifelse(sign(rnorm(100))==-1, 0, 1)
df <- data.frame(cbind(x,y,z))

scatterplot3d(df$x, df$z, df$y, pch=16, highlight.3d=FALSE,
              type="h", angle =235, xlab='', ylab='', zlab='')
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.