- POSTECH에서 제공하는 MOOC 중, 머신러닝기법과 R프로그래밍 Ⅰ 과정입니다.
Ⅹ. k-인접기법과 판별분석
1. k-인접기법
- k-nearest neighbor
분류(Classification)
분류(Classification): 지도학습(Supervised Learning)
- 타겟범주를 알고 있는 데이터로 분류 규칙을 생성하고 새로운 데이터를 특정 범주에 분류하는 기법
군집화(Clustering): 비지도학습(Unsupervised Learning)
- 독립변수들의 속성을 기반으로 객체들을 그룹화하는 방법
k-인접기법
k-인접방법 (kNN): k개의 가장 가까운 이웃을 사용해서 분류하는 방법
- 거리만 고려하거나, 거리에 따라 가중치를 부여하는 2가지 방법
- 사용되는 변수에 결측치가 있는 경우, 미리 처리하고 수행해야 함
- k개의 인접한 관측치의 다수 범주로 할당하는 방법
최적 k는?
- k가 너무 크면 데이터 구조를 파악하기 어렵고, 너무 작으면 과적합(overfitting) 위험이 있음
- 교차검증(Cross-validation)으로 정확도가 높은 k를 선정
장점
- 단순하며 효율적
- 데이터 분산을 추정할 필요가 없음
- 빠른 훈련 단계
단점
- 모델을 생성하지 않음
- 느린 분류 단계
- 많은 메모리 필요
- 결측치는 추가 작업 필요
kNN 수행을 위한 패키지 설치
1
2
3
4
5
6
7# packages
# install.packages("class") #no weighted value knn
# install.packages("gmodels") #검증에 사용되는 cross table을 위한 패키지
# install.packages("scales") #for graph
library(class)
library(gmodels)
library(scales)train/test 데이터 분할(cross-validation)
1
2
3
4
5# read csv file
iris <- read.csv("data/week10_1/iris.csv")
# head(iris)
# str(iris)
attach(iris)1
2
3
4
5
6
7
8
9
10
11
12
13
14# training/ test data : n=150
set.seed(1000, sample.kind="Rounding")
N=nrow(iris)
tr.idx=sample(1:N, size=N*2/3, replace=FALSE)
# attributes in training and test
iris.train<-iris[tr.idx,-5]
iris.test<-iris[-tr.idx,-5]
# target value in training and test
trainLabels<-iris[tr.idx,5]
testLabels<-iris[-tr.idx,5]
train<-iris[tr.idx,]
test<-iris[-tr.idx,]kNN 수행과 결과
- kNN 함수: knn(train=학습데이터, test=검증데이터, cl=타겟변수, k= )
1
2
3# knn (5-nearest neighbor)
md1 <- knn(train=iris.train,test=iris.test,cl=trainLabels,k=5)
md1
- kNN 함수: knn(train=학습데이터, test=검증데이터, cl=타겟변수, k= )
kNN(k=5)의 결과: 정확도
1
2
3# accuracy of 5-nearest neighbor classification
CrossTable(x=testLabels,y=md1, prop.chisq=FALSE)
# x: 타겟변수의 실제값, y: 타겟변수의 예측값결과 해석
- 정확도: 47/50 → 94%
- versicolor를 virginica로 오분류(2개)
- virginica를 versicolor로 오분류(1개)
- 오분류율: 3/50 → 6%
2. k-인접기법: 가중치
kNN에서 최적 k 탐색
- 최적 k의 탐색: 1 to nrow(tran_data)/2 (여기서는 1 to 50)
1 | # optimal k selection (1 to n/2) |
1 | # minimum k for the highest accuracy |
- 결과 해석
- k=7에서 정확도(.98)가 가장 높음
- 최종 kNN 모형 (k=7)
1
2
3#k=7 knn
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)의 결과: 그래픽
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16# graphic display
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는 분류가 잘 되지 않음
Weighted kNN
거리에 따라 가중치를 부여하는 두 가지 알고리즘이 존재
1
2
3# Weighted KNN packages
# install.packages("kknn") # weighted value knn
library(kknn)k=5, distance=1
1
2
3
4
5
6
7# weighted knn
md2 <- kknn(Species~., train=train, test=iris.test, k=5, distance=1, kernel="triangular")
md2
# to see results for weighted knn
md2_fit<-fitted(md2)
md2_fitcross table로 오분류율 보기
1
2# accuracy of weighted knn
CrossTable(x=testLabels,y=md2_fit,prop.chisq=FALSE,prop.c=FALSE)k=7, distance=2로 옵션 변경 결과
1
2
3
4
5
6
7
8# weighted knn (k=7, distance=2)
md3<-kknn(Species~., train=train,test=iris.test,k=7,distance=2,kernel="triangular")
md3
# to see results for weighted knn
md3_fit<-fitted(md3)
md3_fit
# accuracy of weighted knn
CrossTable(x=testLabels,y=md3_fit,prop.chisq=FALSE,prop.c=FALSE)3. 판별분석 Ⅰ
판별분석
데이터 마이닝 분류 기법 중 하나
객체를 몇 개의 범주로 분류
범주를 가장 잘 구분하는 변수 파악 및 범주간 차이를 가장 잘 표현하는 함수 도출
- 피셔(Fisher) 방법
- 의사결정이론
- 선형판별분석(LDA; Liner DA): 정규분포 분산-공분산 행렬이 범주에 관계 없이 동일한 경우
- 이차판별분석(QDA; Quadratic DA): 정규분포의 분산-공분산 행렬이 범주별로 다른 경우
예제 데이터
1
2# install.packages("gmodels") #crosstable
library(gmodels)train / test 분할
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20# read csv file
iris<-read.csv("data/week10_3/iris.csv")
attach(iris)
# training/ test data : n=150
set.seed(1000,sample.kind="Rounding")
N=nrow(iris)
tr.idx=sample(1:N, size=N*2/3, replace=FALSE)
# attributes in training and test
iris.train<-iris[tr.idx,-5] # 독립변수 4개 포함한 100개 데이터
iris.test<-iris[-tr.idx,-5] # 독립변수 4개 포함한 50개 데이터
# target value in training and test
trainLabels<-iris[tr.idx,5] # 학습데이터의 타겟변수
testLabels<-iris[-tr.idx,5] # 검증데이터의 타겟변수
train<-iris[tr.idx,]
test<-iris[-tr.idx,]LDA함수: lda(종속변수~독립변수, data=학습데이터이름, prior=사전확률)
- 사전확률(prioir probability): 원인 A가 발생할 확률인 P(A)와 같이, 결과가 나타나기 전에 결정되어 있는 확률
1
2
3# install the MASS package for LDA
# install.packages("MASS")
library(MASS)1
2
3# Linear Discriminant Analysis (LDA) with training data n=100
iris.lda <- lda(Species ~ ., data=train, prior=c(1/3,1/3,1/3)) # .의 의미: 전체 데이터를 사용하겠다(4개)
iris.lda
- 사전확률(prioir probability): 원인 A가 발생할 확률인 P(A)와 같이, 결과가 나타나기 전에 결정되어 있는 확률
결과 해석
Coefficients ~
첫 번째 범주 판별 함수: LD1 = 0.89 Sepal.Length + 1.71 Sepal.Width - 2.15 Petal.Length - 2.91 Petal.Width
두 번째 범주 판별 함수: LD2 = -0.11 Sepal.Length - 2.23 Sepal.Width + 0.74 Petal.Length - 2.39 Petal.Width
LD1이 between-group variance의 99%를 설명
LD2가 between-group variance의 1%를 설명
검증 데이터에 LDA 결과를 적용하여 범주 추정
1
2
3# predict test data set n=50
testpred <- predict(iris.lda, test)
testpred결과 해석
- $class: 추정 범주
- 세 개 범주의 사후 확률(posterior probability)을 구한 후, max 값의 범주로 할당
정확도 산정: 오분류율(검증데이터)
1
2# accuracy of LDA
CrossTable(x=testLabels,y=testpred$class, prop.chisq=FALSE)결과 해석
- 정확도: 49/50 → 98%
- 오분류율: 1/50 → 2%
퀴즈
iris.lda <- lda(Species ~ ., data=train, prior=c(1/2,1/4,1/4)) # .의 의미: 전체 데이터를 사용하겠다(4개)
iris.lda
testpred <- predict(iris.lda, test)
testpred
CrossTable(x=testLabels,y=testpred$class, prop.chisq=FALSE)
testpred1 <- round(testpred$posterior, 2) id=150
4. 판별분석 Ⅱ
선형판별분석 vs 이차판별분석
LDA | QDA |
---|---|
분산-공분산 행렬이 범주 관계 없이 동일한 경우 | 분산-공분산 행렬이 범주별로 다른 경우 |
(+) 적은 파라미터 사용, 낮은 분산 | (-) 많은 파라미터 사용, 높은 분산 |
(-) 낮은 유연성 | (=) 높은 유연성 |
이차판별분석(QDA)
모집단 등분산 검정
- 분산-공분산 행렬이 범주별로 다른 경우, 이차판별분석 실시
Box’s M-test
- 귀무가설: 모집단의 분산-공분산 행렬이 동일
- 대립가설: 모집단의 분산-공분산 행렬이 동일하지 X
등분산 검정을 위한 패키지: biotools
1
2
3# install.packages("biotools")
library(biotools)
boxM(iris[1:4], iris$Species)결과 해석
- p-value~0: p-value는 거의 0에 가까움
- 귀무가설(등분산 가정)이 기각 → QDA 실시
QDA 함수
qda(종속변수~독립변수, data=학습데이터이름, prior=사전확률)
1
2
3# Quadratic Discriminant Analysis (QDA)
iris.qda <- qda(Species ~ ., data=train, prior=c(1/3,1/3,1/3))
iris.qda추가 설명
- prior은 경우에 따라 다르게 줄 수 있음
- 독립변수에 대한 그룹별 평균값
검증 데이터에 QDA 결과를 적용하여 범주 추정
1
2
3# predict test data set n=50
testpredq <- predict(iris.qda, test)
testpredq결과 해석
- $class: 추정 범주
- 세 개 범주의 사후 확률(posterior probability)을 구한 후, max 값의 범주로 할당
- 정확도 산정: 오분류율(검증데이터)
1
2# accuracy of QDA
CrossTable(x=testLabels,y=testpredq$class, prop.chisq=FALSE) - 결과 해석
- 선형판별로 했을 때와 동일(단, 데이터가 많아지면 결과가 다르게 나올 수 있음)
- Partition Plot
1
2
3
4
5# partimat() function for LDA & QDA
# install.packages("klaR")
library(klaR)
partimat(as.factor(iris$Species) ~ ., data=iris, method="lda")
partimat(as.factor(iris$Species) ~ ., data=iris, method="qda")