Множественная регрессия с помощью Пикальмана? - PullRequest
0 голосов
/ 18 марта 2019

Я ищу способ обобщить регрессию, используя pykalman от 1 до N регрессоров.Сначала мы не будем беспокоиться об онлайн-регрессии - я просто хочу на игрушечном примере настроить фильтр Калмана для 2-х регрессоров вместо 1, то есть Y = c1 * x1 + c2 * x2 + const.

Для одногов случае регрессора работает следующий код.Мой вопрос заключается в том, как изменить настройку фильтра, чтобы он работал для двух регрессоров:

    import matplotlib.pyplot as plt
    import numpy as np
    import pandas as pd
    from pykalman import KalmanFilter

    if __name__ == "__main__":
        file_name = '<path>\KalmanExample.txt'
        df = pd.read_csv(file_name, index_col = 0)
        prices = df[['ETF', 'ASSET_1']] #, 'ASSET_2']]

        delta = 1e-5
        trans_cov = delta / (1 - delta) * np.eye(2)
        obs_mat = np.vstack( [prices['ETF'], 
                            np.ones(prices['ETF'].shape)]).T[:, np.newaxis]

        kf = KalmanFilter(
            n_dim_obs=1,
            n_dim_state=2,
            initial_state_mean=np.zeros(2),
            initial_state_covariance=np.ones((2, 2)),
            transition_matrices=np.eye(2),
            observation_matrices=obs_mat,
            observation_covariance=1.0,
            transition_covariance=trans_cov
        )

        state_means, state_covs = kf.filter(prices['ASSET_1'].values)

        # Draw slope and intercept...
        pd.DataFrame(
            dict(
                slope=state_means[:, 0],
                intercept=state_means[:, 1]
            ), index=prices.index
        ).plot(subplots=True)
        plt.show()

Файл примера KalmanExample.txt содержит следующие данные:

Date,ETF,ASSET_1,ASSET_2
2007-01-02,176.5,136.5,141.0
2007-01-03,169.5,115.5,143.25
2007-01-04,160.5,111.75,143.5
2007-01-05,160.5,112.25,143.25
2007-01-08,161.0,112.0,142.5
2007-01-09,155.5,110.5,141.25
2007-01-10,156.5,112.75,141.25
2007-01-11,162.0,118.5,142.75
2007-01-12,161.5,117.0,142.5
2007-01-15,160.0,118.75,146.75
2007-01-16,156.5,119.5,146.75
2007-01-17,155.0,120.5,145.75
2007-01-18,154.5,124.5,144.0
2007-01-19,155.5,126.0,142.75
2007-01-22,157.5,124.5,142.5
2007-01-23,161.5,124.25,141.75
2007-01-24,164.5,125.25,142.75
2007-01-25,164.0,126.5,143.0
2007-01-26,161.5,128.5,143.0
2007-01-29,161.5,128.5,140.0
2007-01-30,161.5,129.75,139.25
2007-01-31,161.5,131.5,137.5
2007-02-01,164.0,130.0,137.0
2007-02-02,156.5,132.0,128.75
2007-02-05,156.0,131.5,132.0
2007-02-06,159.0,131.25,130.25
2007-02-07,159.5,136.25,131.5
2007-02-08,153.5,136.0,129.5
2007-02-09,154.5,138.75,128.5
2007-02-12,151.0,136.75,126.0
2007-02-13,151.5,139.5,126.75
2007-02-14,155.0,169.0,129.75
2007-02-15,153.0,169.5,129.75
2007-02-16,149.75,166.5,128.0
2007-02-19,150.0,168.5,130.0

В одном случае регрессораследующий вывод и для случая с двумя регрессорами я хочу второй "наклонный" график, представляющий C2.

enter image description here

1 Ответ

1 голос
/ 25 марта 2019

Ответ отредактирован, чтобы отразить мое пересмотренное понимание вопроса.

Если я правильно понимаю, вы хотите смоделировать наблюдаемую выходную переменную Y = ETF как линейную комбинацию двух наблюдаемых значений; ASSET_1, ASSET_2.

Коэффициенты этой регрессии должны рассматриваться как системные состояния, то есть ETF = x1*ASSET_1 + x2*ASSET_2 + x3, где x1 и x2 - коэффициенты 1 и 2 соответственно, а x3 - перехват. Предполагается, что эти коэффициенты эволюционируют медленно .

Код, реализующий это, приведен ниже, обратите внимание, что это просто расширяет существующий пример, чтобы иметь еще один регрессор.

Обратите внимание, что вы можете получить совершенно разные результаты, играя с параметром delta. Если оно установлено большим (далеко от нуля), то коэффициенты будут меняться быстрее, и восстановление регрессии будет почти идеальным. Если оно установлено маленьким (очень близко к нулю), то коэффициенты будут развиваться медленнее, а восстановление регрессии будет менее совершенным. Возможно, вы захотите взглянуть на алгоритм Максимизация ожидания - , поддерживаемый pykalman .

КОД:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from pykalman import KalmanFilter

if __name__ == "__main__":
    file_name = 'KalmanExample.txt'
    df = pd.read_csv(file_name, index_col = 0)
    prices = df[['ETF', 'ASSET_1', 'ASSET_2']]
    delta = 1e-3
    trans_cov = delta / (1 - delta) * np.eye(3)
    obs_mat = np.vstack( [prices['ASSET_1'], prices['ASSET_2'],  
                          np.ones(prices['ASSET_1'].shape)]).T[:, np.newaxis]
    kf = KalmanFilter(
        n_dim_obs=1,
        n_dim_state=3,
        initial_state_mean=np.zeros(3),
        initial_state_covariance=np.ones((3, 3)),
        transition_matrices=np.eye(3),
        observation_matrices=obs_mat,
        observation_covariance=1.0,
        transition_covariance=trans_cov        
    )

    # state_means, state_covs = kf.em(prices['ETF'].values).smooth(prices['ETF'].values)
    state_means, state_covs = kf.filter(prices['ETF'].values)


    # Re-construct ETF from coefficients and 'ASSET_1' and ASSET_2 values:
    ETF_est = np.array([a.dot(b) for a, b in zip(np.squeeze(obs_mat), state_means)])

    # Draw slope and intercept...
    pd.DataFrame(
        dict(
            slope1=state_means[:, 0],
            slope2=state_means[:, 1],
            intercept=state_means[:, 2],
        ), index=prices.index
    ).plot(subplots=True)
    plt.show()

    # Draw actual y, and estimated y:
    pd.DataFrame(
        dict(
            ETF_est=ETF_est,
            ETF_act=prices['ETF'].values
        ), index=prices.index
    ).plot()
    plt.show()

УЧАСТКИ:

States evolving

Reconstruction of regressand

...