Как перевернуть явно заданную ковариационную матрицу? - PullRequest
0 голосов
/ 02 марта 2019

Я определил взвешенную матрицу COVAR.Сейчас я пытаюсь свернуть это со временем.То есть я хочу получить взвешенную матрицу COVAR с скользящим окном 60. В качестве примера я возьму матрицу ковариации населения:

def cm(data):
    data = data.values
    row_data = data.shape[0]
    col_data = data.shape[1]

    cov_mat = np.zeros([col_data, col_data])

    for i in range(0, col_data):
        for j in range(0, col_data):
            mean_1 = np.mean(data[:,i])
            mean_2 = np.mean(data[:,j])
            total = 0

            for k in range(0, row_data):
               total = total + (data[k][i]-mean_1)*(data[k][j]-mean_2)

            cov_mat[i][j] = total * (1/row_data)

    return cov_mat

Для этого конкретного сценария, как я могу эффективно пролонгироватьматрица?

ОБНОВЛЕНИЕ:

После некоторых проб и ошибок мне удалось решить часть моей проблемы, включив цикл for, который повторяется в течение скользящих периодов.:

In:

rolling_window = 60

def cm(data):
     data = data.values    
     row_data = data.shape[0]
     col_data = data.shape[1]

     # Define the number of rolls that have to be made: 
     rolls = row_data - rolling_window

     # Define an empty list which will be filled with COV/VAR matrices:
     cov_mat_main = []

     for t in range(rolls):
         cov_mat = np.zeros([col_data, col_data])

         for i in range(0, col_data):
             for j in range(0, col_data):
                 mean_1 = np.mean(data[t:rolling_window+t,i])
                 mean_2 = np.mean(data[t:rolling_window+t:,j])

                 total = 0
                 for k in range(t, rolling_window+t):
                     total = total + (data[k][i]-mean_1)*(data[k][j]-mean_2)

                 cov_mat[i][j] = total * (1/row_data)

         cov_mat_main.append(cov_mat)

     cov_mat_main = np.array(cov_mat_main)

cm(df)

Out:

[[ 5.81310317e-07 -1.37889464e-06 -3.57360335e-07]
  [-1.37889464e-06  8.73264313e-06  6.19930936e-06]
  [-3.57360335e-07  6.19930936e-06  9.02566589e-06]]

 [[ 4.03349133e-07 -1.31881055e-06 -6.03769261e-07]
  [-1.31881055e-06  8.76683970e-06  6.26991034e-06]
  [-6.03769261e-07  6.26991034e-06  8.68739335e-06]]]

Однако, похоже, что результат этогофункция не соответствует выходу встроенной функции.

In:

cm = df.rolling(rolling_window).cov()

Out:

     [[ 4.50638342e-06 -1.47342972e-05 -6.74556002e-06]
  [-1.47342972e-05  9.79467608e-05  7.00500328e-05]
  [-6.74556002e-06  7.00500328e-05  9.70591532e-05]]

 [[ 3.41189600e-06 -9.47500359e-06 -4.76181287e-06]
  [-9.47500359e-06  7.50918104e-05  5.93125976e-05]
  [-4.76181287e-06  5.93125976e-05  9.40643303e-05]]]

В кадре данных отсутствуют пропущенные значения, которые могли бы объяснить потенциальное смещение в определенных матрицах по сравнению с матрицами .cov().

Надеемся, что кто-то может обнаружить ошибку.

Есть предложения?

1 Ответ

0 голосов
/ 03 марта 2019

После некоторых проб и ошибок мне удалось решить собственную проблему.

Для всех, кто интересуется решением:

rolling_window = 30

def cm(data):
    data = data.values
    row_data = data.shape[0]
    col_data = data.shape[1]

    # Specifying the amount of rolls that have to be taken / the amount of VAR/COV matrices that have to be calculated
    rolls = row_data - rolling_window

    # Creating an empty list which will be appened a VAR/COV matrices for every roll. 
    cov_mat_main = []

    for t in range(rolls):
       cov_mat = np.zeros([col_data, col_data])
       begin_est = t+1
       end_est = rolling_window+t+1

           for i in range(0, col_data):
               for j in range(0, col_data):
                   mean_1 = np.mean(data[begin_est:end_est,i])
                   mean_2 = np.mean(data[begin_est:end_est,j])
                   total = 0

                   for k in range(begin_est, end_est):
                       total = total + (data[k][i]-mean_1)*(data[k][j]-mean_2)
                   cov_mat[i][j] = total * (1/(rolling_window-1))

          cov_mat_main.append(cov_mat)

     cov_mat_main = np.array(cov_mat_main)

     return cov_mat_main

print(cm(df))

Казалось, что я должен был принять во внимание:

  • Степени свободы
  • Деление «итога» на скользящее окно вместо row_data
  • Добавление 1 единицы времени в начало и конец окна оценки

, чтобы выровнять его с .cov()function.

Эта определенная матрица приводит к, out:

 [[ 4.50638342e-06 -1.47342972e-05 -6.74556002e-06]
  [-1.47342972e-05  9.79467608e-05  7.00500328e-05]
  [-6.74556002e-06  7.00500328e-05  9.70591532e-05]]

 [[ 3.41189600e-06 -9.47500359e-06 -4.76181287e-06]
  [-9.47500359e-06  7.50918104e-05  5.93125976e-05]
  [-4.76181287e-06  5.93125976e-05  9.40643303e-05]]]

, который выравнивается с df.rolling(rolling_window).cov():

 [[ 4.50638342e-06 -1.47342972e-05 -6.74556002e-06]
  [-1.47342972e-05  9.79467608e-05  7.00500328e-05]
  [-6.74556002e-06  7.00500328e-05  9.70591532e-05]]

 [[ 3.41189600e-06 -9.47500359e-06 -4.76181287e-06]
  [-9.47500359e-06  7.50918104e-05  5.93125976e-05]
  [-4.76181287e-06  5.93125976e-05  9.40643303e-05]]]
...