51. KNN(K-Nearest Neightbor) 예제


r

Overview

KNN(K-Nearest Neightbor) 알고리즘은 범주를 모르는 어떠한 데이터에 대해 분류되어 있는 가장 유사한 예제의 범주로 지정해주는 알고리즘이다.

그 예제 코드를 살펴본다.


예제 1

library(class)

data <- read.csv('likelyhood.csv', stringsAsFactors = F)
str(data)
summary(data)
dim(data)
colnames(data)

# 1~13행까지 8열만 빼고 training
trainX <- data[c(1:13), -8]
trainX

trainY <- data[c(1:13), 8]
trainY

testX <- data[c(14:14), -8]
testX

testY <- data[c(14:14), 8]
testY

# kSize : 최근접 이웃의 수를 명시하는 정수
kSize_1 <- floor(sqrt(nrow(trainX)))
kSize_1 <- ifelse(kSize_1 %% 2 == 0, kSize_1 + 1, kSize_1)
kSize_1

# K-Nearest Neighbor Algorithm
# 범주를 모르는 데이터에 대해 분류되어 있는 가장 유사한 예제 범주로 지정
# knn func : class Package
# prob : 확률값 표시 여부
knnPred_1 <- knn(train = trainX, test = testX, cl = trainY, k = kSize_1, prob = T)
knnPred_1



예제 2

data <- read.csv('saleinfo.csv', stringsAsFactors = F)

head(data)
str(data)
summary(data)
dim(data)
colnames(data)
rownames(data)

# 파일 이름 : saleinfo.csv
# 쇼핑몰 고객 정보를 담고 있는 엑셀 파일과
# KNN을 이용하여 고객의 구매 여부를 예측해보세요.
# 
# 컬럼 : 나이,월급,구매여부
# 나이와 월급 정보를 이용하여 구매 여부를 파악하는 예시이다.
# 나이와 월급은 Z 표준화 변환을 수행하여 테스트 하도록 한다.
# 테스트할 데이터 정보는 다음과 같다.
test_x <- data.frame(age=44, income=400)

data$age <- scale(data$나이)
data$income <- scale(data$월급)

# 표준화 변환 공식 Z = (X - mu) / sigma
data$age2 <- (data$나이 - mean(data$나이)) / sd(data$나이)
data$age2

train_x <- data[,c(4, 5)]
train_x

train_y <- data[,c(3)]
train_y

kSize_1 <- floor(sqrt(nrow(data)))
kSize_1 <- ifelse(kSize_1 %% 2 == 0, kSize_1 + 1, kSize_1)
kSize_1

knnPred_1 <- knn(train = train_x, test = test_x, cl = train_y, k = kSize_1, prob = T)
knnPred_1



예제 3

# 파일 이름 : customers.csv
# 쇼핑몰에서 회원의 구매 시간대별 소비 지수를 조사한 데이터 셋이 있다.
# 이 정보를 이용하여 해당 구매 고객에 대한 성별을 판단해 보는 
# KNN 모델을 만들어 보세요.
# 이 모델에 대하여 다음 데이터를 이용하여 성별을 예측해보도록 하세요.
# 남자 또는 여자일 확률도 구해 보세요.

data <- read.csv('customers.csv', stringsAsFactors = F)

head(data)
str(data)
summary(data)
dim(data)
colnames(data)
rownames(data)

test <- data.frame(아침 = 12, 점심 = 20, 저녁 = 50, 주말 = 91)

data$mo <- scale(data$아침)
data$lu <- scale(data$점심)
data$di <- scale(data$저녁)
data$we <- scale(data$주말)

trainX <- data[,c(6:9)]
trainX

trainY <- data[,c(5)]
trainY

kSize_1 <- floor(sqrt(nrow(data)))
kSize_1 <- ifelse(kSize_1 %% 2 == 0, kSize_1 + 1, kSize_1)
kSize_1

knnPred_1 <- knn(train = trainX, test = test, cl = trainY, k = kSize_1, prob = T)
knnPred_1


예제 4

library(ggplot2)
library(class)
library(dplyr)

data <- read.csv('food_list.csv', header = T)
head(data)
str(data)
summary(data)
dim(data)
colnames(data)
rownames(data)

tomato <- data.frame(ingredient = 'tomato', sweetness = 6, crunchiness = 4)

ggplot(data = data, aes(x = sweetness, y = crunchiness)) + geom_point(aes(color = class, shape = class), size = 5)

# k = 1로 테스트
trainX <- select(data, sweetness, crunchiness)
testX <- select(tomato, sweetness, crunchiness)
trainY <- data$class

tmt <- knn(train = trainX, test = testX, cl = trainY, k = 1, prob = T)
tmt

# 여러 항목 같이 확인하기(k = 3)
ingredient <- c('grape', 'green bean', 'orange', 'tomato')
sweetness <- c(8, 3, 7, 6)
crunchiness <- c(5, 7, 3, 4)

unknown <- data.frame(ingredient, sweetness, crunchiness)
unknown

testX <- unknown[, c('sweetness', 'crunchiness')]
res <- knn(train = trainX, test = testX, cl = trainY, k = 3, prob = T)
res


예제 5

library(class)
library(gmodels)

data <- read.csv("wisc_bc_data.csv", stringsAsFactors = F)
str(data)
dim(data) # [1] 569  32

data <- data[-1]
unique(data$diagnosis)
table(data$diagnosis)

data$diagnosis <- factor(data$diagnosis, levels = c("B", "M"), labels = c("Benign", "Malignant"))
table(data$diagnosis)
357/(357+212)

colnames(data)

# wdbc.names.txt 파일 참고
summary(data[c("radius_mean", "area_mean", "smoothness_mean")])
# radius_mean       area_mean      smoothness_mean
# Min.   : 6.981   Min.   : 143.5   Min.   :0.05263
# 1st Qu.:11.700   1st Qu.: 420.3   1st Qu.:0.08637
# Median :13.370   Median : 551.1   Median :0.09587
# Mean   :14.127   Mean   : 654.9   Mean   :0.09636
# 3rd Qu.:15.780   3rd Qu.: 782.7   3rd Qu.:0.10530
# Max.   :28.110   Max.   :2501.0   Max.   :0.16340

# min-max Algorithm
normalize <- function(x) {
  return((x - min(x)) / (max(x) - min(x)))
}

dataN <- as.data.frame(lapply(data[2:31], normalize))
dataN

summary(dataN[c("radius_mean", "area_mean", "smoothness_mean")])
# # radius_mean       area_mean      smoothness_mean 
# Min.   :0.0000   Min.   :0.0000   Min.   :0.0000  
# 1st Qu.:0.2233   1st Qu.:0.1174   1st Qu.:0.3046  
# Median :0.3024   Median :0.1729   Median :0.3904  
# Mean   :0.3382   Mean   :0.2169   Mean   :0.3948  
# 3rd Qu.:0.4164   3rd Qu.:0.2711   3rd Qu.:0.4755  
# Max.   :1.0000   Max.   :1.0000   Max.   :1.0000

# 데이터 분리
# 하단 100개를 테스트 용으로 사용
testingRow <- 100
totRow <- nrow(dataN)
trainingRow <- totRow - testingRow

dataTrain <- dataN[1:trainingRow,]
dataTest <- dataN[(trainingRow + 1):totRow,]

dataTrainLabels <- data[1:trainingRow, 1]
dataTestLabels <- data[(trainingRow + 1) : totRow, 1]

kSize_1 <- floor(sqrt(trainingRow))
kSize_1 <- ifelse(kSize_1 %% 2 == 0, kSize_1 + 1, kSize_1)
kSize_1

knnPred <- knn(train = dataTrain, test = dataTest, cl = dataTrainLabels, k = kSize_1, prob = T)
knnPred

table(knnPred, dataTestLabels)

CrossTable(x = dataTestLabels, y = knnPred, prop.chisq = F)

dataTrain <- dataN[1:trainingRow,]
dataTest <- dataN[(trainingRow + 1) : totRow, ]

for(idx in c(5, 11, 15, 21, 27)) {
  kSize_1 <- idx
  knnPred <- knn(train = dataTrain, test = dataTest, cl = dataTrainLabels, k = kSize_1, prob = T)
  CrossTable(x = dataTestLabels, y = knnPred, prop.chisq = F)
  mTable <- table(knnPred, dataTestLabels)
  accuracy <- (mTable[1,1] + mTable[2,2]) / sum(mTable)
  accuracy <- round(accuracy, 2)
  print(accuracy)
  cat('--------------------------------------------------------------')
}







© 2019. by RaP0d

Powered by aiden