자기계발/자격증

[빅데이터 분석기사] 2회 기출문제 연습(R 코드) - 3/3

혁이e 2022. 6. 16.

빅데이터 분석기사, 빅분기 실기 중 가장 어려운 작업형 2유형 연습 코드이다.

이 문제는 전체적인 데이터 분석의 Flow 를 따라가는 것이 중요하다고 생각한다.

 

kdata 데이터자격검정 공식 홈페이지의 실기 체험하기에서는

-. 데이터 전처리 , Feature Engineering, 분류 알고리즘 사용, 초매개변수 최적화, 모형 앙상블 등이 수반되어야 함

-. 수험번호.csv 파일이 만들어지도록 코드 제출

-. ROC-AUC 평가지표에 따라 모델 성능 채점

-. 데이터 저장은 다음과 같이 데이터 테이블 형식임.

이 점들을 고려해서 작업형 제2유형 기출문제 풀이를 진행하였다. 

이전과 마찬가지로 R 을 사용하였고, 모든 것을 완벽하게 하기 보다는 적당하게 알짜만 가져가서 부분점수를 노리는 공략이다.

 데이터 전처리 (결측치 NA 처리, 표준화/정규화) - 모델 형성(glm, randomForest, svm) - 앙상블로 진행.

 저작권 문제가 생길 수 있으므로 문제는 상세하게 기술하기 어려움. 러프하게 비슷한 유형으로 진행.

1. 전자상거래 배송 데이터 모형을 활용하여 제품이 시간에 맞게 배송되었는지에 대한 예측모델 만들기.

학습용 데이터(x_train)를 통해 예측 모형을 만든 후 평가용 데이터(x_test)에 적용하여 얻은 예측값을 csv 파일로 생성하시오. 

 

Train.csv
0.42MB

 

 

# 데이터 불러오기

> ds <- read.csv("c:/data/exam2/Train.csv")

 

# 데이터 확인

> str(ds)
'data.frame': 10999 obs. of  12 variables:
 $ ID                 : int  1 2 3 4 5 6 7 8 9 10 ...
 $ Warehouse_block    : chr  "D" "F" "A" "B" ...
 $ Mode_of_Shipment   : chr  "Flight" "Flight" "Flight" "Flight" ...
 $ Customer_care_calls: int  4 4 2 3 2 3 3 4 3 3 ...
 $ Customer_rating    : int  2 5 2 3 2 1 4 1 4 2 ...
 $ Cost_of_the_Product: int  177 216 183 176 184 162 250 233 150 164 ...
 $ Prior_purchases    : int  3 2 4 4 3 3 3 2 3 3 ...
 $ Product_importance : chr  "low" "low" "low" "medium" ...
 $ Gender             : chr  "F" "M" "M" "M" ...
 $ Discount_offered   : int  44 59 48 10 46 12 3 48 11 29 ...
 $ Weight_in_gms      : int  1233 3088 3374 1177 2484 1417 2371 2804 1861 1187 ...
 $ Reached.on.Time_Y.N: int  1 1 1 1 1 1 1 1 1 1 ...


> head(ds)
  ID Warehouse_block Mode_of_Shipment Customer_care_calls Customer_rating Cost_of_the_Product Prior_purchases
1  1               D           Flight                   4               2                 177               3
2  2               F           Flight                   4               5                 216               2
3  3               A           Flight                   2               2                 183               4
4  4               B           Flight                   3               3                 176               4
5  5               C           Flight                   2               2                 184               3
6  6               F           Flight                   3               1                 162               3
  Product_importance Gender Discount_offered Weight_in_gms Reached.on.Time_Y.N
1                low      F               44          1233                   1
2                low      M               59          3088                   1
3                low      M               48          3374                   1
4             medium      M               10          1177                   1
5             medium      F               46          2484                   1
6             medium      F               12          1417                   1


> summary(ds)
       ID        Warehouse_block    Mode_of_Shipment   Customer_care_calls Customer_rating Cost_of_the_Product
 Min.   :    1   Length:10999       Length:10999       Min.   :2.000       Min.   :1.000   Min.   : 96.0      
 1st Qu.: 2750   Class :character   Class :character   1st Qu.:3.000       1st Qu.:2.000   1st Qu.:169.0      
 Median : 5500   Mode  :character   Mode  :character   Median :4.000       Median :3.000   Median :214.0      
 Mean   : 5500                                         Mean   :4.054       Mean   :2.991   Mean   :210.2      
 3rd Qu.: 8250                                         3rd Qu.:5.000       3rd Qu.:4.000   3rd Qu.:251.0      
 Max.   :10999                                         Max.   :7.000       Max.   :5.000   Max.   :310.0      
 Prior_purchases  Product_importance    Gender          Discount_offered Weight_in_gms  Reached.on.Time_Y.N
 Min.   : 2.000   Length:10999       Length:10999       Min.   : 1.00    Min.   :1001   Min.   :0.0000     
 1st Qu.: 3.000   Class :character   Class :character   1st Qu.: 4.00    1st Qu.:1840   1st Qu.:0.0000     
 Median : 3.000   Mode  :character   Mode  :character   Median : 7.00    Median :4149   Median :1.0000     
 Mean   : 3.568                                         Mean   :13.37    Mean   :3634   Mean   :0.5967     
 3rd Qu.: 4.000                                         3rd Qu.:10.00    3rd Qu.:5050   3rd Qu.:1.0000     
 Max.   :10.000                                         Max.   :65.00    Max.   :7846   Max.   :1.0000     

 

# 결측치 없음, 한번 더 확인

> sum(!complete.cases(ds))
[1] 0

> # 음수나 특이한 값이 확인되지 않음.

> # Reached.on.Time_Y.N 는 0,1 인 이산형 데이터인데 summary 에서는 숫자로 취급되어 있음. 뒤에서 as.factor 을 써서 범주형 Factor 로 바꾸어 주어야 함.

 

# seed 고정. 결과값이 case에 따라 바뀌지 않도록 case를 고정시킨다

# 훈련용, 테스트용 데이터셋으로 나누기

> library(caret)
> set.seed(2022)

> idx <- createDataPartition(ds$Reached.on.Time_Y.N, p=0.7)
> summary(idx)
          Length Class  Mode   
Resample1 7700   -none- numeric

 

# Resample1 을 train, test 로 구분해서 넣기

> x_train <- ds[idx$Resample1, ]
> x_test <- ds[-idx$Resample1, ]

 

> str(x_train)
'data.frame': 7700 obs. of  12 variables:
 $ ID                 : int  1 2 3 4 7 8 9 10 11 12 ...
 $ Warehouse_block    : chr  "D" "F" "A" "B" ...
 $ Mode_of_Shipment   : chr  "Flight" "Flight" "Flight" "Flight" ...
 $ Customer_care_calls: int  4 4 2 3 3 4 3 3 3 4 ...
 $ Customer_rating    : int  2 5 2 3 4 1 4 2 4 5 ...
 $ Cost_of_the_Product: int  177 216 183 176 250 233 150 164 189 232 ...
 $ Prior_purchases    : int  3 2 4 4 3 2 3 3 2 3 ...
 $ Product_importance : chr  "low" "low" "low" "medium" ...
 $ Gender             : chr  "F" "M" "M" "M" ...
 $ Discount_offered   : int  44 59 48 10 3 48 11 29 12 32 ...
 $ Weight_in_gms      : int  1233 3088 3374 1177 2371 2804 1861 1187 2888 3253 ...
 $ Reached.on.Time_Y.N: int  1 1 1 1 1 1 1 1 1 1 ...
> str(x_test)
'data.frame': 3299 obs. of  12 variables:
 $ ID                 : int  5 6 15 17 18 24 29 30 31 35 ...
 $ Warehouse_block    : chr  "C" "F" "A" "C" ...
 $ Mode_of_Shipment   : chr  "Flight" "Flight" "Flight" "Flight" ...
 $ Customer_care_calls: int  2 3 4 3 5 4 2 5 3 4 ...
 $ Customer_rating    : int  2 1 3 4 5 3 3 4 4 2 ...
 $ Cost_of_the_Product: int  184 162 152 143 227 211 234 183 266 227 ...
 $ Prior_purchases    : int  3 3 3 2 3 3 4 2 2 4 ...
 $ Product_importance : chr  "medium" "medium" "low" "medium" ...
 $ Gender             : chr  "F" "F" "M" "F" ...
 $ Discount_offered   : int  46 12 43 6 36 12 44 36 38 22 ...
 $ Weight_in_gms      : int  2484 1417 1009 1194 3952 3922 3134 3819 2741 2460 ...
 $ Reached.on.Time_Y.N: int  1 1 1 1 1 1 1 1 1 1 ...

 

 

# Reached.on.Time 은 중간값이 없다. 1이냐 0 이냐 둘 밖에 없으므로 이렇게 나올 수가 없다.

> summary(x_train$Reached.on.Time_Y.N)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
 0.0000  0.0000  1.0000  0.6004  1.0000  1.0000 

 

# Factor 로 변경

> x_train$Reached.on.Time_Y.N <- as.factor(x_train$Reached.on.Time_Y.N)
> x_test$Reached.on.Time_Y.N <- as.factor(x_test$Reached.on.Time_Y.N)
> summary(x_test$Reached.on.Time_Y.N)
   0    1 
1359 1940 

 

# 데이터 preprocess (scale 작업)

# scale이 없을 경우 변수 X1, X2 가 만약 범위가 다르다면 ex) X1(0~1), X2(1000~10000)   X1은 아무리 중요한 변수라도 모델에 미치는 중요도가 낮게 나올 것이다. 이로 인해 데이터를 표준화 or 정규화 작업을 해 주어야 한다.

# 정규화  (데이터의 범위를 0~1로 변환, 최대-최소 정규화)

 - preProcess(x, method = "range")

값 - 최소 / 최대 - 최소

 - 정규화 한 후 preProcess 객체를 predict 함수를 사용해 데이터셋에 적용해야 한다.

# 표준화 (평균이 0, 분산이 1 인 정규분포)

 - scale(x)

 - preProcess(x, method = c("center, "scale")) 

값 - 평균(center) / 표준편차(scale)

 

# 데이터 정규화

> x_train_scale <- preProcess(x_train, method="range")
> x_test_scale <- preProcess(x_train, method="range")

 

# 정규화된 데이터를 predict 함수로 데이터셋으로 만들어주기

> scaled_x_train <- predict(x_train_scale, x_train)
> scaled_x_test <- predict(x_test_scale, x_test)

 

# 모델 분석

# 1. 로지스틱 회귀분석 (범주형이므로)

> md_glm <- glm(Reached.on.Time_Y.N~., data = scaled_x_train, family='binomial')

> pred_glm <- predict(md_glm, scaled_x_test, type = 'response')

# 일반회귀가 아닌 범주형 로지스틱 회귀일때만  family = binomial, type=response

 

> pred_glm_result <- ifelse(pred_glm >= 0.5, 1, 0)
> pred_glm_result <- as.factor(pred_glm_result)

# 결과도 범주형으로 정리, 0.5보다 높은 확률이면 1, 아니면 0 으로 변경

 

#결과 분석
> confusionMatrix(pred_glm_result, scaled_x_test$Reached.on.Time_Y.N)


Confusion Matrix and Statistics

          Reference
Prediction    0    1
         0  819  596
         1  540 1344
                                          
               Accuracy : 0.6557          
                 95% CI : (0.6392, 0.6719)
    No Information Rate : 0.5881          
    P-Value [Acc > NIR] : 9.467e-16       
                                          
                  Kappa : 0.2936          
                                          
 Mcnemar's Test P-Value : 0.1027          
                                          
            Sensitivity : 0.6026          
            Specificity : 0.6928          
         Pos Pred Value : 0.5788          
         Neg Pred Value : 0.7134          
             Prevalence : 0.4119          
         Detection Rate : 0.2483          
   Detection Prevalence : 0.4289          
      Balanced Accuracy : 0.6477          
                                          
       'Positive' Class : 0            

 

# SVM 분석

> library(e1071)
> md_svm <- svm(Reached.on.Time_Y.N~., scaled_x_train)
> pred_svm <- predict(md_svm, scaled_x_test, type='response')
> confusionMatrix(pred_svm, x_test$Reached.on.Time_Y.N)
Confusion Matrix and Statistics

          Reference
Prediction    0    1
         0 1298  936
         1   61 1004
                                          
               Accuracy : 0.6978          
                 95% CI : (0.6818, 0.7134)
    No Information Rate : 0.5881          
    P-Value [Acc > NIR] : < 2.2e-16       
                                          
                  Kappa : 0.4311          
                                          
 Mcnemar's Test P-Value : < 2.2e-16       
                                          
            Sensitivity : 0.9551          
            Specificity : 0.5175          
         Pos Pred Value : 0.5810          
         Neg Pred Value : 0.9427          
             Prevalence : 0.4119          
         Detection Rate : 0.3935          
   Detection Prevalence : 0.6772          
      Balanced Accuracy : 0.7363          
                                          
       'Positive' Class : 0             

 

# 랜덤 포레스트 모델

> library(randomForest)
> md_rf <- randomForest(Reached.on.Time_Y.N~., scaled_x_train, ntree=300)
> pred_rf <- predict(md_rf, scaled_x_test, type='response')
> confusionMatrix(pred_rf, x_test$Reached.on.Time_Y.N)
Confusion Matrix and Statistics

          Reference
Prediction    0    1
         0 1010  723
         1  349 1217
                                         
               Accuracy : 0.6751         
                 95% CI : (0.6588, 0.691)
    No Information Rate : 0.5881         
    P-Value [Acc > NIR] : < 2.2e-16      
                                         
                  Kappa : 0.3558         
                                         
 Mcnemar's Test P-Value : < 2.2e-16      
                                         
            Sensitivity : 0.7432         
            Specificity : 0.6273         
         Pos Pred Value : 0.5828         
         Neg Pred Value : 0.7771         
             Prevalence : 0.4119         
         Detection Rate : 0.3062         
   Detection Prevalence : 0.5253         
      Balanced Accuracy : 0.6853         
                                         
       'Positive' Class : 0   

 

# 로지스틱 회귀 AUC : 0.6557 

# SVM 회귀 AUC : 0.6978  

# 랜덤 포레스트 회귀 AUC : 0.6751      

 

# 데이터 저장

> total = as.data.frame(cbind(x_test$ID, pred_svm))
> View(total)
> names(total) <- c("ID", 'Reached.on.time_Y.N')
> head(total)
   ID Reached.on.time_Y.N
2   2                   2
3   3                   2
13 13                   2
21 21                   2
22 22                   2
23 23                   2
> write.csv(total, "Train_result_00001.csv", row.names = FALSE)

 

 

댓글

💲 추천 글