티스토리 뷰

반응형

지도학습을 위한 데이터 샘플링






1. Train data set, Test data set 으로 분리

Train Data = 모델의 훈련을 위한 훈련용 데이터

Test Data = 모델을 평가하기 위해 정답(결과)을 이미 알고있는 테스트용 데이터


*) caret::createDataPartition() 함수를 사용한 샘플링 가장 좋은 샘플링 방법 !!!

sampleBy 도 균등 샘플링이 가능하지만, 나머지 30%의 test data를 저장하기 위해 train data의 행 번호를 추출해야하는 번거로움이 있습니다. createDataPartition 함수는 이 모든 것을 한 번에 해결해준답니다.. Goood

> library(caret)

> rn <- createDataPartition(y = iris$Species, p = 0.7, list = F)   # row 색인을 위해 list = F 로 설정

> train <- iris[rn,]            # 70%의 train data (랜덤 샘플링된 행 번호를 색인)

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

> table(train$Species)      # 항상 class별 균등하게 샘플링

    setosa versicolor  virginica 

        35         35         35

> table(test$Species)

    setosa versicolor  virginica 

        15         15         15



1-1) 그룹번호 할당을 통한 샘플링 

sample(data,   # 원본 데이터

          size,      # sample zise

          replace = T)  # 복원추출(중복) 여부 (sampling의 경우 반드시 필요)

> result <- sample(1:2,                    # 1 ~ 2 값으로 그룹 지정

                          size = nrow(iris),    size의 크기만큼 랜덤 추출

                          replace = T,          #  복원추출(중복) 여부

                          prob = c(0.7,0.3))  # 그룹 1이 나올 확률 70%, 그룹 2가 나올 확률 30% 비율로 분리

                                                    # sample 함수로는 데이터 분할이 70:30으로 정확하게 나오지 않을 때가 있음


> train <- iris[result ==1,]                 70% 확률로 선정된 1번 그룹에 속하는 랜덤 (train)데이터

> test <- iris[result ==2,]                  # 30% 확률로 선정된 2번 그룹에 속하는 랜덤 (test)데이터

> table(train$Species)     # sample() 함수는 그룹(class)별 균등 분리 불가능

setosa versicolor  virginica 

        36         39         35 



# 1-2) row 번호 할당을 통한 샘플링

> sn <- sample(1:nrow(iris), size = nrow(iris)*0.7)     # sample(150, 5) : 1~150 에서 5개의 데이터 랜덤 추출

> train <- iris[sn,]             # 70%의 랜덤  (train)데이터

> test <- iris[-sn,]             # 나머지 30%의 랜덤 (test)데이터



# 1-3) sampleBy 함수를 사용한 균등 샘플링

> library(doBy)   # sampleBy 사용을 위한 패키지


> train <- sampleBy(~Species, frac = 0.7, data = iris)    # 70%의 랜덤 (train)데이터를 추출


# 70%에 포함된 train데이터의 행 번호를 추출하기 위한 사용자 함수 생성 

# strsplit(rownames(train), '\\.')  

> f1 <- function(x) {

     as.numeric(strsplit(x, '\\.')[[1]][2])                        # (.)을 문자로 인식시키기 위해 \\ 사용

   }

> rn <- as.vector(sapply(rownames(train), f1))            # 70%에 포함된 train 데이터의 행 번호를 벡터형으로 저장 

> test <- iris[-rn,]                                                    # 나머지 30%를 test 데이터로 저장

> table(train$Species)                                              # 균등하게 데이터가 분리된 것을 확인 

    setosa versicolor  virginica 

        35         35         35 

> table(test$Species)

    setosa versicolor  virginica 

        13         13         14 


# 결론. sampleBy() 함수는 그룹(class)별 균등 분리 가능 => 가장 좋은 샘플링 방법

장점) 종속변수가 각 class별로 균등하지 않으면 예측력이 떨어질 가능성이 높은데, 이를 방지해줄 수 있음

단점) train data 추출을 위해 약간의 작업이 필요

하지만, 원본데이터 내 종속변수의 그룹 별 데이터 수가 균등하지 않을 경우

ex) 종속변수 Group 컬럼의 A 그룹 데이터 = 235개  

                                    B 그룹 데이터 = 100개 

데이터의 수를 균등하게 맞춰줘야 합니다.





2. 모델 생성

각 분석 모델 알고리즘에 맞는 모델 생성




3. 모델 평가

3-1) 새로운 데이터 셋(test)에 대한 예측력 확인

> val_var <- predict(m, newdata = test, type = 'class')  # type : 예측 결과 유형

                                                                                     prob : 각 분류에 대한 확률(defalut)

                                                                                     class : 종속변수의 class 이름으로 출력

> sum(val_var == test$Species) / nrow(test) * 100        

 [1] 97.5                                                          # 모델의 평가 점수 : TRUE(정답) 개수 / test data의 전체 건수 * 100

                                                         # iris 데이터는 이미 4개의 중요 컬럼이 선택되어있기 때문에 바로 높은 결과가 나옴


3-2) overfit(과대적합) 확인

# train data set의 정확도가 test data set의 정확도보다 10% 이상 많이 차이날 경우 재조정 필요

> val_var <- predict(m, newdata = train, type = 'class') 

> sum(val_var == train$Species) / nrow(train) * 100 

[1] 95.45455

# Y 인 종속변수(Species)가 데이터(train)에 포함되어 있어도, 에러가 발생하지 않는 이유는 모델 자체가 필요한 설명 변수만 뽑아서 사용하기 때문




4. 모델을 통한 예측

> iris[9,]     

Sepal.Length Sepal.Width Petal.Length Petal.Width Species

9          4.4         2.9          1.4         0.2  setosa

> new_data <- data.frame(Sepal.Length = 4.5, Sepal.Width = 3,      # iris의 9번째 컬럼과 유사한 test data를 적용

                                     Petal.Length = 1.2, Petal.Width = 0.3)

> predict(m, newdata = new_data, type = 'class')    # predict(모델, test 데이터(data frame))

     1 

setosa 

Levels: setosa versicolor virginica



5. 모델 시각화

각 분석 모델 알고리즘에 맞는 시각화





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

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