기본 콘텐츠로 건너뛰기

R을 이용해 간단한 신경망 만들기 (9)




 nnet 패키지를 이용해서 한 가지 더 예제를 시행해 보겠습니다. moonBook 패키지는 국내에서 R 관련 커뮤니티 확산에 큰 기여를 한 문건웅 선생님이 개발한 것으로 여기엔 857명의 협심증, 심근 경색 환자의 데이터인 acs 데이터가 기본 데이터로 포함되어 있습니다. 여기서는 결과값이 3개인 경우 - 불안정 협심증 (unstable angina), 비 ST 상승 심근경색 (NSTEMI), ST 상승 심근경색 (STEMI) - 분류하는 인공 신경망을 만들어 보겠습니다. nnet 패키지는 분류 범주가 여러 개라도 크게 문제 없이 분석이 가능합니다. 하지만 신경망에 넣기 전에 전처리가 필요합니다. 


require(moonBook)
str(acs)
summary(acs)


> str(acs)
'data.frame': 857 obs. of  17 variables:
 $ age             : int  62 78 76 89 56 73 58 62 59 71 ...
 $ sex             : chr  "Male" "Female" "Female" "Female" ...
 $ cardiogenicShock: chr  "No" "No" "Yes" "No" ...
 $ entry           : chr  "Femoral" "Femoral" "Femoral" "Femoral" ...
 $ Dx              : chr  "STEMI" "STEMI" "STEMI" "STEMI" ...
 $ EF              : num  18 18.4 20 21.8 21.8 22 24.7 26.6 28.5 31.1 ...
 $ height          : num  168 148 NA 165 162 153 167 160 152 168 ...
 $ weight          : num  72 48 NA 50 64 59 78 50 67 60 ...
 $ BMI             : num  25.5 21.9 NA 18.4 24.4 ...
 $ obesity         : chr  "Yes" "No" "No" "No" ...
 $ TC              : num  215 NA NA 121 195 184 161 136 239 169 ...
 $ LDLC            : int  154 NA NA 73 151 112 91 88 161 88 ...
 $ HDLC            : int  35 NA NA 20 36 38 34 33 34 54 ...
 $ TG              : int  155 166 NA 89 63 137 196 30 118 141 ...
 $ DM              : chr  "Yes" "No" "No" "No" ...
 $ HBP             : chr  "No" "Yes" "Yes" "No" ...
 $ smoking         : chr  "Smoker" "Never" "Never" "Never" ...


 범주형 데이터는 0,1,2... 식으로 연속 변수는 scale 함수로 정규화 시키고 결측값은 모두 제거하겠습니다. 참고로 acs 데이터에 대해서 알고 싶다면 아래 문서가 도움이 될 것입니다. 




acs$sex1[acs$sex=="Male"]=1
acs$sex1[acs$sex=="Female"]=0

acs$Dx1[acs$Dx=="Unstable Angina"]=0
acs$Dx1[acs$Dx=="NSTEMI"]=1
acs$Dx1[acs$Dx=="STEMI"]=2

acs$DM1[acs$DM=="Yes"]=1
acs$DM1[acs$DM=="No"]=0

acs$HBP1[acs$HBP=="Yes"]=1
acs$HBP1[acs$HBP=="No"]=0

acs$smoking1[acs$smoking=="Smoker"]=0
acs$smoking1[acs$smoking=="Ex-smoker"]=1
acs$smoking1[acs$smoking=="Never"]=2

acs$cardiogenicShock1[acs$cardiogenicShock=="Yes"]=1
acs$cardiogenicShock1[acs$cardiogenicShock=="No"]=0


data<-acs age="" c="" sex1="" smoking1="" span="" x1="">
data<-na .omit="" data="" span="">
data$age<-scale age="" data="" span="">
data$BMI<-scale data="" span="">
data$LDLC<-scale data="" span="">
data$Dx1<-as .factor="" data="" span="" x1="">


 마지막에 Dx1은 범주형이라는 사실을 알려줘야 nnet 패키지에서 인식할 수 있습니다. 100명을 테스트 데이터로 나머지는 학습 데이터로 나누고 노드를 8개로 만들어 신경망을 돌려보겠습니다. 


set.seed(1234)

n = nrow(data)
train <- 651="" n="" sample="" span="">
test <- data="" span="" train="">
train <- data="" span="" train="">


nn <- data="train," nnet="" size="8) </span" x1="">
nn
data3<-predict nn="" span="" test="" type="class">
test=cbind(test,data3)
test

test$pred<-ifelse test="" x1="=test$data3,1,0)</span">
table(test$pred)
sum(test$pred)/100


> test$pred<-ifelse test="" x1="=test$data3,1,0)</span">
> table(test$pred)

 0  1 
47 53 
> sum(test$pred)/100
[1] 0.53



이 신경망에서는 맞게 분류한 경우가 53% 정도였습니다. 그냥 아무렇게나 찍는 것보다는 확률이 높지만, 아주 만족스러운 성능은 아니라고 하겠습니다. 아마도 협심증이나 심근경색이 있는 경우 그 상태가 비슷한 것이 원인일 것 같지만, 학습 데이터에 하나 더 추가해서 신경망의 학습 성적을 높일 수 있을지 모릅니다. 여기서는 심장의 수축 기능을 평가하는 지표인 EF를 하나 더 넣어 보겠습니다. 이 경우 결측값 때문에 전체 관측치의 숫자가 줄어들기 때문에 train의 숫자를 577개로 조정하겠습니다. 


data<-acs age="" c="" sex1="" smoking1="" span="" x1="">
data<-na .omit="" data="" span="">
data$age<-scale age="" data="" span="">
data$BMI<-scale data="" span="">
data$LDLC<-scale data="" span="">
data$EF<-scale data="" span="">
data$Dx1<-as .factor="" data="" span="" x1="">

set.seed(1234)

n = nrow(data)
train <- 577="" n="" sample="" span="">
test <- data="" span="" train="">
train <- data="" span="" train="">


nn <- data="train," nnet="" size="8) </span" x1="">
nn
data3<-predict nn="" span="" test="" type="class">
test=cbind(test,data3)
test

test$pred<-ifelse test="" x1="=test$data3,1,0)</span">
table(test$pred)
sum(test$pred)/100


> table(test$pred)

 0  1 
54 46 
> sum(test$pred)/100
[1] 0.46


 되려 정확히 분류할 가능성이 더 낮아졌습니다. 반드시 학습 데이터가 많다고 좋지는 않다는 점을 보여주는 사례입니다. 가장 최적의 신경망 모델을 찾는 일은 그렇게 간단하지는 않습니다. 

  
 이런 식으로 예제를 바꿔가면서 방법을 익혀나가다 보면 여러 가지 에러를 만나게 되고 이를 해결하는 과정에서 데이터 전처리를 어떻게 하고 신경망을 어떻게 개선해 나가는지를 이해하게 될 것입니다. 기왕 하는 김에 신경망에 대한 이야기를 조금 더 해보겠습니다. 

댓글

이 블로그의 인기 게시물

벨 V-280 Valor 시험 비행 성공

( The V-280 Valor flew for the first time at Bell Helicopter's Amarillo Assembly Center in Texas(Credit: Bell Helicopter/YouTube) )  앞서 소개드린 V-280 발러가 첫 번째 비행 테스트에 성공했다는 소식입니다. V-22 오스프리의 소형화 버전이라고 할 수 있는 V-280 발러는  미 육군의 차세대 헬기 사업인 Future Vertical Lift (FVL)에 입찰을 시도하는 틸트로터기로 현재 미 육군이 주력으로 사용하는 블랙호크 헬기와 비슷한 체급입니다. 다만 틸트로터기인 만큼 최고 속도나 항속 거리면에서 더 유리합니다. 스펙은 이전 포스트를 참조해 주시기   이전 포스트:  https://blog.naver.com/jjy0501/221115245986  (동영상)   V-280 발러는 틸트로터기의 더 대중화 될 수 있을지를 검증하는 중요한 무대가 될 것입니다. V-22 오스프리의 경우 복잡한 구조로 인해 가격이 너무 비싸져서 사실 미국은 몰라도 그 동맹국에 널리 도입되기는 어려운 부분이 있습니다. V-280 역시 가격이 아주 저렴할 것 같지는 않지만, 좀 더 합리적인 대안은 될 수 있을 것 같습니다. 만약 성공적인 결과가 나오면 한국을 포함한 미국의 동맹국에서 도입을 검토할 수 있을지 모르겠다는 생각입니다.   참고  https://newatlas.com/bell-v-280-valor-maiden-flight/52663/

100 테슬라급 자기장 도달

 미국의 로스 알라모스 국립 연구소 (Los Alamos National Laboratory) 에서 과학자들이 지금까지 인간이 개발한 가장 강력한 자기장을 발생시키는 장치 개발에 도전하고 있습니다. 자기장의 세기를 나타내는 방법으로 자기력선의 밀도를 나타내기 위해 단위 면적당 자기력선의 수를 표시하는 단위인 테슬라 (T) 가 있습니다. (1T = 1Wb/㎡  웨버 (Wb) 는 자속의 단위)   의료용으로 사용되는 초전도체를 이용한 MRI 의 경우 1.5 - 3 테슬라급의 강력한 자기장으로 인체 내부를 볼 수 있게 만들지만 과학 연구용으로 이보다 더 강력한 자기장이 필요할 수 있습니다. 최근에 등장한 90 테슬라급 자기장에 이어 이번에 로스 알라모스 국립 연구소에서는 100 테슬라급인 100.75 T 를 실현 했다고 합니다.   이를 구현한 것은 18000 파운드 (8.16 톤 정도) 의 코일과 여기에 에너지를 공급할 1200 메가줄 (Megajoule) 급 모터 제네레이터등의 설비입니다.  (   The 1,200-megajoule motor generator that powers the magnetic pulse.  )  이와 같은 연구를 통해 알아내고자 하는 것은  Quantum Phase transitions and new ultra high field magnetic states Electronic Structure determination Topologically protected states of matter  로 요약할 수 있다고 합니다.   아무튼 수 T 급 MRI 만 해도 자기장의 힘이 엄청난데 100 T 라니 엄청난 자기장이네요. 이는 지구 자기장 세기보다 200만배 강력한 (물론 좁은 범위에서 작용하는 자기장이라 지구 전체...

고대 양서류 이야기 (2) - 악어를 닮은 거대 양서류들

  페름기에는 다양한 양막류가 진화해서 앞서 소개한 육상형 템노스폰딜리는 점차 설 자리를 잃게 됩니다. 하지만 양서류는 본래 자신의 서식지인 물과 습지에서 여전히 번성을 누렸습니다. 당시에는 악어류 같은 대형 양서형 파충류도 없던 시절이었기 때문에 이와 비슷한 생태학적 지위는 여전히 양서류의 몫이었습니다. 이들에 대한 이야기는 제 책인 포식자에서 비교적 간단히 다뤘는데, 오늘은 여기에 대한 보충 설명입니다.  책 정보:  http://book.naver.com/bookdb/book_detail.nhn?bid=13347200 Yes 24:  http://www.yes24.com/24/goods/58772859 11번가:  http://books.11st.co.kr/product/SellerProductDetail.tmall?method=getSellerProductDetail&prdNo=1977867160 알라딘:  http://www.aladin.co.kr/shop/wproduct.aspx?ItemId=134877825 교보문고:  http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9788970447988&orderClick=LAG&Kc= 인터파크 :  http://book.interpark.com/product/BookDisplay.do?_method=detail&sc.prdNo=279593764&sc.saNo=003002003&bid1=search_auto&bid2=detail&bid3=prd_img&bid4=001 영풍문고:  http://www.ypbooks.co.kr/book.yp?bookcd=100843205&gubun=NV ...