使用扩展窗口计算pandas中的PCA

时间:2018-04-03 23:04:25

标签: python pandas numpy scikit-learn pca

我有以下DataFrame的市场数据:

                DP       PE        BM       CAPE
date
1990-01-31  0.0345  13.7235  0.503474   6.460694
1990-02-01  0.0346  13.6861  0.504719   6.396440
1990-02-02  0.0343  13.7707  0.501329   6.440094
1990-02-05  0.0342  13.7676  0.500350   6.460417
1990-02-06  0.0344  13.6814  0.503550   6.419991
...            ...      ...       ...        ...
2015-04-28  0.0201  18.7347  0.346717  26.741581
2015-04-29  0.0202  18.6630  0.348080  26.637641
2015-04-30  0.0205  18.4793  0.351642  26.363959
2015-05-01  0.0204  18.6794  0.347814  26.620701
2015-05-04  0.0203  18.7261  0.346813  26.695087

对于这个时间序列中的每一天,我想使用向后看的扩展窗口来计算最大的PCA组件。以下代码从上面给出了DF:

def get_PCAprice_daily(start_date = '1990-06-08', end_date = '2015-09-30'):
    start_date = pd.to_datetime(start_date, yearfirst=True) - pd.DateOffset(years=1)
    end_date = pd.to_datetime(end_date, yearfirst=True)
    if(start_date > end_date):
        print("Invalid date range provided")
        return 1
    dp = get_DP_daily().reset_index()
    pe = get_PE_daily().reset_index()
    bm = get_BM_daily().reset_index()
    cape = get_CAPE_daily().reset_index()
    variables = [pe, bm, cape]
    for var in variables:
        dp = dp.merge(var, how='left', on='date')
    df = dp.set_index('date')
    df = df.loc[start_date:end_date].dropna()

我自己尝试了几种不同的方式,但是似乎没有人能够访问PCA的特征值和向量,这样我就可以做this post所说的通过保持一致的符号来消除噪音。这是我当前PCA值的图表,并且符号切换是一个非常大的问题:

PCA

我错误的PCA计算代码:

window = 252*5
# Initialize an empty df of appropriate size for the output
df_pca = pd.DataFrame( np.zeros((df.shape[0] - window + 1, df.shape[1])) )
# Define PCA fit-transform function
# Note: Instead of attempting to return the result,
#       it is written into the previously created output array.
def rolling_pca(window_data):
    pca = PCA()
    transf = pca.fit_transform(df.iloc[window_data])
    df_pca.iloc[int(window_data[0])] = transf[0,:]
    return True

# Create a df containing row indices for the workaround
df_idx = pd.DataFrame(np.arange(df.shape[0]))

# Use `rolling` to apply the PCA function
_ = df_idx.rolling(window).apply(rolling_pca)
df = df.reset_index()
df = df.join(pd.DataFrame(df_pca[0]))
df.rename(columns={0: 'PCAprice'}, inplace=True)
df['PCAprice'] = df['PCAprice'].shift(window)

0 个答案:

没有答案
相关问题