51. KNN(K-Nearest Neightbor) 예제
in Study on R Programming
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('--------------------------------------------------------------')
}