본문 바로가기
공부/기초통계

Cross correlation (비교상관계수) python

by signature95 2022. 4. 5.
728x90
반응형

이전에 다룬 ACF, PACF 이후 작성하는 부분입니다.

2022.01.20 - [공부/통계학] - ACF (auto-correlative function, 자기상관함수) python

 

ACF (auto-correlative function, 자기상관함수) python

자기상관함수는 보통 시계열 분석으로 도출된 잔차가 시간의 흐름에 따라 상관성이 존재하는지 확인하는 함수이다. 물론 ARIMA를 시행할 때, p,q를 설정하기 위해서도 ACF를 활용하기도 한다. 이번

signature95.tistory.com

2022.01.20 - [공부/통계학] - PACF (Partial Auto Correlation Function, 편자기상관함수) python

 

ACF (auto-correlative function, 자기상관함수) python

자기상관함수는 보통 시계열 분석으로 도출된 잔차가 시간의 흐름에 따라 상관성이 존재하는지 확인하는 함수이다. 물론 ARIMA를 시행할 때, p,q를 설정하기 위해서도 ACF를 활용하기도 한다. 이번

signature95.tistory.com

 

자기상관계수, 편자기상관계수와 다르게 비교상관계수는 두 변수에 대해 시차를 적용시켜 상관계수를 도출하는 것입니다.

 

바로 코드를 보도록하겠습니다.

 

# 예시 : 마케팅 비용과 수익간의 상관성 분석
import statsmodels.api as sm
import numpy as np
import matplotlib.pyplot as plt

marketing = np.array([3, 4, 5, 5, 7, 9, 13, 15, 12, 10, 8, 8])
revenue = np.array([21, 19, 22, 24, 25, 29, 30, 34, 37, 40, 35, 30]) 


cc = sm.tsa.stattools.ccf(marketing, revenue, adjusted=False)

for i in range(len(cc)):
    print(f'마케팅 비용과 수익의 {i}번째 기간 후 상관계수 값 : {cc[i] : .5f}')

for i in range(len(cc)):
    plt.scatter(i, cc[i])
plt.axvline(x=0, color='k' ,linestyle = ':') # draw x =0 axes 
plt.axhline(y=0, color='k' ,linestyle = ':') # draw y =0 axes
plt.title('Cross correlation (marketing, revenue)')
plt.xlabel('after k period')
plt.ylabel('cross corr')
plt.show()

결과

마케팅 비용과 수익의 0번째 기간 후 상관계수 값 :  0.77109
마케팅 비용과 수익의 1번째 기간 후 상관계수 값 :  0.46239
마케팅 비용과 수익의 2번째 기간 후 상관계수 값 :  0.19352
마케팅 비용과 수익의 3번째 기간 후 상관계수 값 : -0.06066
마케팅 비용과 수익의 4번째 기간 후 상관계수 값 : -0.28160
마케팅 비용과 수익의 5번째 기간 후 상관계수 값 : -0.44531
마케팅 비용과 수익의 6번째 기간 후 상관계수 값 : -0.49159
마케팅 비용과 수익의 7번째 기간 후 상관계수 값 : -0.35784
마케팅 비용과 수익의 8번째 기간 후 상관계수 값 : -0.15697
마케팅 비용과 수익의 9번째 기간 후 상관계수 값 : -0.03430
마케팅 비용과 수익의 10번째 기간 후 상관계수 값 :  0.01588
마케팅 비용과 수익의 11번째 기간 후 상관계수 값 :  0.00704

 

이를 보면 시차가 증가할 수록 감소하다가 다시 영향력이 거의 없어지는 결과를 볼 수 있습니다.

 

사용한 라이브러리로는 statsmodels의 api에서 추출한 함수로 ccf입니다.

 

ccf의 하이퍼파라미터를 보면 다음과 같습니다.

    """
    The cross-correlation function.

    Parameters
    ----------
    x, y : array_like
        The time series data to use in the calculation.
    adjusted : bool
        If True, then denominators for cross-correlation is n-k, otherwise n.
    fft : bool, default True
        If True, use FFT convolution.  This method should be preferred
        for long time series.

    Returns
    -------
    ndarray
        The cross-correlation function of x and y.

    Notes
    -----
    If adjusted is true, the denominator for the autocovariance is adjusted.
    """

여기서 adjuted를 True로 설정하는 경우, 비교 상관계수의 분모가 n-k가 된다고 합니다. (사실 어떤 차이가 존재하는지 아직은 정확히 모르겠습니다)

 

또한 fft의 경우, True로 설정한다면, Fast Fourier Transform으로 고속퓨리에 변환을 의미하고 convolution은 합성곱을 의미합니다. 여기서는 시계열의 길이가 긴 경우 설정하도록 권장하고 있습니다. (퓨리에 변환 이게 공대에서 나오는데 시간에 대한 신호함수를 주파수에 대한 식으로 변환하는 것이라합니다... 잘 모르겠습니다 ㅠㅠ)

 

하지만, 시차 상관계수를 경제에 적용한다면 다음과 같이 해석할 수 있습니다. 

 

예시를 보면, 통화정책 시행으로 M2 감소 충격시, 유가증권 시장에 어떤 영향을 미치고, 지속성은 어떠한지에 대해 알 수 있는 것이지요.

 

그래서 국내 10년물 국체와 코스피지수의 비교 상관계수를 코드로 구현해보았습니다.

 

financedatareader (fdr) 라이브러리를 활용하여 2010년부터 2020년 초까지 데이터를 불러옵니다.

import FinanceDataReader as fdr

kr10YT = fdr.DataReader('KR10YT=RR','2010-01-01', '2020-01-01')
ks11 = fdr.DataReader('KS11', '2010-01-01', '2020-01-01')

여기서 이제 전처리를 시행하는데, 순서는 다음과 같습니다.

  1. 10년간 영업일 전체를 불러오고 기존 데이터와 병합한다.
  2. 직전값으로 Nan 값을 채워준다.
  3. 월말 영업일 데이터 (ex. 2018.1.31이 토요일이면 2018.1.30)를 제외한 나머지는 drop한다.
  4. 전월 대비 변화율을 구한다.

이게 코드로 일일이 다 보여드리면 좀 길어져서 ks11에 대해서만 업로드하려 합니다. (변수명만 변경해주면 전처리 형태는 동일하기에 10년물 국체에도 무관함)

# 월말 영업일 데이터만 추출 시행

# 데이터 인덱스(날짜)를 컬럼으로 형성 후 처음과 끝을 추출
ks11 = ks11.reset_index()
start_date = ks11['Date'].astype(str).iloc[0]
end_date = ks11['Date'].astype(str).iloc[-1]

# 날짜 처음과 끝에서 영업일 기준 freq 적용 후 데이터 프레임 형성
date_all = pd.date_range(start_date, end_date, freq='B').to_frame().rename(columns={0:'Date'}).reset_index(drop=True)

# 데이터 병합 (영업일 date와 10년물 국체 병합)
df_all = pd.merge(date_all,ks11,how='left')

# 직전 값으로 NaN 값 채우기
df_all = df_all.fillna(method='ffill')


# 마지막 영업일 제외후 나머지 drop
df_ks11 = df_all.set_index(df_all['Date'])

# 각 월당 마지막 영업일 도출
month_end = pd.date_range('2010-01-01', '2020-01-01', freq='BM')

# 마지막 영업일 제외후 나머지 drop
ks11_BM = df_ks11[df_ks11['Date'].isin(month_end)].reset_index(drop=True)
ks11_BM = ks11_BM.set_index(ks11_BM['Date'])
ks11_BM = ks11_BM.drop(columns='Date')

# 전월대비 수익률 도출 (pct_change 사용, %로 표현하기 위해 100을 곱해준다)

kospi_bm_return = ks11_BM['Close'].pct_change().dropna()
kospi_bm_return = pd.DataFrame(kospi_bm_return) * 100
kospi_bm_return.head()

>>>


		Close
Date	
2010-02-26	-0.489881
2010-03-31	6.162751
2010-04-30	2.877396
2010-05-31	-5.759779
2010-06-30	3.475400

 

그리고 이 데이터에 대해 비교상관계수를 구하면 다음과 같습니다.

 

# 예시 : 마케팅 비용과 수익간의 상관성 분석
import statsmodels.api as sm
import numpy as np
import matplotlib.pyplot as plt

kr10yt_data = np.array(kr10yt_bm_return['Close'])
ks11_data = np.array(kospi_bm_return['Close'])


cc = sm.tsa.stattools.ccf(ks11_data, kr10yt_data, adjusted=False, fft=True)

for i in range(12):
    print(f'10년물 국체수익률과 코스피지수 수익률의 {i}개월 후 상관계수 값 : {cc[i] : .5f}')

for i in range(12):
    plt.scatter(i, cc[i])
plt.axvline(x=0, color='k' ,linestyle = ':') 
plt.axhline(y=0, color='k' ,linestyle = ':')
plt.title('Cross correlation (KS11, KR10YT)')
plt.xlabel('after k period')
plt.ylabel('cross corr')
plt.show()

>>>

10년물 국체수익률과 코스피지수 수익률의 0개월 후 상관계수 값 :  0.12547
10년물 국체수익률과 코스피지수 수익률의 1개월 후 상관계수 값 :  0.14507
10년물 국체수익률과 코스피지수 수익률의 2개월 후 상관계수 값 : -0.13085
10년물 국체수익률과 코스피지수 수익률의 3개월 후 상관계수 값 :  0.02708
10년물 국체수익률과 코스피지수 수익률의 4개월 후 상관계수 값 :  0.07631
10년물 국체수익률과 코스피지수 수익률의 5개월 후 상관계수 값 :  0.09027
10년물 국체수익률과 코스피지수 수익률의 6개월 후 상관계수 값 :  0.01290
10년물 국체수익률과 코스피지수 수익률의 7개월 후 상관계수 값 :  0.01621
10년물 국체수익률과 코스피지수 수익률의 8개월 후 상관계수 값 : -0.04429
10년물 국체수익률과 코스피지수 수익률의 9개월 후 상관계수 값 : -0.04753
10년물 국체수익률과 코스피지수 수익률의 10개월 후 상관계수 값 : -0.00915
10년물 국체수익률과 코스피지수 수익률의 11개월 후 상관계수 값 : -0.06412

 

이를 확인해보면 10년물 국체 금리가 변화할때, 1개월 후 KOSPI 지수의 변화하는 정도를 나타내는 상관계수가 가장 높은 절댓값을 가지는 것을 알 수 있습니다. 그리고 점차 상관성은 감소하는 형태를 보이고 있습니다.

 

물론 이는 11개월 시차까지 적용된 상태이기에 시차를 더 적용시키면 그 이후의 시차에 대해서도 알 수 있을 것입니다. 

또한, 어떤 것이 선행지수이고 후행지수인지 알 수 있을 것입니다.

만약 여기서 시차 0일때 상관성이 가장 높게 나왔다면 x,y 변수는 동행지수에 해당하는 것이죠.

 

이번 포스트는 여기서 마치도록 하겠습니다.

 

728x90

댓글