이전글 : https://oikon-mundi.tistory.com/448
파이썬: PCA로 종합 경제 지표 만들기 (hard data index construction)
주성분분석(PCA)는 여러 차원의 데이터를 하나의 차원으로 압축하는데 종종 쓰이는 기법이다. PCA를 통해 여러 경제 지표를 하나의 종합 인덱스로 압축하는 것도 가능하다. 방법론과 배경은 나중
oikon-mundi.tistory.com
위 글에서는 PCA로 경제지표를 만들었는데, 기간이 추가되면 기존의 경제지표수치도 변화한다는 점이 문제였다. 즉 작년에 기록한 2013년도의 지표수치가 -2였어도, 올해 기록한 2013년도 지표 수치는 3이 될 수 있다.
이러한 부분을 보완하기 위해 롤링 PCA(혹은 moving window PCA)를 써보기로 했다. 즉 일정 기간의 창(window)를 정해두고, 개별 창마다 PCA를 수행해서 값을 따오는 것이다. 예를 들면 2017.01~2019.01의 24개월 데이터를 하나의 창으로 두고 PCA를 수행해서 2019.01에 대응되는 PC1값을 형성한다. 그 다음 2017.02~2019.02의 24개월 데이터를 창으로 두고 다시 PCA를 수행하고, 2019.02의 PC1값을 채워넣어가는 방식이다.
코랩에 엑셀 데이터를 업로드하는 파트는 생략한다.
1.로우df에 인덱스 붙이기
df = pd.read_excel(excel_direc, header =0, engine= 'openpyxl')
display(df)
df.set_index('observation date', drop= True, inplace =True )
df.sort_index(ascending = False, inplace= True )
display(df)
df 디스플레이 값
observation date 미국:개인가처분소득-SAAR 미국:자동차판매:트럭 미국:제조업 신규수주:내구재-SA 미국:실업률 미국:재고율(출하대비 재고):제조업-SA 미국:산업생산지수-SA 미국:심각한회수불량률(90일이상연체 미국:신규독주택판매 미국:건설기성액 미국:기업이익 미국:소매판매 미국:4주평균 신규 실업수당청구건수-NSA 미국:설비가동률:제조업-SA 미국:수입 미국:수출
0 2023-06-30 19853.44 547.0 288353.0 3.8 1.49 102.25 1.89 73 167.44 2688.02 613207.0 238110.50 77.97 915.19 738.87
1 2023-05-31 19853.44 566.0 288353.0 3.4 1.49 102.80 1.89 73 167.44 2688.02 631059.0 204279.25 78.32 915.19 738.87
2 2023-04-30 19766.76 538.0 283311.0 3.1 1.50 103.28 1.89 60 156.63 2688.02 588220.0 223385.60 78.49 915.19 738.87
3 2023-03-31 19708.94 486.0 279837.0 3.6 1.48 102.66 1.89 63 150.25 2688.02 604084.0 223530.00 77.79 915.19 738.87
4 2023-02-28 19619.11 516.0 270825.0 3.9 1.49 102.57 1.89 56 133.23 2721.29 529374.0 218125.50 78.45 969.73 766.70
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
709 1964-05-31 473.94 NaN NaN 4.8 NaN 28.62 NaN 52 6.35 44.41 NaN NaN NaN 6.41 8.40
710 1964-04-30 471.41 NaN NaN 5.3 NaN 28.46 NaN 49 6.00 44.41 NaN NaN NaN 6.41 8.40
711 1964-03-31 468.51 NaN NaN 5.9 NaN 28.00 NaN 53 5.33 44.41 NaN NaN NaN 6.41 8.40
712 1964-02-29 457.38 NaN NaN 6.2 NaN 28.00 NaN 46 4.51 40.69 NaN NaN NaN 6.66 8.38
713 1964-01-31 455.28 NaN NaN 6.4 NaN 27.81 NaN 39 4.85 40.69 NaN NaN NaN 6.66 8.38
714 rows × 16 columns
미국:개인가처분소득-SAAR 미국:자동차판매:트럭 미국:제조업 신규수주:내구재-SA 미국:실업률 미국:재고율(출하대비 재고):제조업-SA 미국:산업생산지수-SA 미국:심각한회수불량률(90일이상연체 미국:신규독주택판매 미국:건설기성액 미국:기업이익 미국:소매판매 미국:4주평균 신규 실업수당청구건수-NSA 미국:설비가동률:제조업-SA 미국:수입 미국:수출
observation date
2023-06-30 19853.44 547.0 288353.0 3.8 1.49 102.25 1.89 73 167.44 2688.02 613207.0 238110.50 77.97 915.19 738.87
2023-05-31 19853.44 566.0 288353.0 3.4 1.49 102.80 1.89 73 167.44 2688.02 631059.0 204279.25 78.32 915.19 738.87
2023-04-30 19766.76 538.0 283311.0 3.1 1.50 103.28 1.89 60 156.63 2688.02 588220.0 223385.60 78.49 915.19 738.87
2023-03-31 19708.94 486.0 279837.0 3.6 1.48 102.66 1.89 63 150.25 2688.02 604084.0 223530.00 77.79 915.19 738.87
2023-02-28 19619.11 516.0 270825.0 3.9 1.49 102.57 1.89 56 133.23 2721.29 529374.0 218125.50 78.45 969.73 766.70
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
1964-05-31 473.94 NaN NaN 4.8 NaN 28.62 NaN 52 6.35 44.41 NaN NaN NaN 6.41 8.40
1964-04-30 471.41 NaN NaN 5.3 NaN 28.46 NaN 49 6.00 44.41 NaN NaN NaN 6.41 8.40
1964-03-31 468.51 NaN NaN 5.9 NaN 28.00 NaN 53 5.33 44.41 NaN NaN NaN 6.41 8.40
1964-02-29 457.38 NaN NaN 6.2 NaN 28.00 NaN 46 4.51 40.69 NaN NaN NaN 6.66 8.38
1964-01-31 455.28 NaN NaN 6.4 NaN 27.81 NaN 39 4.85 40.69 NaN NaN NaN 6.66 8.38
2.
#데이터 열에 대응되는 전처리 방법 딕셔너리 형성
transform_method_dic = {
'미국:개인가처분소득-SAAR': 'deltalog',
'미국:자동차판매:트럭': 'loglevel',
'미국:제조업 신규수주:내구재-SA': 'deltalog',
'미국:실업률':'loglevel',
'미국:재고율(출하대비 재고):제조업-SA' : 'loglevel',
'미국:산업생산지수-SA' : 'deltalog',
'미국:심각한회수불량률(90일이상연체': 'loglevel',
'미국:신규독주택판매' : 'deltalog',
'미국:건설기성액': 'deltalog',
'미국:기업이익' : 'deltalog',
'미국:소매판매' : 'deltalog',
'미국:4주평균 신규 실업수당청구건수-NSA' : 'deltalog', # 고민해봐야함
'미국:설비가동률:제조업-SA': 'loglevel',
'미국:수입' : 'deltalog',
'미국:수출' : 'deltalog',
}
display(transform_method_dic )
3.데이터 열별로변환
columns = list(df)
print(columns)
for i in range(0,len(columns)) :
if transform_method_dic[ columns[i] ] == 'loglevel' :
df.iloc[:, i] = np.log10( df.iloc[:, i] )
elif transform_method_dic[ columns[i] ] == 'deltalog' :
df.iloc[:, i] = np.log10( df.iloc[:, i] ) - np.log10( df.iloc[:, i].shift(periods=-1))
i=i+1
display(df)
4.
from sklearn.decomposition import PCA
pca = PCA(n_components=2) # 주성분을 몇개로 할지 결정
#Local PCA를 돌릴 때 시계 길이 (window_size = 24-> 24개월 )
window_size = 36
#PC1을 모을 Global 데이터프레임 df_PC 형성
arr = np.zeros(( df.shape[0] -window_size, 2))
df_PC = pd.DataFrame(data = arr,columns = ['PC1','PC2'] )
df_PC.index = index_date = df.index.tolist()[:df.shape[0] -window_size ] #df_PC의 인덱스는 로우데이터프레임 df의 인덱스를 리스트로 변환하고, 이 리스트를 다시 로우데이터 행수- 윈도우 사이즈 만큼만 잘라서 넣기
5. 반복문으로 개별 창마다 PCA를 수행하고 그 결과를 df_PC에 저장
-개별 창마다 PCA를 수행하면서 데이터가 없는 열은 제외한다. 압축하려는 경제지표들이 발표되기 시작한 시점이 다 다르므로, 시간 흐름에 따라 반영하는 경제지표들이 추가되는 식으로 PCA를 수행했다. 이런 방식이 얼마나 유의미한지는 논의 여지가 있다.
#0부터 로우데이터 행수-윈도우사이즈를 반복해서 PCA를 돌림
try :
for i in range( 0, df.shape[0] - window_size) :
df_w = df.iloc[i : i+ window_size ]
df_w.dropna(axis=1, how= 'any', inplace = True)
#df_w.dropna(axis=0)
#정규화
norm_df = (df_w - df_w.mean())/df_w.std()
norm_df = norm_df.dropna()
#PCA 수행
PC = pca.fit_transform(norm_df)
PCdf = pd.DataFrame(data=PC, columns = ['PC1','PC2']) # 개별 PCA의 결과인 Local PC1의 데이터프레임
PCdf['PC1'] = PCdf['PC1'].apply(lambda x: x*-1)
PCdf['PC2'] = PCdf['PC2'].apply(lambda x: x*-1)
df_PC.iloc[i] = PCdf.iloc[0] # Local PCA 첫 값을 Global PC1 데이터프레임에 집어넣기
except: print(i)
#반복문 끝
display(df_PC)
6.그래프화
#주성분1을 그래프화
import matplotlib.pyplot as plt
#import matplotlib.dates as dates
#import matplotlib.ticker as ticker
import matplotlib.dates as mdates
plt.figure(figsize=(19,6))
plt.plot(index_date, df_PC.iloc[:, 0], label= 'PC1 index')
plt.gca().xaxis.set_major_locator(mdates.YearLocator(base=2)) # gca로 축정보를 가져오고 축단위를 설정
plt.gca().xaxis.set_minor_locator(mdates.YearLocator(base=1))
plt.legend()
plt.grid(True)
plt.title('Hard data Index (Rolling PCA, window size={}m)'.format(window_size)) #format 함수로 {}에 window_size 변수를 이름으로 넣기
만들기는 했지만 유용성은 그다지 높지 않은 것같고, 가끔씩 재미삼아 참조해보려 한다. 적재계수까지 확인해보고 싶은데 당장은 그냥 두려 한다. 롤링 PCA 방법론에 대해 유의해야할 점을 좀 더 찾아보고싶지만 당장 눈에 띄는 것은 없다.
'엑셀_파이썬_기타 코딩' 카테고리의 다른 글
분 단위 데이터 분석 -판다스 피벗테이블 활용 (0) | 2023.09.30 |
---|---|
엑셀 차트 그리는 도구 (엑셀 사용자 foam) (0) | 2023.09.12 |
엑셀 반복 행/열 출력 (0) | 2023.07.11 |
파이썬 Lagged variable Linear Regression (0) | 2023.06.17 |
파이썬: PCA로 종합 경제 지표 만들기 (hard data index construction) (0) | 2023.06.15 |