Python 利用扩展窗口计算熊猫的主成分分析

Python 利用扩展窗口计算熊猫的主成分分析,python,pandas,numpy,scikit-learn,pca,Python,Pandas,Numpy,Scikit Learn,Pca,我有以下市场数据框架: 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

我有以下市场数据框架:

                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的特征值和向量,这样我就可以通过保持一致的符号来消除噪声。这是我当前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)