본문 바로가기

Study/class note

머신러닝 / R 로 신경망 모델 만들기

ㅇ활성화 함수? 신경만의 세포인 뉴런에 입력되는 신호를 다음 신호로 내보낼지 말지(계단함수) 또는 어떠한 크기(시크모이드, 렐루함수)로 내보낼지를 결정하는 함수

 목표 : 들어오는 신호가 역치(임계값)에 넘어서면 중요한 신호이고 역치에 도달하지 않으면 중요하지 않은 신호라는 것을 결정하는 함수

 

문제331. 시그모이드 함수 그래프를 R로 시각화 하시오.

#R
sigmoid <- function(x){ 1/ (1+exp(-x)) }

x <- seq(-10, 10, 0.01)

plot(x, sigmoid(x), type = 'o', cex = 0.5)

문제332. 이번에는 파이썬으로 시그모이드 함수를 만드시오.

#python
def sigmoid(x):
    import numpy as np
    return 1 / (1+np.exp(-x))

문제333. 위의 시그모이드 함수를 가지고 R에서와 같이 파이썬에서도 그래프로 그리시오.

import numpy as np
import matplotlib.pyplot as plt

def sigmoid(x):
    import numpy as np
    return 1 / (1+np.exp(-x))

x = np.arange(-10.0, 10.0, 0.01)
y = sigmoid(x)

plt.plot(x,y)

 

ㅇ시그모이드 함수의 단점? 신경망의 층이 깊어지게 되면 오차가 앞층으로 잘 전달 안되는 현상이 발생함. 오차가 신경망 앞층까지 잘 전달되어야  W(가중치)를 갱신할 수 있게 됨.(기울기 소실문제)

 

그래서 나온게 바로 렐루함수(relu)

> 입력되는 값이 0이거나 음수이면 0을 출력하고 입력되는 값이 0보다 크면 입력되는 값을 그대로 출력하는 함수

#R
relu <- function(x){ifelse(x>0, x, 0)}

relu(4)   # 4
relu(-3)   # 0

 

문제334. 위의 relu함수를 파이썬으로 구현하시오.

#python
def relu(x):
    if x > 0:
        return x
    else:
        return 0
    
relu(4)  # 4
relu(-3) # 0

> 그러나 이 방법으로 그래프를 그릴수는 없음.

 

 

문제335. 위의 relu함수를 파이썬으로 그리시오.

import numpy as np
import matplotlib.pyplot as plt

def relu(x):
    return np.maximum(x,0)
    
x = np.arange(-5, 5, 0.1)
y = relu(x)

plt.plot(x,y)
plt.show()

 

 

 

66 R 로 신경망 모델 만들기 - p.328

 

어떻게 재료를 조합해야 강도가 높은 콘크리트를 만들 수 있을까?

콘크리트의 강도를 예측하는 신경망 만드는 실습

> 자갈, 모래, 시멘트 등을 몇 대 몇 비율로 섞었을 때 어느정도 강도가 나오는지 예측하는 신경망

 

(신경망으로 분류(정상, 암환자)도 할 수 있고 수치예측(집값)도 할 수 있는데 이번 실습은 수치예측)

cement : 시멘트
slag : 슬래그
ash : 분
water : 물
superplastic : 고성능 감수제(콘크리트의 강도를 높이는 첨가제)
coarseagg : 굵은 자갈
fineagg : 잔자갈
age : 숙성시간
strength : 강도(label)

 

#1. 데이터 로드

#2. 결측치 확인

#3. 데이터 정규화

#4. 훈련데이터, 테스트 데이터 분리(8:2)

#5. 모델 설정

#6. 훈련 데이터로 모델 훈련

#7. 신경망 시각화

#8. 테스트 데이터 예측

#9. 모델 성능 평가

#10. 모델 성능 개선

 

#1.데이터 로드
concrete <- read.csv("c:\\data\\concrete.csv")
head(concrete)

nrow(concrete)
ncol(concrete)

#2. 결측치 확인
colSums(is.na(concrete))

#3. 데이터 정규화
normalize <- function(x){
  return( (x-min(x)) / (max(x)-min(x)))
}

concrete_norm <- as.data.frame(lapply(concrete, normalize))
head(concrete_norm)

#4. 훈련데이터, 테스트데이터 분리
library(caret)
set.seed(1)
k <- createDataPartition(concrete_norm$strength, p = 0.8, list = F)
train_data <- concrete_norm[k, ]
test_data <- concrete_norm[-k,]

#5. 모델 설정
install.packages("neuralnet")
library(neuralnet)

#6. 훈련 데이터로 모델 훈련
concrete_model <- neuralnet(formula = strength ~ .,
                            data = train_data)
#7. 신경망 시각화
plot(concrete_model)

0층 : 입력층, 1층 : 은닉층, 2층 : 출력층 -> 2층 신경망으로 구성되어 있음

w0가 가중치라고 보면 됨

 

#8. 테스트 데이터 예측
result <- compute(concrete_model, test_data[, 1:8]) #strength 빼고 데이터 입력
result$net.result

#9. 모델 성능 평가
cor(result$net.result, test_data[,9])  # 0.8246728

> 분류면 정확도로 성능을 확인하는데 수치예측이므로 상관계수로 모델의 성능을 확인함.

 

#10. 모델 성능 개선

위의 신경망은 2층 신경망이었음. 개선방법은 층수를 2층에서 3층으로 늘리고, 은닉층의 뉴런의 갯수도 1개에서 7개로 늘려봅니다.

#10. 모델 성능 개선
set.seed(1)
concrete_model2 <- neuralnet(formula = strength ~ .,
                            data = train_data, hidden=c(5,2))
plot(concrete_model2)

> hidden=c(5,2) 에서 5는 은닉1층의 뉴런수, 2는 은닉2층의 뉴런수

#11. 개선된 모델의 성능 평가
result2 <- compute(concrete_model2, test_data[,1:8])
cor(result2$net.result, test_data[,9])  #0.9413332

0.82에서 약 0.94로 개선됨

  층수 은닉층의 뉴런수 상관관계 개선 방법
model 2층 1개 0.82  
model2 3층 7개 0.94 hidden = c(5,2)

 

문제336. (점심시간 문제) 위의 신경망의 성능을 더 높일 수 있는지 hidden 파라미터를 조정해서 실험하시오. 층수와 뉴런의 갯수를 늘려보시오.

hidden_value <- c()
cor_result <- c()
for (i in 1:10){
  for (k in 1:5){
    set.seed(1)
    concrete_model2 <- neuralnet(formula = strength ~ .,
                                data = train_data, hidden=c(i,k))
    #plot(concrete_model2)
    
    result2 <- compute(concrete_model2, test_data[,1:8])
    test_cor <- cor(result2$net.result, test_data[,9])
    hidden_value <- c(hidden_value,paste('c(',i,',',k,')'))
    cor_result <- c(cor_result, test_cor)

  }
}

find_hidden <- data.frame(hidden_value, cor_result)
find_hidden[cor_result == max(cor_result), ]

  층수 은닉층의 뉴런수 상관관계 개선 방법
model 3층 11개 0.95 hidden = c(8,3)

 

 

ㅇ보스톤 집값(boston.csv) 데이터를 가지고 집값을 예측하는 인공신경망 모델 만들기

질문1 : 미국도 우리나라처럼 강 주변의 집값이 더 비싼가?

질문2 : 미국도 우리나라처럼 학군이 좋은 곳이 더 집값이 비싼가?

 

문제337. 직업, 직업별 토탈월급을 세로로 출력하시오.

emp <- read.csv("c:\\data\\emp2.csv")
aggregate(sal~job, emp, sum)

문제338. 직업, 직업별 평균월급을 출력하시오.

emp <- read.csv("c:\\data\\emp2.csv")
aggregate(sal~job, emp, mean)

 

문제339. 보스톤 하우징 데이터를 R로 로드하고 찰스강 경계에 있는지 아닌지를 알려주는 CHAS(찰스강 경계에 있는지에 대한 더미변수)를 중복제거해서 출력하시오.

unique(boston$CHAS)  # 0 1

>찰스강 경계에 위치하면 1 , 아니면 0

 

문제340. CHAS를 출력하고 CHAS별 평균 집값을 출력하시오.

aggregate(price ~ CHAS, boston, mean)

CHAS    price
    0 22.09384
    1 28.44000

> 찰스강 주변의 평균 집값이 더 높음. 

 

 

ㅁBoston 데이터 설명

 [01]  CRIM 자치시(town) 별 1인당 범죄율
 [02]  ZN 25,000 평방피트를 초과하는 거주지역의 비율
 [03]  INDUS 비소매상업지역이 점유하고 있는 토지의 비율
 [04]  CHAS 찰스강에 대한 더미변수(강의 경계에 위치한 경우는 1, 아니면 0)
 [05]  NOX 10ppm 당 농축 일산화질소
 [06]  RM 주택 1가구당 평균 방의 개수
 [07]  AGE 1940년 이전에 건축된 소유주택의 비율
 [08]  DIS 5개의 보스턴 직업센터까지의 접근성 지수
 [09]  RAD 방사형 도로까지의 접근성 지수
 [10]  TAX 10,000 달러 당 재산세율
 [11]  PTRATIO 자치시(town)별 학생/교사 비율
 [12]  B 1000(Bk-0.63)^2, 여기서 Bk는 자치시별 흑인의 비율을 말함.
 [13]  LSTAT 모집단의 하위계층의 비율(%)
 [14]  MEDV 본인 소유의 주택가격(중앙값) (단위: $1,000)

 

PTRATIO 자치시(town)별 학생/교사 비율의 데이터를 중복 제거해서 출력하시오.

> PTRATIO의 값을 등급으로 나눠서 데이터를 다시 보겠음.

 

문제341. boston데이터에서 PTRATIO를 4개의 등급으로 나누어서 ptr_grade라는 파생변수로 생성하시오.

library(dplyr)
boston$ptr_grade <- ntile( boston$PTRATIO, 4)

library(data.table)
data.table(grade = boston$ptr_grade, 비율 = boston$PTRATIO)

> 비율이 높을수록 등급(grade)도 높게 나옴.

 

문제342. ptr_grade를 출력하고 ptr_grade별 평균집값을 출력하시오.

aggregate(price ~ ptr_grade, boston, mean)

ptr_grade    price
         1    27.55512
         2    26.31654
         3    19.32222
         4    16.86746

> 비율이 작을수록, 등급이 작을수록 좋은 거(교사1인당 관리하는 학생수가 적기 때문)

따라서 등급이 작을수록 평균 집값이 높은 걸 확인할 수 있음.

 

문제343. 보스톤 하우징 데이터의 상관관계그래프를 그리시오.

boston <- read.csv("c:\\data\\boston.csv")

library(psych)
pairs.panels(boston[,-1], cex = 7)

> RM, PTRATIO, LSTAT가 집값(price)과 상관계수가 0.5이상으로 상관관계가 높은걸 확인할 수 있음.

(RM : 방의 갯수의 비율, LSTAT : 하위계층의 비율, PTRATIO:학생/교사 비율)

=> 1. RM이 높으면 집값이 비싼까?

     2. LSTAT가 높으면 집값이 떨어질까?

     3. PTRATIO가 높으면 집값이 떨어질까? 

 

신경망의 성능을 올릴려면 hidden과 같은 하이퍼 파라미터의 값을 조절해야 하지만, 기계가 잘 학습할 수 있도록 좋은 학습데이터(파생변수)제공해줘야할 필요가 있음

 

ㅁ머신러닝의 성능을 높이는 방법

1. 하이퍼 파라미터 조절

2. 파생변수 추가 ( 데이터를 보고 질문을 생각할 수 있는 상상력이 있어야함)

 

 

문제344. 보스턴 하우징 집값을 예측하는 신경망 모델을 R로 생성하시오.

#1. 데이터 로드
boston <- read.csv("c:\\data\\boston.csv")
nrow(boston) #506
ncol(boston)  #15

#2. 결측치 확인
colSums(is.na(boston))

#3. 정규화 진행
normalize <- function(x){
  return( (x-min(x)) / (max(x) - min(x)))
}

boston_norm <- as.data.frame(lapply(boston, normalize))

#4. 훈련데이터와 테스트 데이터 분리
library(caret)
set.seed(1)
k <- createDataPartition(boston_norm$price, p = 0.9, list = F)
train_data <- boston_norm[k,-1]  # id컬럼 제거
test_data <- boston_norm[-k,-1]

nrow(train_data)  #826
nrow(test_data)  #48

#5. 모델 생성 및 훈련
library(neuralnet)
set.seed(2)
boston_model <- neuralnet(price ~ .,data = train_data)

plot(boston_model)

#6. 모델 평가
result <- neuralnet::compute(boston_model, test_data[, c(1:13)])
cor(result$net.result, test_data[,14])  #0.8310895


#7. 모델 성능 개선
hidden_value <- c()
cor_result <- c()
for (i in 1:10){
  for (k in 1:5){
    set.seed(2)
    boston_model <- neuralnet(price ~ .,data = train_data,hidden = c(i,k))
    result <- neuralnet::compute(boston_model, test_data[, c(1:13)])
    test_cor <- cor(result$net.result, test_data[,14])  #0.8310895
    
    hidden_value <- c(hidden_value,paste('c(',i,',',k,')'))
    cor_result <- c(cor_result, test_cor)
  }
}
find_hidden <- data.frame(hidden_value, cor_result)
find_hidden[cor_result == max(cor_result), ]
#c( 9 , 3 )  0.9515888 출력됨

#위의 결과를 바탕으로 다시 모델 생성
set.seed(2)
boston_model <- neuralnet(price ~ .,data = train_data, hidden = c(9,3))

plot(boston_model)

result <- neuralnet::compute(boston_model, test_data[, c(1:13)])
cor(result$net.result, test_data[,14])  #0.9515888

 

ㅇ신경망의 하이퍼 파라미터 hidden?

신경망의 층수와 노드(뉴런)수를 조정하는 파라미터

 

지금까지는 신경망의 하이퍼 파라미터를 hidden만 조정했는데 활성화 함수도 변경해서 성능이 더 올라가는지 확인해보겠음.

활성화 함수의 종류 3가지 : 계단함수, 시그모이드 함수, 렐루함수, softplus함수(p.339)

library(neuralnet)
set.seed(2)
boston_model3 <- neuralnet(price ~ .,data = train_data, hidden = c(8,4),act.fct = softplus)

plot(boston_model3)

result3 <- neuralnet::compute(boston_model3, test_data[, c(1:13)])
cor(result3$net.result, test_data[,14])   #0.9507334

 

 

반응형