RUBY

[R]3. 게으른 학습: 최근접 이웃 분류/k-NN알고리즘 본문

STUDY/R을 활용한 머신러닝

[R]3. 게으른 학습: 최근접 이웃 분류/k-NN알고리즘

RUBY_루비 2020. 8. 22. 00:00

-최근접 분류기를 정의하는 주요개념과 ‘게으른 학습자‘로 간주되는 이유

-거리를 이용한 두 예시의 유사도 측정방법

-k-NN이라 불리는 유명한 최근접 이웃 분류 적용방법

 


최근접 이웃 분류의 이해

▶최근접 이웃 분류기

:레이블이 없는 예시를 레이블 된 유사한 예시의 클래스로 할당해 분류하는 특징

▶응용분야

-정지 영상 및 동영상에서 광학 글자 인식과 얼굴 인식을 포함하는 컴퓨터 비전 응용

-영화나 음악 추천에 대한 개인별 선호 예측

-특정 단백질 및 질병 발견에 사용 가능한 유전자 데이터의 패턴인식

▶유사한 클래스 유형의 아이템들이 상당히 동질적인 경향을 띨 때

▶개념을 정의하기는 어렵지만 보면 뭔 지 알 때

▶데이터에 잡음이 많고 그룹 간에 명확한 그룹이 없다면 클래스 경계 식별이 어려움

K-NN알고리즘

장점

단점

〮단순하고 효율적

〮모델을 생성하지 않아 특징과 클래스 간의 관계를 이해하는 능력 제약

〮기저 데이터 분포에 대한 가정 없음

〮적절한 k의 선택이 필요

〮훈련 단계가 빠름

〮분류단계가 느림

〮명목 특징 및 누락 데이터를 위한 추가처리 필요

k-NN(Nearest Neighbor)

❶글자 k

:최근접 이웃의 개수를 임의로 사용해도 된다는 변수항목

❷여러 범주로 분류되어 레이블된 예시들로 구성된 훈련 데이터 셋 필요

❸k-NN은 테스트 데이터셋의 레이블이 없는 각 레코드에 대해 훈련 데이터에서 유사도 기준으로 '가장 가까운' k개의 레코드를 찾는다.

❹레이블이 없는 테스트 인스턴스는 k개 최근접 이웃의 대다수 클래스에 배정한다.

거리의 유사도 측정

K-NN알고리즘은 유클리드 거리 사용

유클리드 거리: 두 점을 연결하기 위해 자를 사용할 수 있는 경우에 측정한 거리, 최단 직선로를 의미하는 ‘일직선 거리’로 측정 된다.

EX) 토마토는 과일인가 채소인가 단백질인가

: 오렌지(d=1.4) 에 배정하면 오렌지는 과일이므로 1-NN알고리즘

k=3 인 k-NN알고리즘을 사용하면, 세 개의 최근접 이웃인 오렌지, 포토, 견과가 투표 를 하면 오렌지,포도 3표 중 2표가 과일이므로 토마토는 다시 과일로 분류된다.

적절한 k선택

▶k-NN에 사용할 이웃의 개수는 모델이 미래 데이터에 일반화 되는 능력을 결정

▶훈련에 대한 overfitting 과 underfitting의 균형은 bias-variance tradeoff로 알려진 문제

▶ k를 큰값으로 선택하면,

잡음이 많은 데이터로 인한 영향이나 분산은 감소하지만, 작더라도 중요한 패턴을 무시하는 위험을 감수하는 학습자로 편향될 수 있음

▶k를 1개로 가정하면, 잡음이 있는 데이터나 이상치가 예시의 분류에 과도한 영향을 미침

▶실제 k의 선택은 학습될 개념의 난이도와 훈련 데이터의 레코드 개수에 의존, 관례적으로 k를 훈련 예시 개수의 제곱근으로 두고 시작

ex)15개의 예시 제료 -> 15 제곱근 3.87 =>k=4

 

k-NN사용을 위한 데이터 준비

▶거리 공식이 특정한 측정 방법에 매우 의존적이므로 k-NN알고리즘에 적용하기 전에 표준 범위로 변환된다.

▶특정한 특징 값의 범위가 매우 크면, 거리 측정치는 큰 범위를 갖는 특징에 따라 좌우된다. EX)매운 맛 (1-100만)추가

▶해결책) 특징을 재조정해 각 특징이 거리 공식에 상대적으로 동일하게 기여하도록 범위 줄이거나 늘리기

❶최소-최대 정규화

-0에서 1 사이 범위에 있게 특징 변환

❷Z-점수표준화(z-score standardization)

❸dummy coding

:1은 해당 범주 0은 다른 범주

-더미 코드화된 특징 사이의 거리가 항상 1이거나 0이라는 것

-최소-최대 정규화가 적용된 수치 데이터와 동일한 범위에 속한다.

K-NN알고리즘이 게으른 이유

▶게으른 학습(lazy learning)이라고 하는 이유? 추상화가 일어나지 않아서

▶훈련 데이터를 글자 그대로 저장하기 만 함

▶ 훈련 인스턴스에 많이 의존하기 때문에 instance-based learning(인스턴스 기반 학습), role learning(암기학습)

▶비모수 학습(non-parametric): 인스턴스 기반 학습자는 모델을 만들지 않기 때문에 , 비모수 방법은 기저 데이터에 대해 이론을 생성하지 않아 분류기의 데이터 이용 방법을 이해하기 어렵다

 

K-NN알고리즘으로 유방암 진단

▶게으른 학습(lazy learning)이라고 하는 이유? 추상화가 일어나지 않아서

▶훈련 데이터를 글자 그대로 저장하기 만 함

▶ 훈련 인스턴스에 많이 의존하기 때문에 instance-based learning(인스턴스 기반 학습), role learning(암기학습)

▶비모수 학습(non-parametric): 인스턴스 기반 학습자는 모델을 만들지 않기 때문에 , 비모수 방법은 기저 데이터에 대해 이론을 생성하지 않아 분류기의 데이터 이용 방법을 이해하기 어렵다

 

#유방암 분석

library(readr)
wbcd <- read_csv("R/material/wisc_bc_data.csv")
str(wbcd)

#id특징은 데이터분석에 정보 제공 하지 않으므로 id있는 1열 삭제
wbcd <- wbcd[-1]

#양성: T 357개  음성 M 212개
table(wbcd$diagnosis)

#팩터로 코딩화 
#왜? 팩터는 범주형 데이터를 표현하기 위한 데이터 타입
# R머신러닝 분류기의 목표특징이 팩터로 코딩되는 것
wbcd$diagnosis <- factor(wbcd$diagnosis, levels=c("B","M"),labels =c("Benign","Malignant"))

#round(x,n):x를 소수n자리로 반올림 
#prop.table : 변수의 비율 확인
round(prop.table(table(wbcd$diagnosis)) * 100, digits = 1)   

summary(wbcd[c("radius_mean","area_mean","smoothness_mean")])
#면적의 범위와 매끄러움의 범위가 달라 면적의 영향이 더 커진다. 
#해결위해 정규화한다.

#정규화하는 함수 
normalize <- function(x){
  return ((x - min(x)) / (max(x) - min(x)))
}
          
normalize(c(1,2,3,4,5))
normalize(c(10,20,30,40,50))

#30개의 수치변수를 개별적으로 정규화 하지 않고 이 과정을 자동화하는 R함수 사용 

#lapply(): 리스트를 취해서 각 리스트 항목에 지정된 함수를 적용
#데이터 프레임: 동일한 길이의 벡터들의 리스트
#as.data.frame() :lapple()에서 반환된 리스트를 데이터 프레임으로 변환하는 것 
wbcd_n <- as.data.frame(lapply(wbcd[2:31],normalize))

summary(wbcd_n$area_mean)

#train dataset과 test dataset으로 분리하는 과정 

#train 과 test 
wbcd_train <- wbcd_n[1:469, ]
wbcd_test <- wbcd_n[470:569, ]


#wbcd데이터 프레임의 첫번째 열에 있는 diagnosis 팩터를 가져와서 분리

wbcd_train_labels <- wbcd[1:469, 1]
wbcd_test_labels <- wbcd[470:569, 1]

#class 패키지: 테스트 인스턴스를 분류하기 위한 기본 R함수 제공
#knn(): k-NN 표준 알고리즘 구현 제공, 데이터의 각 인스턴스별로 유클리드 거리 이용하여 식별
# knn(train, test, class, k)
# train: 수치 훈련 데이터를 포함하는 데이터 프레임
# test : 수치 테스트 데이터를 포함하는 데이터 프레임
# class: 훈련 데이터의 각 행에 대한 클래스를 갖는 팩터 백터
#  K: 최근접 이웃의 개수를 가리키는 정수
# 테스트 데이터 프레임의 각 행에 대해 예측된 벡터 반환
install.packages("class")

#훈련데이터 469개 -> 469의 제곱근과 동일한 홀수 -> k=21
#2-범주 결과이므로 홀수를 이용하여 동점 표일 가능성을 제거 

#wbcd_test_pred <- knn(train =wbcd_train, test=wbcd_test , cl=wbcd_train_labels , k=21)
library(class)
wbcd_test_pred <- knn(train = wbcd_train, test = wbcd_test,
                      cl = wbcd_train_labels, k = 21)

library(gmodels)
#필요없는 카이제곱 값 제거
CrossTable( x= wbcd_test_labels, u=wbcd_test_pred,prop.chisq = FALSE)


#scale(): dataframe에 직접 적용할 수 있어 lapply가 필요없다.
#z-점수 표준화 
#사전에 정의된 최솟값, 최댓값이 없기 때문에 극값이 중심 방향으로 축소되지 않는다. 
wbcd_z <- as.data.frame(scale(wbcd[-1]))
summary(wbcd_z$area_mean)

wbcd_train <- wbcd_z[1:469, ]
wbcd_test <- wbcd_z[470:569, ]

wbcd_test_pred <- knn(train = wbcd_train, test = wbcd_test,
                      cl = wbcd_train_labels, k = 21)
print(wbcd_train_labels)
print(wbcd_train)
#예측된 label과 실제 label 비교 
CrossTable(x = wbcd_test_labels, y = wbcd_test_pred,
           prop.chisq = FALSE)

 

Factor(팩터)

Factor는 범주형Categorical 데이터 (자료)를 표현하기 위한 데이터 타입이다.

범주형 데이터란 데이터가 사전에 정해진 특정 유형으로만 분류되는 경우를 뜻한다. 예를 들어, 방의 크기를 대, 중, 소로 나누어 기재하고 있을 때 특정 방의 크기를 ‘대’라고 적는다면 이 값은 범주형 데이터다. 이와 같이 범주형 변수가 담을 수 있는 값의 목록(이 예에서는 대, 중, 소)을 레벨(수준)level이라고 한다. 따라서 범주형 데이터를 저장하는 데이터 타입인 팩터에는 관측된 값뿐만 아니라 관측 가능한 값의 레벨도 나열해야 한다.

범주형 데이터는 또 다시 명목형Nominal순서형Ordinal으로 구분된다. 명목형 데이터는 값들 간에 크기 비교가 불가능한 경우를 뜻한다. 예를 들어, 정치적 성향을 좌파, 우파로 구분하여 저장한 데이터는 명목형이다. 반면 순서형 데이터는 대, 중, 소와 같이 값에 순서를 둘 수 있는 경우를 말한다.

범주형 데이터에 상반하는 개념에는 수치형Numerical 데이터가 있다. 수치형 데이터는 값을 측정하거나 개수를 세는 경우와 같이 숫자로 나온 값을 의미한다. 예를 들어, 방의 크기를 30㎡, 28㎡와 같이 기록하는 경우나 학생들의 성적이 이에 해당한다.

참고: https://thebook.io/006723/ch02/03/06/

브레트 란츠, 윤성진 옮김, 『R을 활용한 머신러닝』, 에이콘출판주식회사(2017)

Comments