본문 바로가기
공부/R & Python

10-2. k-인접기법(k-Nearest Neighbor) 2(최적 k 탐색과 가중치 k-인접기법)

by 드인 2020. 2. 26.

10-2. k-인접기법(k-Nearest Neighbor) 2

(최적 k 탐색과 가중치 k-인접기법)


6) kNN에서 최적 k 탐색

- 최적 k의 탐색 : 1 to nrow(train_data)/2 (여기서는 1 to 50 까지)

accuracy_k <- NULL
nnum<-nrow(iris.train)/2

for(kk in c(1:nnum))
{
  set.seed(1234)
  knn_k<-knn(train=iris.train,test=iris.test,cl=trainLabels,k=kk)
  accuracy_k<-c(accuracy_k,sum(knn_k==testLabels)/length(testLabels))
}
test_k<-data.frame(k=c(1:nnum), accuracy=accuracy_k[c(1:nnum)])
plot(formula=accuracy~k, data=test_k,type="o",ylim=c(0.5,1), pch=20, col=3, main="validation-optimal k")
with(test_k,text(accuracy~k,labels = k,pos=1,cex=0.7))

min(test_k[test_k$accuracy %in% max(accuracy_k),"k"])

k=7에서 정확도(.98)가 가장 높음

 

-최종 kNN모형 (k=7)

md1<-knn(train=iris.train,test=iris.test,cl=trainLabels,k=7)
CrossTable(x=testLabels,y=md1, prop.chisq=FALSE)

- 정확도 : 49/50 -> 98%

- versicolor를 virginica로 오분류(1개)

- 오분류율 : 1/50 -> 2%

 

kNN(k=7)의 결과-그래픽

plot(formula=Petal.Length ~ Petal.Width,
     data=iris.train,col=alpha(c("purple","blue","green"),0.7)[trainLabels],
     main="knn(k=7)")
points(formula = Petal.Length~Petal.Width,
       data=iris.test,
       pch = 17,
       cex= 1.2,
       col=alpha(c("purple","blue","green"),0.7)[md1]
)
legend("bottomright",
       c(paste("train",levels(trainLabels)),paste("test",levels(testLabels))),
       pch=c(rep(1,3),rep(17,3)),
       col=c(rep(alpha(c("purple","blue","green"),0.7),2)),
       cex=0.9
)

- Petal.width와 Petal.length에 산점도를 그려보면 setosa는 잘 분류됨

- virginica와 versicolor는 분류가 잘 되지 않음

 

7) Weighted kNN

- 거리에 따라 가중치를 부여하는 두 가지 알고리즘이 존재

install.packages("kknn")
library(kknn)
help("kknn")

 

- k=5, distance=1

md2<-kknn(Species~., train=train,test=iris.test,k=5,distance=1,kernel="triangular")
md2

weighted kNN의 결과를 md2로 저장

ighted kNN의 결과를 보기 위해서 fitted함수를 이용 (fitted(md2))

md2_fit<-fitted(md2)
md2_fit

 

CrossTable(x=testLabels,y=md2_fit,prop.chisq=FALSE,prop.c=FALSE)

- 정확도 : 47/50 -> 94%

- versicolor를 virginica로 오분류(2개)

- virginica를 versicolor로 오분류(1개)

 

- k=7, distance=2로 옵션 변경한 결과

md3<-kknn(Species~., train=train,test=iris.test,k=7,distance=2,kernel="triangular")
md3

md3_fit<-fitted(md3)
md3_fit

 

CrossTable(x=testLabels,y=md3_fit,prop.chisq=FALSE,prop.c=FALSE)

- 정확도 : 49/50 -> 98%

- virginica를 versicolor로 오분류(1개)