기본 콘텐츠로 건너뛰기

[ML] 결정트리(Decision Tree) 모델

데이터를 목록화하여 함수 적용_python

연속변수와 명목변수가 혼합된 데이터 셋의 경우 연속변수를 명목변수로 목록화하여 어떤 통계량을 계산할 필요가 있습니다. 특히 anova 등 분산분석시 이러한 과정이 필요합니다.

다음의 자료는 각 환기 시스템에 대한 유량을 측정한 것입니다. 
import numpy as np
import pandas as pd
>>> ven
    folate ventilation
1      243  N2O+O2,24h
2      251  N2O+O2,24h
3      275  N2O+O2,24h
...
20     270      O2,24h
21     293      O2,24h
22     328      O2,24h

위 자료들 중 ventilation의 종류에 따라 float를 분류할 목적입니다. ventilation의 종류는 pd.unique() 함수를 사용하여 알아볼수 있습니다. 이 함수는 데이터들 중 고유한 부분만을 추출하여 반환합니다. 
>>> idx=pd.unique(ven["ventilation"])
>>> idx
array(['N2O+O2,24h', 'N2O+O2,op', 'O2,24h'], dtype=object)

즉 ventilation은 3가지로 값들로 구성되어 있으며 이에 따라 float를 구분하여 각각에 대한 통계량을 계산하고자 합니다. 
우선 반복문을 사용하여 다음과 같이 분류하고 각 분류된 그룹화된 데이터셋에서 평균과 합을 계산할 수 있습니다. 
ven1={}
...: mu={}
...: tot={}
...: for i in idx:
...:     ven1[i]=ven[ven.iloc[:,1]==i].iloc[:,0]
...:     mu[i]=np.mean(ven1[i])
...:     tot[i]=np.sum(ven1[i])

ven1
Out[30]: 
{'N2O+O2,24h': 1    243
 2    251
 3    275
 4    291
 5    347
 6    354
 7    380
 8    392
 Name: folate, dtype: int64, 'N2O+O2,op': 9     206
 10    210
 11    226
 12    249
 13    255
 14    273
 15    285
 16    295
 17    309
 Name: folate, dtype: int64, 'O2,24h': 18    241
 19    258
 20    270
 21    293
 22    328
 Name: folate, dtype: int64}

mu
Out[31]: {'N2O+O2,24h': 316.625, 'N2O+O2,op': 256.44444444444446, 'O2,24h': 278.0}

tot
Out[32]: {'N2O+O2,24h': 2533, 'N2O+O2,op': 2308, 'O2,24h': 1390}

위와 같은 과정은 groupby()와 agg()함수로 간단하게 계산할 수 있습니다. 
DataFrame.groupby(['목록화할 변수이름'])
위 데이터에 시행하면 다음과 같습니다. 
x=ven.groupby(['ventilation'])

list(x)
Out[53]: 
[('N2O+O2,24h',    folate ventilation
  1     243  N2O+O2,24h
  2     251  N2O+O2,24h
  3     275  N2O+O2,24h
  4     291  N2O+O2,24h
  5     347  N2O+O2,24h
  6     354  N2O+O2,24h
  7     380  N2O+O2,24h
  8     392  N2O+O2,24h), ('N2O+O2,op',     folate ventilation
  9      206   N2O+O2,op
  10     210   N2O+O2,op
  11     226   N2O+O2,op
  12     249   N2O+O2,op
  13     255   N2O+O2,op
  14     273   N2O+O2,op
  15     285   N2O+O2,op
  16     295   N2O+O2,op
  17     309   N2O+O2,op), ('O2,24h',     folate ventilation
  18     241      O2,24h
  19     258      O2,24h
  20     270      O2,24h
  21     293      O2,24h
  22     328      O2,24h)]
위의 형태는 ventilation을 목록화 하였기 때문에 그에 따라 분류된 것을 볼 수 있습니다. 위 결과에 apply()함수를 적용하여 각 그룹의 평균과 합을 계산하여 보면 다음과 같습니다. 

mu=x.apply(np.mean, axis=0)

mu
Out[55]: 
                 folate
ventilation            
N2O+O2,24h   316.625000
N2O+O2,op    256.444444
O2,24h       278.000000

tot=x.apply(np.sum, axis=0)

tot
Out[57]: 
             folate                                        ventilation
ventilation                                                           
N2O+O2,24h     2533  N2O+O2,24hN2O+O2,24hN2O+O2,24hN2O+O2,24hN2O+O2...
N2O+O2,op      2308  N2O+O2,opN2O+O2,opN2O+O2,opN2O+O2,opN2O+O2,opN...
O2,24h         1390                     O2,24hO2,24hO2,24hO2,24hO2,24h

DataFrame.apply(함수, axis=0): apply()함수는 DataFrame 객체에 지정된 행 또는 열 (axis=1, 0)에 따라 인수로 전달한 함수를 적용합니다. axis의 기본값은 열(0)입니다.

apply() 함수와 유사하지만 여러개의 함수를 동시에 적용할 수 있다는 점이 다른 함수로 
DataFrame.agg(함수들, axis=0) 

ven.iloc[:,0].agg([np.sum, np.mean])
Out[63]: 
sum     6231.000000
mean     283.227273
Name: folate, dtype: float64

위와 같이 대상이 되는 DataFrame이 목록화된 것이라면 위의 객체 x에 apply()를 적용한 결과와 동일할 것입니다. 볼까요.
x.agg([np.sum, np.mean])
Out[64]: 
            folate            
               sum        mean
ventilation                   
N2O+O2,24h    2533  316.625000
N2O+O2,op     2308  256.444444
O2,24h        1390  278.000000

데이터의 목록화는 위에서 소개한 방법외에 피봇테이블을 작성하여 통계량을 계산할 수 있습니다. 사실 피봇테이블은 목록변수 2개에 대한 각각의 해당하는 값들을 나타내기 위한 것입니다. 
df = pd.DataFrame({'foo': ['one','one','one','two','two','two'],
...:                        'bar': ['A', 'B', 'C', 'A', 'B', 'C'],
...:                        'baz': [1, 2, 3, 4, 5, 6]})
...: df.pivot(index='foo', columns='bar', values='baz')
Out[83]: 
bar  A  B  C
foo         
one  1  2  3
two  4  5  6
위 데이터는 foo, bar 두개의 목록변수에 따라 baz의 값을 나타낼 수 있습니다. 
Data.Frame.pivot(index, columns, value) : 결과에서 행이름(index), 열이름(columns), 표 내부의 값(values)

그러면 위의 결과 표에서 각 목록화된 변수 별로 통계량을 산출하기 위해서는 위에서 소개한 apply() 또는 agg() 함수를 사용할 수 있습니다. 위의 결과 객체의 type은 다음과 같이 DataFrame입니다. 
type(y)
Out[88]: pandas.core.frame.DataFrame
이 구조에서 apply(), agg() 함수를 사용하여 각 그룹에 대한 통계량을 계산할 수 있습니다.

 y.apply(np.mean, axis=1)
Out[18]:
foo
one    2.0
two    5.0
dtype: float64

y.apply(np.mean, axis=0)
Out[19]:
bar
A    2.5
B    3.5
C    4.5
dtype: float64

y.agg([np.mean, np.sum])
Out[20]:
        A    B    C
mean  2.5  3.5  4.5
sum   5.0  7.0  9.0
y.T.agg([np.mean, np.sum])
Out[21]:
      one   two
mean  2.0   5.0
sum   6.0  15.0

위의 과정을 한번에 적용할 수 있는 함수로 다음을 사용할 수 있습니다.
 pd.pivot_table(data, index=None, columns=None, aggfunc='mean',...)
위 함수는 지정한 index 또는 columns에 따라 분류된 값들에 함수(aggfunc)들을 적용합니다. 적용할 함수는 여러함수를 리스트 형식으로 지정할 수 있으며 기본은 np.mean 즉 평균을 계산입니다. 
pd.pivot_table(df, index='foo')
Out[84]: 
     baz
foo     
one    2
two    5
pd.pivot_table(df, index='bar')
Out[85]: 
     baz
bar     
A    2.5
B    3.5
C    4.5

pd.pivot_table(df, columns='bar')
Out[23]:
bar    A    B    C
baz  2.5  3.5  4.5

pd.pivot_table(df, index='bar', aggfunc=[np.mean, np.sum])
Out[26]:
    mean sum
     baz baz
bar       
A    2.5   5
B    3.5   7
C    4.5   9

댓글

이 블로그의 인기 게시물

[Linear Algebra] 유사변환(Similarity transformation)

유사변환(Similarity transformation) n×n 차원의 정방 행렬 A, B 그리고 가역 행렬 P 사이에 식 1의 관계가 성립하면 행렬 A와 B는 유사행렬(similarity matrix)이 되며 행렬 A를 가역행렬 P와 B로 분해하는 것을 유사 변환(similarity transformation) 이라고 합니다. $$\tag{1} A = PBP^{-1} \Leftrightarrow P^{-1}AP = B $$ 식 2는 식 1의 양변에 B의 고유값을 고려한 것입니다. \begin{align}\tag{식 2} B - \lambda I &= P^{-1}AP – \lambda P^{-1}P\\ &= P^{-1}(AP – \lambda P)\\ &= P^{-1}(A - \lambda I)P \end{align} 식 2의 행렬식은 식 3과 같이 정리됩니다. \begin{align} &\begin{aligned}\textsf{det}(B - \lambda I ) & = \textsf{det}(P^{-1}(AP – \lambda P))\\ &= \textsf{det}(P^{-1}) \textsf{det}((A – \lambda I)) \textsf{det}(P)\\ &= \textsf{det}(P^{-1}) \textsf{det}(P) \textsf{det}((A – \lambda I))\\ &= \textsf{det}(A – \lambda I)\end{aligned}\\ &\begin{aligned}\because \; \textsf{det}(P^{-1}) \textsf{det}(P) &= \textsf{det}(P^{-1}P)\\ &= \textsf{det}(I)\end{aligned}\end{align} 유사행렬의 특성 유사행렬인 두 정방행렬 A와 B는 'A ~ B' 와 같

[matplotlib] 히스토그램(Histogram)

히스토그램(Histogram) 히스토그램은 확률분포의 그래픽적인 표현이며 막대그래프의 종류입니다. 이 그래프가 확률분포와 관계가 있으므로 통계적 요소를 나타내기 위해 많이 사용됩니다. plt.hist(X, bins=10)함수를 사용합니다. x=np.random.randn(1000) plt.hist(x, 10) plt.show() 위 그래프의 y축은 각 구간에 해당하는 갯수이다. 빈도수 대신 확률밀도를 나타내기 위해서는 위 함수의 매개변수 normed=True로 조정하여 나타낼 수 있다. 또한 매개변수 bins의 인수를 숫자로 전달할 수 있지만 리스트 객체로 지정할 수 있다. 막대그래프의 경우와 마찬가지로 각 막대의 폭은 매개변수 width에 의해 조정된다. y=np.linspace(min(x)-1, max(x)+1, 10) y array([-4.48810153, -3.54351935, -2.59893717, -1.65435499, -0.70977282, 0.23480936, 1.17939154, 2.12397372, 3.0685559 , 4.01313807]) plt.hist(x, y, normed=True) plt.show()

R 미분과 적분

내용 expression 미분 2차 미분 mosaic를 사용한 미분 적분 미분과 적분 R에서의 미분과 적분 함수는 expression()함수에 의해 생성된 표현식을 대상으로 합니다. expression expression(문자, 또는 식) 이 표현식의 평가는 eval() 함수에 의해 실행됩니다. > ex1<-expression(1+0:9) > ex1 expression(1 + 0:9) > eval(ex1) [1] 1 2 3 4 5 6 7 8 9 10 > ex2<-expression(u, 2, u+0:9) > ex2 expression(u, 2, u + 0:9) > ex2[1] expression(u) > ex2[2] expression(2) > ex2[3] expression(u + 0:9) > u<-0.9 > eval(ex2[3]) [1] 0.9 1.9 2.9 3.9 4.9 5.9 6.9 7.9 8.9 9.9 미분 D(표현식, 미분 변수) 함수로 미분을 실행합니다. 이 함수의 표현식은 expression() 함수로 생성된 객체이며 미분 변수는 다음 식의 분모의 변수를 의미합니다. $$\frac{d}{d \text{변수}}\text{표현식}$$ 이 함수는 어떤 함수의 미분의 결과를 표현식으로 반환합니다. > D(expression(2*x^3), "x") 2 * (3 * x^2) > eq<-expression(log(x)) > eq expression(log(x)) > D(eq, "x") 1/x > eq2<-expression(a/(1+b*exp(-d*x))); eq2 expression(a/(1 + b * exp(-d * x))) > D(eq2, "x") a * (b * (exp(-d * x) * d))/(1 + b