iris데이터를 통해 여러모델을 돌려보고자한다. 이 모델의 목표는 Species를 분류하고자 함이며, 최종 모델 선정은 정확도로 하도록 할 것이다. 각각의 모델에 대한 기술적인 설명은 본인의 블로그에 명시해 두려고 한다.

1. 탐색적 데이터 분석(EDA)

우선 데이터를 파악해 보자. 데이터는 traning_set기준으로 파악을 할 것이고, 이 파악을 통해서 Species를 분류하는데 어떤 데이터가 필요한지 먼저 알아보기 위함이다.

1) 필요한 패키지


library(nnet) # Logistic regression, Neural Network
library(rpart) # Decision Tree
library(randomForest) # Random Forest
## randomForest 4.6-14
## Type rfNews() to see new features/changes/bug fixes.
library(dplyr) # Data Handling 
## 
## Attaching package: 'dplyr'
## The following object is masked from 'package:randomForest':
## 
##     combine
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(caret) # Confusion Matrix
## Loading required package: lattice
## Loading required package: ggplot2
## 
## Attaching package: 'ggplot2'
## The following object is masked from 'package:randomForest':
## 
##     margin
library(DT) # Data visualize
library(class) # KNN
library(ggvis) # Data visualize
## 
## Attaching package: 'ggvis'
## The following object is masked from 'package:ggplot2':
## 
##     resolution
library(kernlab) # Support Vector Machine
## 
## Attaching package: 'kernlab'
## The following object is masked from 'package:ggplot2':
## 
##     alpha



2) 데이터 시각화

우선 데이터가 어떻게 분포되어 있는지 파악해 보자. Petal.Length, Petal.Width가 Species에 좀더 영향을 준다는 것을 알 수 있었다.

plot(iris)


### 2-1) Petal.Length, Petal.Width를 이용한 시각화 앞선 그래프에서 Petal.Length, Petal.Width가 Species를 분류하는데 있어서 많은 관계를 가지고 있다는 것을 알았기 때문에 이 두개를 가지고 분류를 해보자. 다음 그림에서 알 수 있드시 setosa는 뚜렷하게 구분이 되는것으로 보이고 versicolor, verginica는 약 3개정도 애매함을 보인다.

iris %>% 
  ggvis(~Petal.Length, ~Petal.Width, fill = ~factor(Species)) %>%
  layer_points()



3) 데이터 구조 파악

iris 데이터의 구조를 파악해 보자. 구조를 파악하는 이유는 데이터의 자료형이 character인지, int인지, vector인지 파악하기 위함이다.

str(iris)
## 'data.frame':    150 obs. of  5 variables:
##  $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
##  $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
##  $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
##  $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
##  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...



4) 데이터의 통계적 수치 파악

iris데이터의 통계적 수치를 파악해보자.

summary(iris)
##   Sepal.Length    Sepal.Width     Petal.Length    Petal.Width   
##  Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100  
##  1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300  
##  Median :5.800   Median :3.000   Median :4.350   Median :1.300  
##  Mean   :5.843   Mean   :3.057   Mean   :3.758   Mean   :1.199  
##  3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100   3rd Qu.:1.800  
##  Max.   :7.900   Max.   :4.400   Max.   :6.900   Max.   :2.500  
##        Species  
##  setosa    :50  
##  versicolor:50  
##  virginica :50  
##                 
##                 
## 



5) 데이터의 결측치 파악

데이터가 결측치가 있는지 파악해보자. 결측치는 존재하지 않는 것으로 확인되었다.

sum(is.na(iris))
## [1] 0




2. 데이터 처리

우선, traning_set과 test_set을 나누도록 하자. 비율은 7:3으로 할 것이며 필요하다면 8:2 또는 6.5:3.5로도 진행 할 것이다.

# data 생성
df <- iris

# seed값 설정
set.seed(919)

# train/test sampling
training_sampling <- sort(sample(1:nrow(df), nrow(df) * 0.7 ))
test_sampling <- setdiff(1:nrow(df),training_sampling)

# traning_set, test_set
training_set <- df[training_sampling,]
test_set <- df[test_sampling,]



3. 머신러닝 모델 생성

Training / Test set를 나누었으니 이제 이 데이터로 학습을 시켜보자. 모델은 Logistic regression, Decision Tree, Random Forest를 사용 했다.

1) Logistic regression을 통한 분류

먼저, Logistic regression로 분류를 해보자. 로지스틱 회귀란 선형데이터를 분류하는 선형 분류기의 개념이다. nnet 패키지의 multinom()을 사용하여 로지스틱 회귀분석을 사용해보자. 로지스틱 회귀에 대한 자세한 과정은 다음 블로그를 참고하길 바란다.
- Logistic regression : 머신러닝의 기초 #2 (로지스틱 회귀분석)

multi_logit_m <- multinom(Species ~ Petal.Length + Petal.Width, data = training_set)
## # weights:  12 (6 variable)
## initial  value 115.354290 
## iter  10 value 8.103704
## iter  20 value 6.085925
## iter  30 value 6.068446
## iter  40 value 6.061376
## iter  50 value 6.058734
## iter  60 value 6.055210
## iter  70 value 6.053575
## iter  80 value 6.048157
## iter  90 value 6.047643
## iter 100 value 6.047423
## final  value 6.047423 
## stopped after 100 iterations
multi_logit_p <- predict(multi_logit_m, newdata = test_set, type = "class")



2) Decision tree를 통한 분류

이번엔 Decision tree로 분류를 해볼 것이다. 의사결정나무란 노드에서 가지를 쳐 마치 나무와 같은 형태로 분류를 하는 방법이다. 자세한 내용은 밑의 기술블로그를 참조하길 바란다. rpart패키지 불러와 rpart 함수를 사용하여 Decision tree를 생성해보자.
- Decision tree : 머신러닝의 기초 #3 (의사결정 나무)

rpart_m <- rpart(Species ~ Petal.Length + Petal.Width, data = training_set)

rpart_p <- predict(rpart_m, newdata = test_set, type = "class")



3) Random Forest를 통한 분류

이번엔 Random Forest로 분류를 해볼 것이다. Random Forest란 앙상블 기법 중 하나로 여러가지 의사결정 나무를 집합하여 숲을 이룬 것과 비슷하다고 볼 수 있다. Random Forest에 대한 내용은 기술블로그를 참조 하길 바란다. randomForest패키지의 randomForest함수를 사용하여 Random Forest 모델을 만들어 보자.
- Random Forest : 랜덤 포레스트(Random Forest)

rf_m <- randomForest(Species ~ Petal.Length + Petal.Width, data = training_set)

rf_p <- predict(rf_m, newdata = test_set, type = "class")



4) Neural Network을 통한 분류

이번엔 Neural Network을 통해 분류를 해볼 것이다. neural network란 인간의 뇌를 본따서 만든 모델이다. 뉴런을 흉내내서 만들었으며 입력층, 은닉층, 출력층으로 구분되어 있다. 은닉층에서 입력값이 조합되기 때문에 비선형적인 문제를 해결할 수 있다. 자세한 내용은 기술블로그를 참고하도록 하자.
- Neural Network : 뉴럴 네트워크(Neural Network)

nnet_m <- nnet(Species ~ Petal.Length + Petal.Width , data = training_set, size = 3)
## # weights:  21
## initial  value 116.371335 
## iter  10 value 43.410233
## iter  20 value 5.701629
## iter  30 value 5.314187
## iter  40 value 3.647732
## iter  50 value 3.110659
## iter  60 value 2.971219
## iter  70 value 2.540678
## iter  80 value 2.251522
## iter  90 value 2.250146
## iter 100 value 2.250097
## final  value 2.250097 
## stopped after 100 iterations
nnet_p <- predict(nnet_m, newdata = test_set, type = "class")



5) Support Vector Machine을 통한 분류

이번엔 Support Vector Machine 을 통해 분류를 해볼 것이다. SVM(Support Vector Machine)이란 데이터 상에 있는 각점들의 거리를 분석해 가장 먼 거리에 있는 점들을 기준으로 support vector를 형성하여 두개의 support vector 중간에 초평면을 만들어 분류를 하는 방법이다. 쉽게말하면 두점 사이의 거리가 최대가 되는 지점을 찾는 것이다.
- Support Vector Machine : 서포트 벡터 머신(Support Vector Machine)


svm_m <- ksvm(Species ~ Petal.Length + Petal.Width , data = training_set)

svm_p <- predict(svm_m, newdata = test_set)



6) K-Nearest Neighbor을 통한 분류

이번엔 KNN으로 분류를 해보자. KNN이란 K-Nearest Neighbor의 점들에 주어진 가장 근접해있는 K근접이웃을 알아내는 과정이다. 자세한 내용은 기술블로그를 참고하도록 하자.
- K-Nearest Neighbor : K-최근접 이웃(K-Nearest Neighbor)

  • KNN을 하기전에 데이터를 정규화 시키자. 정규화를 하는 이유는 모든 feature들을 같은 scale상에 놓기 위함이다.
#정규화함수
normalizer <- function(x) {
  return_value <- (x - min(x)) / (max(x) - min(x))
  return(return_value)
}


normal_iris <- sapply(iris[,1:4] , normalizer) %>% 
  as.data.frame()

# data 생성
df <- cbind(normal_iris, "Species" = iris[,5])

# train/test sampling
# training_sampling <- sort(sample(1:nrow(df), nrow(df) * 0.7 ))
# test_sampling <- setdiff(1:nrow(df),training_sampling)

# traning_set, test_set
training_set <- df[training_sampling,]
test_set <- df[test_sampling,]

training_set_unlable <- training_set[,1:4]
training_set_lable <- training_set[,5]


test_set_unlable <- test_set[,1:4]
test_set_lable <- test_set[,5]

knn_p <- knn(train = training_set_unlable, test = test_set_unlable, cl = training_set_lable, k = 3)



4. 모델 평가

각각의 모델을 평가해 보자. 평가항목은 정확도로 할 것이고 이중에서 가장 좋은 모델을 채택한다.

model_list <- cbind(
  as.character(multi_logit_p), 
  as.character(rpart_p), 
  as.character(rf_p),
  as.character(nnet_p),
  as.character(svm_p),
  as.character(knn_p)) %>%
  as.data.frame()

# str(model_list)

total_model_accuracy <- data.frame()
for (model in model_list[,1:ncol(model_list)]) {
  model_cm <- confusionMatrix(model, test_set$Species)
  model_cm_class <- model_cm$byClass %>% as.data.frame()
  model_accuracy <- model_cm_class$`Balanced Accuracy`
  total_model_accuracy <- rbind(total_model_accuracy, model_accuracy)
}



colnames(total_model_accuracy) <- levels(test_set$Species)

rownames(total_model_accuracy) <- c("Logistic Regression", "Decision Tree", "Random Forest", "Neural Network", "Support Vector Machine", "KNN")



모델의 정확도 비교 테이블

예측값, 실측값의 비교를 위해 각 모델별 분류에 대한 정확도 비교테이블이다.

datatable(total_model_accuracy)

후기


이렇게 6가지의 모델로 iris 데이터를 분류해 보았다. 6개의 모델 모두 대체적으로 높은 수준의 예측률을 보여주었다. 그러나 당장 위의 수치만으로는 어떤 모델이 더 좋다라는 것을 판단하기에는 무리가 있다. iris데이터는 분류가 잘되는 데이터 였지만, 세상에는 iris와 같이 분류가 잘 되는 데이터만이 있는 것이 아니다. 특히 인간의 생명과 연결된 의료분야에서 많은 데이터 분석이 진행중인데 이러한 분야에서는 데이터 분석가의 도메인 지식과 역량에 따라 데이터 분석을 함에 있어서 가장 적합한 모델을 선정하여 분석해야한다. 그러기 위해서는 다양한 모델들의 개념과 특성을 알아야하며 주어진 데이터를 분석하는대에 있어서 어떠한 모델을 사용하고 또한 그 속에서 사용되는 여러가지 옵션들을 잘 다룰 수 있는 역량을 갖추어야 한다고 생각한다.