Tensorflow/Tensorflow for R

Multilayer Perceptron (ver.R)

딥스탯 2017. 9. 30. 11:22
Multilayer Perceptron (ver.R)

DATA SET 출처

https://www.kaggle.com/ludobenistant/hr-analytics/data (Kaggle, Human Resources Analysis) (해당 데이터셋은 현재 사라졌습니다.)

참고자료

https://www.tensorflow.org (TensorFlow)

https://tensorflow.rstudio.com (TensorFlow for R)

Multilayer Perceptron (ver.R)

The Human Resources Analysis data set

In [1]:
HR_data_set <- read.csv("HR_comma_sep.csv")
In [2]:
str(HR_data_set)
'data.frame':	14999 obs. of  10 variables:
 $ satisfaction_level   : num  0.38 0.8 0.11 0.72 0.37 0.41 0.1 0.92 0.89 0.42 ...
 $ last_evaluation      : num  0.53 0.86 0.88 0.87 0.52 0.5 0.77 0.85 1 0.53 ...
 $ number_project       : int  2 5 7 5 2 2 6 5 5 2 ...
 $ average_montly_hours : int  157 262 272 223 159 153 247 259 224 142 ...
 $ time_spend_company   : int  3 6 4 5 3 3 4 5 5 3 ...
 $ Work_accident        : int  0 0 0 0 0 0 0 0 0 0 ...
 $ left                 : int  1 1 1 1 1 1 1 1 1 1 ...
 $ promotion_last_5years: int  0 0 0 0 0 0 0 0 0 0 ...
 $ sales                : Factor w/ 10 levels "IT","RandD","accounting",..: 8 8 8 8 8 8 8 8 8 8 ...
 $ salary               : Factor w/ 3 levels "high","low","medium": 2 3 3 2 2 2 2 2 2 2 ...
In [3]:
summary(HR_data_set)
 satisfaction_level last_evaluation  number_project  average_montly_hours
 Min.   :0.0900     Min.   :0.3600   Min.   :2.000   Min.   : 96.0       
 1st Qu.:0.4400     1st Qu.:0.5600   1st Qu.:3.000   1st Qu.:156.0       
 Median :0.6400     Median :0.7200   Median :4.000   Median :200.0       
 Mean   :0.6128     Mean   :0.7161   Mean   :3.803   Mean   :201.1       
 3rd Qu.:0.8200     3rd Qu.:0.8700   3rd Qu.:5.000   3rd Qu.:245.0       
 Max.   :1.0000     Max.   :1.0000   Max.   :7.000   Max.   :310.0       
                                                                         
 time_spend_company Work_accident         left        promotion_last_5years
 Min.   : 2.000     Min.   :0.0000   Min.   :0.0000   Min.   :0.00000      
 1st Qu.: 3.000     1st Qu.:0.0000   1st Qu.:0.0000   1st Qu.:0.00000      
 Median : 3.000     Median :0.0000   Median :0.0000   Median :0.00000      
 Mean   : 3.498     Mean   :0.1446   Mean   :0.2381   Mean   :0.02127      
 3rd Qu.: 4.000     3rd Qu.:0.0000   3rd Qu.:0.0000   3rd Qu.:0.00000      
 Max.   :10.000     Max.   :1.0000   Max.   :1.0000   Max.   :1.00000      
                                                                           
         sales         salary    
 sales      :4140   high  :1237  
 technical  :2720   low   :7316  
 support    :2229   medium:6446  
 IT         :1227                
 product_mng: 902                
 marketing  : 858                
 (Other)    :2923                
In [4]:
table(HR_data_set$number_project)
   2    3    4    5    6    7 
2388 4055 4365 2761 1174  256 
In [5]:
table(HR_data_set$time_spend_company)
   2    3    4    5    6    7    8   10 
3244 6443 2557 1473  718  188  162  214 
In [6]:
table(HR_data_set$sales)
         IT       RandD  accounting          hr  management   marketing 
       1227         787         767         739         630         858 
product_mng       sales     support   technical 
        902        4140        2229        2720 

Handling the data set

In [7]:
set.seed(1)
test_obs <- sample(nrow(HR_data_set),4999)
In [8]:
training_set <- HR_data_set[-test_obs,]
testing_set  <- HR_data_set[test_obs,]
In [9]:
training_y <- training_set$satisfaction_level
training_X <- model.matrix(satisfaction_level ~ .,data=training_set)
In [10]:
testing_y <- testing_set$satisfaction_level
testing_X <- model.matrix(satisfaction_level ~.,data=testing_set)
In [11]:
sd_amh <- sd(training_X[,4]) ; mean_amh <- mean(training_X[,4])
In [12]:
training_X[,4] <- (training_X[,4]-mean_amh)/sd_amh
testing_X[,4] <- (testing_X[,4]-mean_amh)/sd_amh
training_X <- training_X[,-1]
testing_X  <- testing_X[,-1]
In [13]:
dim(training_X)
  1. 10000
  2. 18

모형에 대한 자세한 설명은 생략하도록 하겠습니다.

MLP(multilayer perceptron), elu, ReLU, sigmoid, Adam

input -> [inner product -> elu] -> dropout -> [inner product -> relu] -> dropout -> [inner product -> sigmoid] -> output

Loss : squared error loss, Optimizer : Adam

In [14]:
require(tensorflow)
Loading required package: tensorflow
In [15]:
x  <- tf$placeholder("float", shape(NULL, 18L))
y_ <- tf$placeholder("float", shape(NULL, 1L))

함수 정의 : weight_variable - truncated normal distribution에서 난수 발생해서 원하는 모양으로 weight tensor를 만드는 함수.

In [16]:
weight_variable <- function(shape){
    initial <- tf$truncated_normal(as.integer(shape))
    return(tf$Variable(initial))
}

함수 정의 : bias_variable - 원하는 모양으로 bias tensor를 만드는 함수.

In [17]:
bias_variable <- function(shape){
    initial <- tf$constant(rep(1,shape))
    return(tf$Variable(initial))
}

모형 설정

[inner product -> elu]

In [18]:
W1   <- weight_variable(c(18,2^5))
b1    <- bias_variable(2^5)
elu1 <- tf$nn$elu(tf$matmul(x, W1) + b1)

dropping out 1

In [19]:
keep_prob1  <- tf$placeholder("float")
layer1          <- tf$nn$dropout(elu1, keep_prob1)

[inner product -> relu]

In [20]:
W2    <- weight_variable(c(2^5,2^3))
b2     <- bias_variable(2^3)
relu2 <- tf$nn$relu(tf$matmul(layer1, W2) + b2)

dropping out 2

In [21]:
keep_prob2  <- tf$placeholder("float")
layer2          <- tf$nn$dropout(relu2, keep_prob2)

[inner product -> sigmoid]

In [22]:
W3          <- weight_variable(c(2^3,1))
b3           <- bias_variable(1)
sigmoid3 <- tf$nn$sigmoid(tf$matmul(layer2, W3) + b3)

Loss 와 Optimizer 설정

In [23]:
SSE          <- tf$reduce_sum((sigmoid3 - y_)^2)
train_step <- tf$train$AdamOptimizer(1e-4)$minimize(SSE)

Session 반복 실행

In [24]:
sess <- tf$Session()
sess$run(tf$global_variables_initializer())
In [25]:
for(i in 0:2000){
    batch_obs <- sample(10000,5000)
    sess$run(train_step,feed_dict =
             dict(x = training_X[batch_obs,], y_ = as.matrix(training_y[batch_obs]),
                  keep_prob1 = .5, keep_prob2 = .7))
    if(i%%100 == 0){
        train_accuracy <- sess$run(SSE, feed_dict =
                                   dict(x = training_X, y_ = as.matrix(training_y),
                                        keep_prob1 = 1, keep_prob2 = 1))
        cat("step ", i, "training accuracy ", train_accuracy , "\n")
    }
    if(i%%500 == 0){
        cat("test accuracy ", sess$run(SSE, feed_dict =
                                       dict(x = testing_X, y_ = as.matrix(testing_y), keep_prob1 = 1, keep_prob2 = 1)),
            "step ", i, "\n")
    }
}
step  0 training accuracy  3190.276 
test accuracy  1579.748 step  0 
step  100 training accuracy  2719.152 
step  200 training accuracy  2270.686 
step  300 training accuracy  1823.717 
step  400 training accuracy  1466.969 
step  500 training accuracy  1266.925 
test accuracy  630.7994 step  500 
step  600 training accuracy  1186.715 
step  700 training accuracy  1155.402 
step  800 training accuracy  1155.422 
step  900 training accuracy  1162.379 
step  1000 training accuracy  1145.085 
test accuracy  574.7202 step  1000 
step  1100 training accuracy  1109.995 
step  1200 training accuracy  1066.265 
step  1300 training accuracy  1014.73 
step  1400 training accuracy  959.0842 
step  1500 training accuracy  906.4619 
test accuracy  455.8181 step  1500 
step  1600 training accuracy  855.71 
step  1700 training accuracy  808.1107 
step  1800 training accuracy  764.0373 
step  1900 training accuracy  721.1246 
step  2000 training accuracy  695.4656 
test accuracy  344.1904 step  2000 
In [ ]: