본문 바로가기
R

22. 데이터 가공

by #Glacier 2018. 11. 21.
반응형

안녕하세요~ 오늘도 쓸쓸히 혼자 인사합니다ㅋㅋ

오늘은 데이터 가공에 대해서 알아보겠습니다.


1. Data Exploration


​#제가 매 번 언급하듯이, 데이터를 일단 loading한 순간, 데이터가 어떻게 생겼는지 알아보아야 합니다. 

 아무것도 모르고 데이터를 가공할 수는 없죠.

 앞서서 사용해봤던 reshape패키지의 tips 데이터를 불러들입니다.


install.packages("reshape")

library(reshape)

data(tips, package="reshape")


#요렇게 불러들인 후에, 데이터를 살펴보는 방법은 앞에서도 자주 사용했던 방식들로 살펴봅니다.


1) head(), tail()

2) summary()

3) str()

4) tabplot()


#일단 첫 번째 head()함수부터 알아볼게요

#head()함수의 default값은 6줄까지 보여줍니다. 저는 10을 사용해봤습니다.


head(tips, 10)


   total_bill  tip    sex smoker day   time size
1       16.99 1.01 Female     No Sun Dinner    2
2       10.34 1.66   Male     No Sun Dinner    3
3       21.01 3.50   Male     No Sun Dinner    3
4       23.68 3.31   Male     No Sun Dinner    2
5       24.59 3.61 Female     No Sun Dinner    4
6       25.29 4.71   Male     No Sun Dinner    4
7        8.77 2.00   Male     No Sun Dinner    2
8       26.88 3.12   Male     No Sun Dinner    4
9       15.04 1.96   Male     No Sun Dinner    2
10      14.78 3.23   Male     No Sun Dinner    2


tail(tips)

 tail(tips)
    total_bill  tip    sex smoker  day   time size
239      35.83 4.67 Female     No  Sat Dinner    3
240      29.03 5.92   Male     No  Sat Dinner    3
241      27.18 2.00 Female    Yes  Sat Dinner    2
242      22.67 2.00   Male    Yes  Sat Dinner    2
243      17.82 1.75   Male     No  Sat Dinner    2
244      18.78 3.00 Female     No Thur Dinner    2​

#tips또한 default값은 6줄입니다.​

#다음, summary()함수는 각 변수의 요약을 보여줍니다.


#Numeric변수는 : 최솟값, 1사분위-3사분위 값, 중간값, 평균값, 최댓값, NA의 개수

 Factor변수 : 요인별 개수

 Character변수 : Length(개수) 표시


summary(tips)
   total_bill         tip             sex      smoker      day    
 Min.   : 3.07   Min.   : 1.000   Female: 87   No :151   Fri :19  
 1st Qu.:13.35   1st Qu.: 2.000   Male  :157   Yes: 93   Sat :87  
 Median :17.80   Median : 2.900                          Sun :76  
 Mean   :19.79   Mean   : 2.998                          Thur:62  
 3rd Qu.:24.13   3rd Qu.: 3.562                                   
 Max.   :50.81   Max.   :10.000                                   
     time          size     
 Dinner:176   Min.   :1.00  
 Lunch : 68   1st Qu.:2.00  
              Median :2.00  
              Mean   :2.57  
              3rd Qu.:3.00  
              Max.   :6.00  

 

#저렇게 Numeric인지 Factor인지 Character인지 등을 알아보기위한 함수로, str()함수가 있죠


str(tips)

'data.frame':   244 obs. of  7 variables:
 $ total_bill: num  17 10.3 21 23.7 24.6 ...
 $ tip       : num  1.01 1.66 3.5 3.31 3.61 4.71 2 3.12 1.96 3.23 ...
 $ sex       : Factor w/ 2 levels "Female","Male": 1 2 2 2 1 2 2 2 2 2 ...
 $ smoker    : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 1 1 1 1 ...
 $ day       : Factor w/ 4 levels "Fri","Sat","Sun",..: 3 3 3 3 3 3 3 3 3 3 ...
 $ time      : Factor w/ 2 levels "Dinner","Lunch": 1 1 1 1 1 1 1 1 1 1 ...
 $ size      : int  2 3 3 2 4 4 2 4 2 2 ...


#이렇게 나타납니다. 그다음은 tabplot입니다.

install.packages("tabplot")
library(tabplot)

#tabplot은 데이터가 어떻게 입체적으로 분포되어 있는지 보기 위한 방법입니다.

tableplot(tips, cex=1.8)




#요렇게 나타나죠~ 쑥 훑어보면, total_bill이 클수록 tips와 size가 커짐을 알 수 있습니다.

#tableplot을 이용하면 값의 변화에 따른 전체적인 다른 변수와의 관계도 파악할 수 있어 시각적인 효과가 도움이 됩니다.


2. 변수 중요도

# 변수의 중요도는 개발 중인 모델에 준비된 데이터를 기준으로 한 번에 여러 개의 변수를 평가하는 방식.

# 평가 방법은 1) 패키지를 이용한 평가 2) 모델링 결과 평가( 많이 쓰이는 방법 ) 이 있다.

# 변수 평가 시에는 Ex 분류모델 개발을 위해 100개의 변수를 만드는 경우 한 번에 투입하게 되면 속도가 느리거나

  메모리 부족현상이 일어나기 때문에 50개씩 나누어 실행한 후 최종 모델 개발하는 것이 현명하다.


​사례)

# 사례로 사용하는 패키지는 klaR패키지의 greedy.wilks 입니다.


# greedy.wilks는 모델링을 정의-> 변수를 stepwise하게 투입 -> 의미있는 변수를 순서대로 보여줍니다. 

  또, 효율적으로 정확도를 최소한으로 희생하면서 초기 모델링을 빨리 실행할 수 있게 해줍니다.


# 일반적인 접근 방법은 데이터 사이즈를 증대시켜 가면서 해당 시스템에서 어느 정도 시간이 소요되는지 performance test를 해봄

  -> 분석 시나리오를 결정

# 이런 접근을 하지 않는 경우, 초기 분석은 가능한 시스템 성능문제로 모델링을 완성하지 못할 수도 있다(참고!)


# 이제 사용해보겠습니다. 패키지 설치는 기본적으로 바로바로~

install.packages("klaR")

library(klaR)

data(wine, package="HDclassif")

head(wine)


  class    V1   V2   V3   V4  V5   V6   V7   V8   V9  V10  V11  V12  V13
1     1 14.23 1.71 2.43 15.6 127 2.80 3.06 0.28 2.29 5.64 1.04 3.92 1065
2     1 13.20 1.78 2.14 11.2 100 2.65 2.76 0.26 1.28 4.38 1.05 3.40 1050
3     1 13.16 2.36 2.67 18.6 101 2.80 3.24 0.30 2.81 5.68 1.03 3.17 1185
4     1 14.37 1.95 2.50 16.8 113 3.85 3.49 0.24 2.18 7.80 0.86 3.45 1480
5     1 13.24 2.59 2.87 21.0 118 2.80 2.69 0.39 1.82 4.32 1.04 2.93  735
6     1 14.20 1.76 2.45 15.2 112 3.27 3.39 0.34 1.97 6.75 1.05 2.85 1450


#wine데이터에 대한 설명은 전에 설명했었죠~

#저렇게 많은 변수들을 이제 평가하기 위해 작업을 합니다.


wine$class <- factor(wine$class)

gw_obj<-greedy.wilks(class~ . , data=wine, niveau=0.1)

#여기서 niveau는 level for the approximate F-test decision이라고 되어있네요. F테스트의 유의수준을 말하는 것 같군요~

gw_obj


Formula containing included variables:

class ~ V7 + V10 + V13 + V1 + V2 + V12 + V4 + V3 + V11 + V8 + 
    V6
<environment: 0x04ac3ce0>


Values calculated in each step of the selection procedure:

   vars Wilks.lambda F.statistics.overall p.value.overall F.statistics.diff
1    V7   0.27222451            233.92587    3.598586e-50        233.925873
2   V10   0.10249051            184.75493    1.014146e-84        144.080253
3   V13   0.04776254            206.19793   5.138343e-111         99.114675
4    V1   0.03715530            180.07869   4.876154e-118         24.551631
5    V2   0.03188288            157.33465   1.957156e-121         14.138991
6   V12   0.02895773            138.16711   9.089025e-123          8.586222
7    V4   0.02615005            125.15459   2.415657e-124          9.072598
8    V3   0.02237129            119.40215   6.772558e-128         14.188535
9   V11   0.02101388            109.44766   4.538891e-128          5.393777
10   V8   0.02031904             99.85455   3.129930e-127          2.838279
11   V6   0.01965857             91.98314   2.104278e-126          2.771790
   p.value.diff
1  3.598586e-50
2  0.000000e+00
3  0.000000e+00
4  4.111362e-10
5  2.065335e-06
6  2.796580e-04
7  1.804022e-04
8  2.013054e-06
9  5.365968e-03
10 6.135329e-02
11 6.544712e-02


# 요렇게 손쉽게 V7 + V10 + V13 + V1 + V2 + V12 + V4 + V3 + V11 + V8 + V6 순서로 의미있는 변수를 알려줍니다.

vars

the names of the variables in the final model in the order of selection.

Wilks.lambda    

the appropriate Wilks' lambda for the selected variables.

F.statistics

 .overall 

the approximated F-statistic for the so far selected model.

p.value

 .overall 

the appropriate p-value of the F-statistic.

F.statistics

.diff 

the approximated F-statistic of the partial Wilks's lambda (for comparing the model including the new variable with the model not including it).

p.value.diff

the appropriate p-value of the F-statistic of the partial Wilk's lambda.

--요렇게 참고적으로 보시면 될 것 같군요~

#klaR 패키지의 plineplot은 특정 변수가 주어졌을 때 class가 어떻게 분류되는지 error rate를 돌려주고, 

 graphical하게 결과를 보여주는 기능을 합니다. 


 wine_impVar<-wine[,c("V7","V10","class")]

 plineplot(class ~ . , data=wine_impVar, method = "lda" , x= wine_impVar$V7, xlab="V7")






[1] 0.1011236


# 요렇게 나옵니다. 그림으로 보면, 0~1까지는 class3이 분포, 1~2까지는 class2, 3이 섞여 있고, 2~3에는 class1, 2가 섞여 있고,

   3 이상에서는 class 1 이 주로 분포하고 있음을 알 수 있습니다. 조금 더 보기 쉽게 요약하면

# 0~1 : class3

# 1~2 : class2, 3

# 2~3 : class1, 2

# 3이상 : class 1


# 이제 V7을 위의 구역별로 Binning하고, Table을 만듭니다.


 summary(wine$V7)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  0.340   1.205   2.135   2.029   2.875   5.080 
V7_breaks<-c(0,1,2,3,6)

# 위에서 나온 구역을 지정해 주기 위해 0, 1 , 2, 3, 6 을 V7_breaks라는 변수안에 집어넣습니다.

wine$V7_bin<-cut(wine$V7, V7_breaks)

#wine$V7_bin (Binning)에 wine내부의 V7을 V7_breaks로 cut합니다. 그리고 테이블화 합니다.

table(wine$class, wine$V7_bin)
   
    (0,1] (1,2] (2,3] (3,6]
  1     0     0    34    25
  2     2    31    32     6
  3    38    10     0     0

# 이렇게 Class 별로 분포가 위의 결과와 일치함을 확인할 수 있습니다.


# klaR패키지의 NaiveBayes는 변수별 분포를 그래프로 보여줍니다.

mN<-NaiveBayes(class ~. , data=wine[,c(1,8,11,14,2)])

par(mfrow=c(2,2))


# 여기서는 wine data의 class, V7, V10, V13, V1 을 고른 것이구요~ 위의 결과처럼 가장 중요한 변수 위에서 4가지를 고른 겁니다!

   par(mfrow=c(2,2))는 예~전에 한 번 말씀드렸듯이, 그래프를 그리기 위한 칸을 설정하는 겁니다 가로2, 세로2의 총 4칸이죠~


plot(mN)






# 이렇게 총4개의 그래프를 그려냅니다. 클래스별 변수들의 분포를 알기 쉽겠죠~? !


# 그 다음은 Binning입니다. Binning에 대해 서적의 설명을 참고하도록 하겠습니다. Binning에 대해 쉽게 설명하면 분류작업이라고 하면 되겠죠.

 - 변수별 분포를 그래프로 보여줌.

 - Continuous variable보다 categorial variable이 이해가 용이할 수 있음. -> 일정 크기로 Binning해서 활용.

 - Binning의 개수가 증가하면 정확도가 높아지나 , 속도가 느려지고, overestimation될 수 있음. (과다추정)

 - 40개 정도 Binning -> 이를 target과 비교하여 유사한 performance를 보이는 인접구간을 merge하는 방식 적용

 - klaR에는 이러한 상세 기능까지 포함하고 있지 않음.

TIP) Binning은 무조건 해야 하는 것은 아니나 해석을 용이하게 하는 데 도움이 됨. 그러기 위해서는 Binning 구간을 잘 정하거나, 업무특성에 맞게

      해석이나 과거 연구자료와 연관이 되게 구간화해야 한다고 합니다.


install.packages("party")

library(party)

data(wine, package="HDclassif")

wine$class<-factor(wine$class)

summary(wine$V7)

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  0.340   1.205   2.135   2.029   2.875   5.080


wine$V7_c<-cut(wine$V7, 10)

# 요렇게 wine$V7_c에다가 wine$V7을 10으로 Binning하도록 합니다.

wine_ctr<-ctree(class ~. , data=wine)
# wine_ctr변수에 cut한것의 tree모형을 나타내도록 명령하고, class변수에 대해 모든 변수를 지정합니다.


plot(wine_ctr)




# 이렇게 의사결정나무모형처럼 tree모형으로 나옵니다.

# 제가 노트북으로 포스팅하느라, 화면크기에 한계가있어서(ㅋㅋ) 조금 짤렸는데 R에서 잘 안보이시면 창을 Drag&Drop으로 키워주시면 정상적으로 나타납니다.

# 시각화 결과, root node에서 왼쪽으로는 0.335~1.29까지 분기되고, 오른쪽으로는 1.29~4.13, 4.61~5.08까지 분기되는 것을 확인할 수 있습니다.

# 다른 방법으로 확인하면,

wine_ctr


         Conditional inference tree with 6 terminal nodes

Response:  class 
Inputs:  V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12, V13, V7_c 
Number of observations:  178

1) V7_c == {(0.335,0.814], (0.814,1.29]}; criterion = 1, statistic = 213.945
  2) V11 <= 0.89; criterion = 1, statistic = 23.079
    3)*  weights = 43 
  2) V11 > 0.89
    4)*  weights = 8 
1) V7_c == {(1.29,1.76], (1.76,2.24], (2.24,2.71], (2.71,3.18], (3.18,3.66], (3.66,4.13], (4.61,5.08]}
  5) V13 <= 750; criterion = 1, statistic = 91.349
    6) V10 <= 4.8; criterion = 1, statistic = 49.374
      7)*  weights = 60 
    6) V10 > 4.8
      8)*  weights = 7 
  5) V13 > 750
    9) V1 <= 13.05; criterion = 0.999, statistic = 16.317
      10)*  weights = 9 
    9) V1 > 13.05
      11)*  weights = 51 

 

# 요렇게 나옵니다. 투입변수로 저렇게 V1~ V7_c까지 들어간 것을 알수 있구요~ 위와 같은 결과들을 볼 수 있습니다.


# 조금 복잡하죠? 저도 마찬가집니다. 하지만 복습하면 더 잘 알 수 있겠죠~

# 오늘은 데이터 가공에 대해서 알아보았는데요~ 다음 시간에는 기초 분석 및 데이터 관리에 대해서 알아보도록 하겠습니다~!

반응형