티스토리 뷰

반응형

Random Forest 매개변수 튜닝



           


> cancer <- read.csv('cancer.csv') 

                    # 데이터를 수정할 필요가 없다면 문자열을 Factor형으로 저장하는 것이 좋음 (stringAsFactor = T 생략 가능)

> table(cancer$diagnosis)

   Benign Malignant       # 현재 cancer data는 class별 데이터가 불균등한 상태입니다. 

      357       212 


### 1. train set과 test set 분리(upsampling 수행)

> library(caret)

> data <- upSample(cancer[,-c(1,2)],      # 설명변수(x)

                             cancer[,2],            # 종속변수(y)

                             yname = 'Class')   # 종속변수의 변경 후 컬럼이름 설정 

> table(data$Class)   

   Benign Malignant   # class별로 데이터가 균등하게 분배

      357       357 


> library(doBy)

> train_up <- sampleBy(~Class, data = data, frac = 0.7)    # 70%의 train data 추출

> table(train_up$Class)


 # train data set의 선택된 row number를 추출하기 위한 함수 

> f_split <- function(x) {     

     as.numeric(strsplit(x, '\\.')[[1]][2])

   }

> rn <- sapply(rownames(train_up), f_split)


> test_up <- data[-rn,]     # 나머지 30%의 test data 추출


> table(train_up$Class)

   Benign Malignant 

      250       250 

> table(test_up$Class)

   Benign Malignant 

      107       107



### 2. 모델 적용

> library(randomForest)

> m2 <- randomForest(Class ~ ., data=train_up) 



### 3. 모델 평가

> prd2 <- predict(m2, newdata = test_up, type = 'class')

> sum(prd2 == test_up$Class) / nrow(test_up) * 100

[1] 95.3271



### 4. 매개변수 튜닝 (ntree, mtry 옵션)

# 1) ntree 변화 (default = 500)

# test data에 대한 score

> ntree_test <- c()

> for (i in 1:1000) {

     m <- randomForest(Class ~ . , data=train_up, ntree = i)

     val_var <- predict(m, newdata=test_up, type="class") 

     ntree_test <- c(ntree_test, sum(val_var == test_up$Class)/nrow(test_up) * 100)

   }

> ntree_test

[1] 93.92523 94.85981 93.92523 95.32710 94.85981 94.39252 94.85981 95.79439 ..  [496] 95.32710 95.32710 95.32710 95.79439 95.79439


# train data에 대한 score 

> ntree_train <- c()

> for (i in 1:1000) {

     m <- randomForest(Class ~ . , data=train_up, ntree = i)

     val_var <- predict(m, newdata=train_up, type="class") 

     ntree_train <- c(ntree_train, sum(val_var == train_up$Class)/nrow(train_up) * 100)

   }

> ntree_train

[1]  97.6  98.0  99.8  99.6  99.6  99.8  99.4 100.0 100.0  99.8 ...  [496] 100.0 100.0 100.0 100.0 100.0


# 2) mtry 변화

# test data에 대한 score

> mtry_test <- c()

> for (i in 1:(length(train_up)-1)) {

     m <- randomForest(Class ~ . , data=train_up, mtry = i)

     val_var <- predict(m, newdata=test_up, type="class") 

     mtry_test <- c(mtry_test, sum(val_var == test_up$Class)/nrow(test_up) * 100)

   }

> mtry_test

[1] 96.26168 96.26168 95.32710 95.79439 95.79439 95.79439 95.79439  ... 96.26168 96.26168 96.26168 96.26168


# train data에 대한 score 

> mtry_train <- c()

> for (i in 1:(length(train_up)-1)) {

     m <- randomForest(Class ~ . , data=train_up, mtry = i)

     val_var <- predict(m, newdata=train_up, type="class") 

     mtry_train <- c(mtry_train, sum(val_var == train_up$Class)/nrow(train_up) * 100)

   }

> mtry_train

[1] 100 100 100 100 100 100 100 100  ...  100 100 100 100 100 100 100


### 5. 결과 해석

# 1) ntree 변화에 따른 결과

> plot(1:length(ntree_test), ntree_test, type = 'l', xlab = 'ntree(size of tree)', col='red', ylim = c(95,100))

> lines(1:length(ntree_train), ntree_train, type = 'l')

# train data(black)를 적용한 결과는 당연히 높은 정확도를 나타내고 있고 test data(red)와의 과대적합(overfit)이 적은 지점의 ntree로 매개변수를 설정해주는 것이 좋다는 것을 확인할 수 있습니다. 또한 무조건 tree를 많이 생성한다고 좋은 결과를 도출하는 것이 아니라는 점도 알 수 있죠 !

# 2) mtry 변화에 따른 결과

> plot(1:length(mtry_test)-1, mtry_test, type = 'b', xlab = 'mtry', col='red', ylim = c(95,100))

> lines(1:length(mtry_train)-1, mtry_train, type = 'b')

# train data(black)를 적용한 결과 상당히 좋은 score(정확도)를 보여주고있는데.. 여기도 마찬가지로 과대적합(overfit)이 적은 지점을 mtry의 매개변수로 설정해주는 것이 좋습니다.

# 결론) 모델, 데이터마다 적절한 ntree, mtry의 개수가 다 다르기 때문에 매개변수 튜닝을 통해 적절한 지점을 찾아주는 것이 중요합니다!


### 6. 예측 

> test_up[10,31]

[1] Benign

Levels: Benign Malignant

> predict(m2, newdata = test_up[10,-31] + 0.01, type = 'class')

    33 

Benign 

Levels: Benign Malignant





참고: KIC 캠퍼스 머신러닝기반의 빅데이터분석 양성과정

반응형
댓글
최근에 올라온 글
최근에 달린 댓글
링크
Total
Today
Yesterday