Я пытаюсь сохранить первые три ПК, коэффициенты, оценки, собственные значения и остатки (восстановленные исходные данные) последнего дня каждого 20-дневного скользящего окна в наборе данных ежедневных возвратов для 20 индексов CDS с различными периодами истечения и 108торговые дни.Я пытаюсь кодировать весь алгоритм самостоятельно без помощи scikit.learn в педагогических целях.К сожалению, я не могу сохранить коэффициенты ПК в DataFrames coeff1roll, coeff2roll, coeff3roll, которые я ранее инициализировал.Все остальное работает нормально.
Пожалуйста, помогите мне и будьте свободны, чтобы я мог заметить любую другую ошибку в моей процедуре.
Вот мой код:
d = data
t = 20
scores1roll = np.zeros((n-t)) # scores
scores2roll = np.zeros((n-t))
scores3roll = np.zeros((n-t))
coeff1roll = pd.DataFrame(data = np.zeros((n-t, m))) # loadings
coeff2roll = pd.DataFrame(data = np.zeros((n-t, m)))
coeff3roll = pd.DataFrame(data = np.zeros((n-t, m)))
eigvalroll1 = np.zeros((n-t)) # eigenvalues
eigvalroll2 = np.zeros((n-t))
eigvalroll3 = np.zeros((n-t))
res_roll = pd.DataFrame(data = np.zeros((n-t, m))) # Residuals
# Loop with PCA step by step
for i in range(n-t):
droll = d.iloc[i:i+t-1,:] # window of data
r,c = droll.shape
meanroll = np.mean(droll, axis=0) # mean by column
stddevroll = np.sqrt(np.var(droll, axis=0)) # standard deviation by col
dstdrollss = (droll - meanroll)/stddevroll
# mean should be 0 and std dev 1
cor_mat = (dstdrollss.T.dot(dstdrollss))/(r - 1) # correlation matrix
eigvalues, eigvectors = np.linalg.eig(cor_mat)
eig_pairs = [(np.abs(eigval[i]), eigvec[:, i]) for i in
range(len(eigval))] # associating each eigvec to the correspondent eigval
eig_pairs.sort(reverse=True) # sorting according to abs val of eigenval
loadingsroll = np.hstack((eig_pairs[0][1].reshape(20, 1),
eig_pairs[1][1].reshape(20, 1),
eig_pairs[2][1].reshape(20, 1))) # selecting first 3
scoresroll = dstdrollss.dot(loadingsroll) # projections on new directions
coeff1roll.iloc[i, :] = loadingsroll[:, 0] # renamed coeff
coeff2roll.iloc[i, :] = loadingsroll[:, 1]
coeff3roll.iloc[i, :] = loadingsroll[:, 2]
scores1roll[i] = scoresroll.iloc[0,0]
scores2roll[i] = scoresroll.iloc[0,1]
scores3roll[i] = scoresroll.iloc[0,2]
eigvalroll1[i] = eigvalues[0]
eigvalroll2[i] = eigvalues[1]
eigvalroll3[i] = eigvalues[2]
d_hatroll = scoresroll.dot(loadingsroll.T) # back to raw normalized data
d_rawroll = d_hatroll * stddevroll.values + meanroll.values # raw data
c = dict(zip(d_rawroll.columns, droll.columns))
resrolling = droll.subtract(d_rawroll.rename(columns=c),
axis='column') # calculate residuals
res_roll.iloc[i, :] = resrolling.iloc[0, :].values
Я ожидал, что coeff1roll, coeff2roll, coeff3roll будут иметь разные значения для каждой точки данных, но вместо этого цикл возвращает столбцы с равными значениями, которые в точности равны значениюКоэффициенты самого последнего дня окна последних 20 дней:
coeff1roll.head()
0 1 2 ... 17 18 19
0 0.223961 0.223526 0.223531 ... 0.223876 0.223852 0.22368
1 0.223961 0.223526 0.223531 ... 0.223876 0.223852 0.22368
2 0.223961 0.223526 0.223531 ... 0.223876 0.223852 0.22368
3 0.223961 0.223526 0.223531 ... 0.223876 0.223852 0.22368
4 0.223961 0.223526 0.223531 ... 0.223876 0.223852 0.22368
[5 rows x 20 columns]