기본 콘텐츠로 건너뛰기

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

회귀분석을 위한 주가데이터 만들기2_ DataForRegressionS

포스트 DayInInterRetStockS()의 클래스를 소개하는 글에서 원 일일주가데이터로 부터 새로운 변수들을 생성하여 새로운 객체를 만들었습니다.
그 결과를 바탕으로 회귀분석을 위한 데이터 생성을 계속해 보면 다음과 같습니다. 
이전의 데이터 경향으로 새로운 값을 예측하는 것이 회귀분석의 기본방향이라면 위에서 생성된 데이터들 중에 예측에 사용되는 변수들(독립변수)과 예측을 위한 변수(반응변수)를 구분해야 겠지요.
이전에 생성한 객체의 변수명은 다음과 같습니다. 
>>> da.columns
Index(['Open', 'High', 'Low', 'Close', 'Volume', 'Close:Open:ret',
       'Close:High:ret', 'Close:Low:ret', 'Open:intRet', 'High:intRet',
       'Low:intRet', 'Close:intRet', 'Volume:intRet', 'olag', 'hlag', 'llag',
       'clag', 'vlag'],
      dtype='object')
위의 변수들 중에 반응변수의 대상은 'Open', 'High', 'Low', 'Close'중의 하나의 변수가 될 것입니다. 
예로서 Close를 반응변수로 한다면 나머지 변수들은 독립변수가 됩니다. 독립과 반응변수는 날들로 모형의 설계는 
'당일까지의 독립변수들의 성격들로 다음날의 반응변수를 예측'
으로 구축할 것입니다. 
이러한 구축을 위해 먼저 독립변수들과 반응변수를 구분하고 이 두 대상의 날짜를 다르게 하여 한 행에 위치시켜야 합니다. 
또한 데이터 구축 후 분석을 위해 sklearn 패키지의 함수들을 사용할 것입니다. 이 함수들의 인수들은 np.array 객체가 대상이 됩니다. 데이터는 모두 동일한 형식으로 반환됩니다. 
아래 함수에서 독립변수들은 표준화됩니다. 이것은 각 변수들 간의 scale의 차이로 효과를 제거하기 위한 것으로 별도의 함수를 만들어 사용해도 되지만 sklearn에거 제공하는 함수를 사용하는 것이 편리합니다. 그러므로 다음과 같이 관련된 모듈을 부착합니다. 

>>> from sklearn import preprocessing, cross_validation, svm

def DataRegS1(da, deCol, stdize=1, shiftD=1):
        d_lag=da.shift(shiftD)
        if type(deCol) !=str:
            deCol=d_lag.columns[deCol]
        d=pd.concat([d_lag.drop([deCol], axis=1), da[deCol]],axis=1)
        d=d.dropna()
        ind=np.array(d.drop([deCol], axis=1))
        de=np.array(d[deCol])
        new=da.drop([deCol], axis=1).ix[len(da)-1,:]
        if stdize==0:
            ind=ind
            new=new
        else:
            ind=preprocessing.scale(ind)
            ind1_mu=np.mean(ind, axis=0)
            ind1_sd=np.array([np.std(ind[:,i]) for i in range(ind.shape[1])])   
            new=np.array((new-ind1_mu)/ind1_sd)
        return(ind, de, new) 

반환되는 결과는 독립변수(ind), 반응변수(de), 최종적으로 사용되는 변수(new) 입니다. 
new는 원 자료의 마지막 행입니다. 

>>> cpind, cpde, cpnew=DataRegS1(da, 3)
>>> cpind[:2,:]
array([[-1.9438624 , -2.0539455 , -1.97377112, -0.34551834, -0.04362155,
         0.48868343, -0.36767019, -0.7867308 , -1.11823123, -0.202969  ,
        -0.13116804, -0.78078135, -1.39300768, -1.33736073, -1.4881869 ,
        -1.4835275 ,  0.33076086],
       [-2.13940978, -2.2486958 , -2.21829566,  0.30033078, -0.27026372,
         0.16433956, -0.51126002, -0.67611283, -0.69818054, -0.92970837,
        -0.90124321,  0.44802125, -1.58394452, -1.58412679, -1.45874598,
        -1.47638189, -0.15688456]])

>>> cpde[:2,]
array([16405, 16340], dtype=int64)

>>> cpnew 
array([  1.74300000e+04,   1.74850000e+04,   1.68400000e+04,
         1.59008480e+07,  -3.38496845e+00,  -3.68887618e+00,
         2.60999799e-16,  -4.00000000e-01,  -1.04697227e+00,
        -3.71640938e+00,  -3.88127854e+00,   2.50238248e+02,
         1.75800000e+04,   1.76300000e+04,   1.74850000e+04,
         1.75850000e+04,   5.32917100e+06])

회귀분석을 위한 데이터가 생성되었습니다. 

다음으로 위 함수에서 사용한 데이터 da를 사용하여 이전에 사용한 bootstrap 방법을 적용하여 데이터 수를 증가시켜 회귀분석을 위한 데이터를 생성하는 함수를 만들어 봅니다. 이 함수는 이전에 작성한 mkbtsSampleS()(bootstrap 방법 참조, 위 링크된 포스트)과 위 DataRegS1()와의 결합으로 실행될 수 있습니다.
DataRegS1() 함수에서 사용된 pd.shift(number)는 데이터프레임 형태의 데이터에서 지정된 수 만큼 행을 아래로(양수), 위로(음수) 이동시킵니다. 
다음을 볼까요?
>>> x=np.random.randint(0, 10, 10).reshape(5,2)
>>> x=pd.DataFrame(x)
>>> x
   0  1
0  4  8
1  5  8
2  1  7
3  3  8
4  6  9
>>> x.shift(1)
     0    1
0  NaN  NaN
1  4.0  8.0
2  5.0  8.0
3  1.0  7.0
4  3.0  8.0

>>> x.shift(-1)
     0    1
0  5.0  8.0
1  1.0  7.0
2  3.0  8.0
3  6.0  9.0
4  NaN  NaN

이 함수를 사용하여 분석에 대응되는 독립변수들과 반응변수를 한 행에 정리한 후 이들의resampling의 bootstrap 방법 즉,  mkbtsSampleS()를 적용합니다. 그 적용후에 DataRegS1에 그 결과를 적용합니다. 다음과 같이 class를 생성하여 사용합니다.

1. 클래스 BtsDataRegS에 사용할 객체를 전달하여 클래스 객체를 생성합니다.
2. 클래스 객체에 반응변수로 사용할 열 번호 또는 열 이름을 전달하여 독립변수들과 반응변수간의 날짜를 변경시켜 분석을 위한 데이터 형태로 만듭니다. 이 과정에서 반응변수는 생성된 데이터셋의 마지막 열에 위치하게 됩니다.
3. bootstrap 방법을 적용하여 샘플의 수를 증가시킵니다.
4. 3번에서 생성된 데이터를 독립변수와 반응변수, 그리고 최종적으로 사용하게 될 독립변수들을 생성합니다. 이 과정에서 독립변수들의 표준화를 적용할 수 있습니다.

class BtsDataRegS:
    def __init__(self, da):
        self.da=da
    def MkIndDeS(self, deCol, shiftD=1):
        self.deCol=deCol
        d_lag=self.da.shift(shiftD)
        if type(self.deCol) !=str:
            self.deCol=d_lag.columns[self.deCol]
        d=pd.concat([d_lag.drop([self.deCol], axis=1), self.da[self.deCol]],axis=1)
        self.d=d.dropna()
        return(self.d)
    def MkbtsS(self, smpN=10, repN=500):
        n=len(self.d)
        spId=np.random.choice(n, size=smpN, replace=True)
        sample=np.array(np.mean(self.d.iloc[spId,:], 0)).reshape(1,self.d.shape[1])
        for i in range(repN+1):
            spId=np.random.choice(n, size=smpN, replace=True)
            sp=np.array(np.mean(self.d.iloc[spId,:], 0)).reshape(1,self.d.shape[1])
            sample=np.r_[sample,sp]
        self.sample=sample
        return(self.sample)
    def MkData(self,stdize=1):
        ind=self.sample[:, :(self.sample.shape[1]-1)]
        self.de=self.sample[:, (self.sample.shape[1]-1)]
        new=self.da.drop([self.deCol], axis=1).iloc[len(self.da)-1,:]
        if stdize==0:
            self.ind=ind
            self.new=new
        else:
            self.ind=preprocessing.scale(ind)
            daS=preprocessing.scale(self.da.drop(["Close"], axis=1))
            self.new=daS[(daS.shape[0]-1),:]
        return(self.ind, self.de, self.new)

위 클래스를 적용하기 위해 위에서 생성된 데이터 da의 마지막 5행을 사용합니다.
>>> trg=da.tail(5)
>>> test=BtsDataRegS(trg)
>>> inde=test.MkIndDeS(3)
>>> sm=test.MkbtsS()
>>> ind, de, new=test.MkData()
>>> new.shape
(17,)
>>> ind.shape
(502, 17)
>>> de.shape
(502,)

위에서 생성된 cpde와 500회 반복한 샘플 de, 1000회 반복한 샘플의 정규성을 확인하여 보면 다음과 같습니다. (그래프 작성을 위한 사용자 정의 함수 histNormalplotS)
먼저 bootstrap을 적용하지 않은 경우;
(0.98360045319196987, 1.3322215876321926e-42)
 상관계수와 상관분석의 p-value가 결과로 반환됩니다. 
500회 반복한 샘플;

(0.98502701750103172, 0.0)
1000회 반복한 샘플;


(0.99757571983444615, 0.0)
반복회수가 증가할 수록 정규성의 부합정도가 증가됨을 알 수 있습니다.
이는 회귀분석의 기본 가정 즉, 반응변수가 정규분포에 부합한다는 것을 만족시키는 것입니다. 이 가정은 분석자 입장에서 데이터의 모수를 아는 상태에 이루어지므로 분석 결과를 적용하는 합리적 근거가 됩니다. 

댓글

이 블로그의 인기 게시물

[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