ggplot2 패키지의 diamonds 데이터를 활용하여 다이아몬드 가격을 예측하는 다층 신경망 모델을 생성해본다.
개요
많은 딥러닝 예제가 임의의 데이터를 생성하고 모델링을 하는데 그치는 경우가 많다. 여기서는 테이블 형식의 ggplot2 패키지의 diamonds 데이터를 사용하고자 한다. 데이터 전처리 부터 모델 구동 및 손실 평가까지 진행하고자 한다.
환경설정
데이터 준비를 위해서 ggplot2, factDummies, caTools 를 불러오고 신경망 학습을 위해서 torch 를 불러온다. 그리고 오차를 시각적으로 확인하기 위해 ggplot2 를 활용한다. 추가로 사용자 정의 함수 minmax()
는 정규화를 위해 지정하였다.
1 | library("ggplot2") |
데이터 준비
ggplot2 패키지의 diamonds 데이터는 다음과 같다.
1 | df = as.data.frame(diamonds) |
각 변수의 속성을 확인한다 다음 코드 관련한 상세 동작 설명 포스팅은 아래 링크 참고
※ 변수 속성 확인 포스팅 바로가기 -> [클릭]
1 | df_classes = unlist(lapply(sapply(df, FUN = "class"), FUN = "[", 1)) |
변수 속성이 순서형(ordered factor)이면 가변수 변환 함수가 제대로 동작하지 않기 때문에 다음과 같이 순서형 변수를 모두 문자형으로 변환해주었다.
1 | pos_ordered = which(df_classes == "ordered") |
물론 순서형 변수는 가변수 변환이 아니라 수치형으로 변환하여 활용해도 되는데 그 때는 as.numeric()
함수를 적용하면 되나 일단 factDummies 패키지의 dummy_cols()
함수로 가변수 변환을 해주었다. 여기서 가변수 변환 대상이 되는 변수의 제거를 쉽게 하기 위해 remove_select_columns = TRUE
로 지정해주었다. 다음으로는 신경망 학습을 보다 원활하게 하기 위해 사전에 정의한 minmax()
함수로 정규화를 해줬는데 이 과정을 생략하면 신경망 학습시 에러가 발생하거나 멈출 수 있으니(torch 패키지 버전이 높아지면 해결 될 수 있음) 주의하도록 한다.
1 | df_dum = dummy_cols(df, |
데이터 분할 절차는 다음과 같이 한다. caTools 패키지를 활용하였으나 보다 간단하게 하려면 단순 sample()
함수를 사용해도 된다.
1 | set.seed(123) |
하이퍼파라미터 설정
D_in 객체는 입력되는 변수의 개수로 지정하였다.
D_out 객체는 출력되는 값이 price 하나여서 1로 지정하였다.
1 | device = torch_device("cpu") # cuda |
하이퍼파라미터 설정에 맞춰 데이터 세트를 tensor로 변환한 결과는 다음과 같다.
1 | tensor_train_x = torch_tensor(data = as.matrix(df_dum_train_x), |
신경망 구조 정의
두 개의 레이어를 사용하며 각 레이어의 입출력은 udf_init()
함수에서 정의하고 신경망 구조는 udf_str()
함수에서 정의한다. 두 레이어 사이에 위치하는 활성함수(activation function)은 ReLU로 지정하였다.
1 | udf_init = function(D_in, H, D_out) { |
동일한 초기값을 위해 torch_manual_seed()
함수를 활용했고 최종 신경망 객체 model 를 생성하였다.
1 | torch_manual_seed(123) |
학습 및 평가
최적화 설정을 하고 200 스텝 마다 중간 결과가 출력되도록 하였다. 그리고 손실은 loss 객체에 모두 저장하였다.
1 | optimizer = optimizer(model$parameters, lr = learning_rate) |
학습에 따른 손실 그래프를 그려보면 다음과 같다.
1 | df_loss = data.frame(step = 1:step, |
정규화 이전의 자료 비교, 평가 데이터 세트 확인, 학습률, 최적화 함수 등 다양한 옵션은 별도의 포스팅에서 다룰 예정이다.