R에는 인공 신경망이나 서포트 벡터 머신 등 여러 가지 머신 러닝 기법을 사용할 수 있는 패키지가 나와 있습니다. 데이터 및 통계 분석과 이들이 매우 밀접한 관계를 지니고 있기 때문이죠. 물론 인공지능에서 가장 인기가 좋은 파이선이라는 경쟁자가 있지만, 데이터 분석 및 통계 분석에 최적화된 R 역시 만만치 않은 상대입니다.
이번에는 nnet 패키지를 이용해서 간단한 신경망을 만들어 보겠습니다. nnet은 연속 변수가 아니라 범주형 데이터에 대해서도 다른 별도의 작업 없이 간단하게 분류할 수 있으므로 역시 널리 사용되는 패키지입니다. 뉴럴넷과 마찬가지로 싱글 쓰레드로 작업하며 GPU는 사용하지 않는 최근 기준으로 보면 상당히 단순한 패키지입니다. 하지만 신경망의 기능을 이해하는데는 이렇게 비교적 단순한 쪽이 큰 도움이 될 것입니다.
우선 nnet 패키지를 이용해서 iris 데이터를 분류해 보겠습니다. 이 데이터는 붓꽃의 형태에 따른 분류 데이터로 워낙 유명한 데이터라 기본 예제로 항상 등장하곤 합니다.
require(nnet)
nn <- data="iris," nnet="" pecies="" size="3) </span">->
predict(nn, newdata=iris, type="class")
매우 단순한 방식으로 3개의 은닉층 (size로 지정) 을 지닌 신경망을 만들어봤습니다. nnet (포뮬라, 데이터, 은닉층의 수)가 가장 기본적인 형태이며 예측은 predict(학습시킨 신경망, 테스트할 데이터)가 기본 예측 형태입니다. 그리고 범주형 데이터라는 점을 알려주기 위해 type = "class"라고 지정해 주어야 합니다.
이 신경망은 범주형 자료라도 문제 없이 잘 분류하고 있습니다. 앞서 피마 인디언 데이터를 nnet을 이용해서 분석해 보겠습니다.
library(mlbench)
data(PimaIndiansDiabetes)
pima <- pimaindiansdiabetes="" span="">->
pima<-pima age="" c="" diabetes="" glucose="" mass="" pedigree="" pregnant="" pressure="" span="">-pima>
pima=subset(pima,glucose>0)
pima=subset(pima,pressure>0)
pima=subset(pima,mass>0)
set.seed(1234)
data1<-scale c="" pima="" span="">-scale>
data2<-pima c="" span="">-pima>
data=cbind(data1,data2)
data<-data .frame="" data="" span="">-data>
data$data2<-as .factor="" data2="" data="" span="">-as>
마지막에 연속형 변수가 아니라 범주형 변수라는 점을 인식하기 위해 as.factor를 사용한 점에 주목해야 합니다. 문자가 아니라 숫자형인 경우 연속 변수로 잘못 이해할 수 있습니다.
n = nrow(data)
train <- 600="" n="" sample="" span="">->
test <- data="" span="" train="">->
train <- data="" span="" train="">->
nn <- data2="" data="train," nnet="" size="4) </span">->
nn
data3<-predict nn="" span="" test="" type="class">-predict>
test=cbind(test,data3)
test
test$pred<-ifelse data2="=test$data3,1,0)</span" test="">-ifelse>
table(test$pred)
sum(test$pred)/124
이번에는 4개의 뉴런을 지닌 신경망을 만든 후 그 결과를 data3라는 변수로 저장했습니다. 그리고 맞게 예측한 경우가 얼마나 되는지 보기 위해 test$pred<-ifelse 0="" 1="" data2="=test$data3,1,0)를" nbsp="" span="" test="">-ifelse>
> table(test$pred)
0 1
37 87
> sum(test$pred)/124
[1] 0.7016129
맞게 예측한 경우가 70% 이상으로 뉴럴넷 보다 더 좋은 것 같습니다. 물론 코드도 단순하고 해보면 알겠지만, 속도도 빠릅니다. 뉴런을 세 개로 만들면 어떨까요?
> test$pred<-ifelse data2="=test$data3,1,0)</span" test="">-ifelse>
> table(test$pred)
0 1
34 90
> sum(test$pred)/124
[1] 0.7258065
맞게 분류한 경우가 72.6%로 더 높아졌습니다.
nnet 역시 여러 가지 옵션을 제공할 수 있습니다. 다음에 이를 좀 더 알아보겠습니다.
댓글
댓글 쓰기