PCA 对具有许多 ID 但每个日期仅派生一个主成分的面板数据
PCA on panel data with many IDs but only derive one principal component for each date
为了简单和可重现性,这里是生成样本数据集的代码:
import pandas as pd
import numpy as np
from sklearn.decomposition import PCA
data = pd.DataFrame({
'year':['2001', '2002', '2003', '2004', '2005', '2001', '2002', '2003', '2004', '2005', '2006', '2001', '2002', '2003', '2004', '2005', '2006', '2001', '2002', '2003', '2004', '2005', '2006'],
'ID':[1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4],
'factor':[np.nan, 0.45, .4, .2, -0.3, np.nan, .11, .21, .4, .01, np.nan, -0.32, 0.93, 0.66, np.nan, 0.5, np.nan, -0.12, -0.14, 0.36, 0.3, 0.21, np.nan],
'return':[.11, 0.45, .34, .52, -0.93, 1.54, 1.01, .31, np.nan, -0.01, -0.2, -0.32, 1.94, 0.66, 1.34, 1.5, 0.1, np.nan, -0.14, 0.36, 0.3, 0.2, 0.9],
'size': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23],
'age': [0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 11, 0, 2, 3, 15, 16, 17, 0, 1, 1, 2, 22, 23]})
data = data.set_index(['ID', 'year'])
data = data.fillna(0)
X = data.drop('return', axis = 1)
pca = PCA(n_components = 1)
PCA_PCs = pca.fit(X).transform(X)
当我对数据应用 PCA 时,我希望每年获得单个主成分,但我却得到:
print(PCA_PCs)
[[-11.16171282]
[-10.43225691]
[ -9.7023714 ]
[ -8.972357 ]
[ -7.467887 ]
[ -7.99143666]
[ -6.48749078]
[ -5.75773415]
[ -5.02805484]
[ -4.2978772 ]
[ 4.17395234]
[ -4.20443643]
[ -1.92727222]
[ -0.42299984]
[ 9.59778387]
[ 11.10139466]
[ 12.60586466]
[ -0.417883 ]
[ 1.08617458]
[ 1.81558753]
[ 3.31967947]
[ 19.53355614]
[ 21.03777697]]
这对应于数据框中的总行数。有什么方法可以汇总或计算每年的加权主成分吗?
您可以将第一个主成分作为新列分配给原始 DataFrame
。然后你可以按年份和平均值分组。
data.assign(pc1=PCA_PCs[:, 0]).groupby('year')['pc1'].mean()
# year
# 2001 -5.726232
# 2002 -4.321416
# 2003 -3.502976
# 2004 -0.337490
# 2005 4.588059
# 2006 12.400073
# Name: pc1, dtype: float64
这是总结多年数据的有效方法,与矢量 space 的任何平均值一样多。这基本上意味着如果您信任并理解您的主要组件,它就会起作用。
第一主成分通常只衡量平均值,因此您可能只是表明 2006 年比其他年份大。服用更多成分可能会有所帮助。
PCA_PCs = PCA(n_components = 2).fit_transform(X)
pca_df = pd.DataFrame(PCA_PCs, columns=['pc1', 'pc2'])]
years = data.reset_index()[['year']]
year_pca_df = pd.concat([years, pca_df], axis=1)
year_pca_df.groupby('year').mean()
# pc1 pc2
# year
# 2001 -5.726232 1.043865
# 2002 -4.321416 1.204462
# 2003 -3.502976 1.831200
# 2004 -0.337490 0.588444
# 2005 4.588059 -2.055726
# 2006 12.400073 -3.482995
为了简单和可重现性,这里是生成样本数据集的代码:
import pandas as pd
import numpy as np
from sklearn.decomposition import PCA
data = pd.DataFrame({
'year':['2001', '2002', '2003', '2004', '2005', '2001', '2002', '2003', '2004', '2005', '2006', '2001', '2002', '2003', '2004', '2005', '2006', '2001', '2002', '2003', '2004', '2005', '2006'],
'ID':[1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4],
'factor':[np.nan, 0.45, .4, .2, -0.3, np.nan, .11, .21, .4, .01, np.nan, -0.32, 0.93, 0.66, np.nan, 0.5, np.nan, -0.12, -0.14, 0.36, 0.3, 0.21, np.nan],
'return':[.11, 0.45, .34, .52, -0.93, 1.54, 1.01, .31, np.nan, -0.01, -0.2, -0.32, 1.94, 0.66, 1.34, 1.5, 0.1, np.nan, -0.14, 0.36, 0.3, 0.2, 0.9],
'size': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23],
'age': [0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 11, 0, 2, 3, 15, 16, 17, 0, 1, 1, 2, 22, 23]})
data = data.set_index(['ID', 'year'])
data = data.fillna(0)
X = data.drop('return', axis = 1)
pca = PCA(n_components = 1)
PCA_PCs = pca.fit(X).transform(X)
当我对数据应用 PCA 时,我希望每年获得单个主成分,但我却得到:
print(PCA_PCs)
[[-11.16171282]
[-10.43225691]
[ -9.7023714 ]
[ -8.972357 ]
[ -7.467887 ]
[ -7.99143666]
[ -6.48749078]
[ -5.75773415]
[ -5.02805484]
[ -4.2978772 ]
[ 4.17395234]
[ -4.20443643]
[ -1.92727222]
[ -0.42299984]
[ 9.59778387]
[ 11.10139466]
[ 12.60586466]
[ -0.417883 ]
[ 1.08617458]
[ 1.81558753]
[ 3.31967947]
[ 19.53355614]
[ 21.03777697]]
这对应于数据框中的总行数。有什么方法可以汇总或计算每年的加权主成分吗?
您可以将第一个主成分作为新列分配给原始 DataFrame
。然后你可以按年份和平均值分组。
data.assign(pc1=PCA_PCs[:, 0]).groupby('year')['pc1'].mean()
# year
# 2001 -5.726232
# 2002 -4.321416
# 2003 -3.502976
# 2004 -0.337490
# 2005 4.588059
# 2006 12.400073
# Name: pc1, dtype: float64
这是总结多年数据的有效方法,与矢量 space 的任何平均值一样多。这基本上意味着如果您信任并理解您的主要组件,它就会起作用。
第一主成分通常只衡量平均值,因此您可能只是表明 2006 年比其他年份大。服用更多成分可能会有所帮助。
PCA_PCs = PCA(n_components = 2).fit_transform(X)
pca_df = pd.DataFrame(PCA_PCs, columns=['pc1', 'pc2'])]
years = data.reset_index()[['year']]
year_pca_df = pd.concat([years, pca_df], axis=1)
year_pca_df.groupby('year').mean()
# pc1 pc2
# year
# 2001 -5.726232 1.043865
# 2002 -4.321416 1.204462
# 2003 -3.502976 1.831200
# 2004 -0.337490 0.588444
# 2005 4.588059 -2.055726
# 2006 12.400073 -3.482995