이전글 : https://oikon-mundi.tistory.com/448
위 글에서는 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 |