Exemple #1
0
    def test_smoke_test(self):
        np.random.seed(0)
        n = 2
        p = 1
        T = 1000
        lam = 1e-5

        A_true = np.array([
            [1., 1.],
            [0, 1.],
        ])
        C_true = np.array([[1., 1.]])
        W_true = .01 * np.eye(n)
        V_true = .1 * np.eye(p)

        # Get trajectory
        x = [npr.randn(n)]
        y = [
            C_true @ x[0] + np.random.multivariate_normal(np.zeros(p), V_true)
        ]
        for t in range(T - 1):
            xt = x[-1]
            x.append(A_true @ xt +
                     np.random.multivariate_normal(np.zeros(n), W_true))
            y.append(C_true @ xt +
                     np.random.multivariate_normal(np.zeros(p), V_true))
        x = np.array(x)
        y = np.array(y)

        K = np.ones((T, p), dtype=np.bool)

        W_neg_sqrt_true = sqrtm(np.linalg.inv(W_true))
        V_neg_sqrt_true = sqrtm(np.linalg.inv(V_true))

        def prox(params, t):
            return auto_ks.KalmanSmootherParameters(params.A,
                                                    params.W_neg_sqrt,
                                                    params.C,
                                                    params.V_neg_sqrt), 0.0

        params = auto_ks.KalmanSmootherParameters(
            A_true + 1e-2 * np.random.randn(n, n), W_neg_sqrt_true, C_true,
            V_neg_sqrt_true + .1 * np.eye(p))

        params, info = auto_ks.tune(params,
                                    prox,
                                    y,
                                    K,
                                    lam,
                                    verbose=True,
                                    niter=25,
                                    lr=1e-3)

        np.testing.assert_array_less(np.diff(info["losses"]), 0.0)
Exemple #2
0
def prox(params, t):
    r = 0.0
    W_neg_sqrt = params.W_neg_sqrt / (t * alpha + 1.0)
    idx = np.arange(W_neg_sqrt.shape[0])
    W_neg_sqrt[idx, idx] = 0.0
    r += alpha * np.sum(np.square(W_neg_sqrt))
    W_neg_sqrt[idx, idx] = np.diag(params.W_neg_sqrt)

    V_neg_sqrt = params.V_neg_sqrt / (t * alpha + 1.0)
    idx = np.arange(V_neg_sqrt.shape[0])
    V_neg_sqrt[idx, idx] = 0.0
    r += alpha * np.sum(np.square(V_neg_sqrt))
    V_neg_sqrt[idx, idx] = np.diag(params.V_neg_sqrt)

    return auto_ks.KalmanSmootherParameters(A, W_neg_sqrt, C, V_neg_sqrt), r
Exemple #3
0
    def test_kalman_filter_vs_cvxpy(self):
        np.random.seed(0)

        n = 3
        p = 6
        T = 10
        lam = 1e-10

        for _ in range(5):

            A = npr.randn(n, n)
            W_neg_sqrt = npr.randn(n, n)
            C = npr.randn(p, n)
            V_neg_sqrt = npr.randn(p, p)

            y = npr.randn(T, p)
            K = np.zeros(T * p, dtype=int)
            K[:int(.7 * T * p)] = 1
            np.random.shuffle(K)
            K = K.astype(bool).reshape((T, p))

            params = auto_ks.KalmanSmootherParameters(A, W_neg_sqrt, C,
                                                      V_neg_sqrt)
            xhat, yhat, DT = auto_ks.kalman_smoother(params, y, K, lam)

            xs = cp.Variable((T, n))
            ys = cp.Variable((T, p))
            objective = 0.0
            for t in range(T):
                objective += cp.sum_squares(V_neg_sqrt @ (ys[t] - C @ xs[t]))
                if t < T - 1:
                    objective += cp.sum_squares(
                        W_neg_sqrt @ (xs[t + 1] - A @ xs[t]))
            objective += cp.sum_squares(lam * xs) + cp.sum_squares(lam * ys)
            constraints = []
            rows, cols = K.nonzero()
            for t, i in zip(rows, cols):
                constraints += [ys[t, i] == y[t, i]]
            prob = cp.Problem(cp.Minimize(objective), constraints)
            prob.solve(solver='OSQP')
            np.testing.assert_allclose(xhat, xs.value)
            np.testing.assert_allclose(yhat, ys.value)
Exemple #4
0
    def test_kalman_filter_derivative(self):
        np.random.seed(0)

        n = 5
        p = 10
        T = 100
        lam = 1e-10

        for _ in range(10):
            A = npr.randn(n, n)
            W_neg_sqrt = np.eye(n)
            C = npr.randn(p, n)
            V_neg_sqrt = npr.randn(p, p)

            y = npr.randn(T, p)
            K = np.zeros(T * p, dtype=int)
            K[:int(.7 * T * p)] = 1
            np.random.shuffle(K)
            K = K.astype(bool).reshape((T, p))

            params = auto_ks.KalmanSmootherParameters(A, W_neg_sqrt, C,
                                                      V_neg_sqrt)
            xhat, yhat, DT = auto_ks.kalman_smoother(params, y, K, lam)
            f = np.sum(xhat) + np.sum(yhat)

            dxhat = np.ones(xhat.shape)
            dyhat = np.ones(yhat.shape)

            derivatives = DT(dxhat, dyhat)
            eps = 1e-6
            xhat_p, yhat_p, _ = auto_ks.kalman_smoother(
                params + eps * derivatives, y, K, lam)
            fp = np.sum(xhat_p) + np.sum(yhat_p)
            increase = fp - f
            dA = derivatives.DA
            dW_neg_sqrt = derivatives.DW_neg_sqrt
            dC = derivatives.DC
            dV_neg_sqrt = derivatives.DV_neg_sqrt
            predicted_increase = eps * (
                np.sum(dA * dA) + np.sum(dW_neg_sqrt * dW_neg_sqrt) +
                np.sum(dC * dC) + np.sum(dV_neg_sqrt * dV_neg_sqrt))
            np.testing.assert_allclose(predicted_increase, increase, atol=1e-5)
Exemple #5
0
def prox(params, t):
    return auto_ks.KalmanSmootherParameters(
        np.maximum(params.A, 0), W_neg_sqrt, C,
        np.diag(np.maximum(np.diag(params.V_neg_sqrt), 0))), 0.0
Exemple #6
0
df = pd.read_csv("data/state_pop_Annual.txt",
                 delimiter="\t",
                 parse_dates=["DATE"])
df.drop(["AKPOP", "HIPOP"], axis=1, inplace=True)
columns = df.columns[1:]
y = np.array(df.drop(["DATE"], axis=1)) / 1000.0

# construct initial parameters
T, n = y.shape
m = n
lam = 1e-10
A = np.eye(n)
W_neg_sqrt = np.sqrt(1. / .001) * np.diag(np.random.uniform(0.8, 1.2, size=n))
C = np.eye(m)
V_neg_sqrt = np.sqrt(1. / .001) * np.diag(np.random.uniform(0.8, 1.2, size=n))
params = auto_ks.KalmanSmootherParameters(A, W_neg_sqrt, C, V_neg_sqrt)

K = np.zeros(y.shape, dtype=bool)
M = np.zeros(y.shape, dtype=bool)
M_test = np.zeros(y.shape, dtype=bool)
for t in range(T):
    idx = np.arange(n)
    np.random.shuffle(idx)
    indices = idx[:30]
    K[t, indices] = True
    np.random.shuffle(indices)
    M[t, indices[:12]] = True
    M_test[t, indices[12:12 + 5]] = True


def prox(params, t):
Exemple #7
0
    y = np.random.multivariate_normal(C @ x, V)
    ys.append(y)

ys = np.array(ys)

x = np.zeros(n)
ys_test = []
for _ in range(T):
    x = np.random.multivariate_normal(A @ x, W)
    y = np.random.multivariate_normal(C @ x, V)
    ys_test.append(y)

ys_test = np.array(ys_test)

parameters = auto_ks.KalmanSmootherParameters(np.random.randn(n, n),
                                              np.eye(n) * .5,
                                              np.random.randn(m, n),
                                              np.eye(m) * .5)


def prox(params, t):
    return params, 0.


def callback(k, yhat, parameters, prediction_loss_forecast):
    print("TEST", prediction_loss_forecast(parameters, ys_test))


parameters, info, prediction_loss_forecast = auto_ks.tune_forecast(
    parameters,
    prox,
    ys,
Exemple #8
0
 def prox(params, t):
     return auto_ks.KalmanSmootherParameters(params.A,
                                             params.W_neg_sqrt,
                                             params.C,
                                             params.V_neg_sqrt), 0.0
Exemple #9
0
eye = np.eye(3)
zeros = np.zeros((3, 3))
h = 1. / 100.0
lam = 1e-10
alpha = 1e-4
n = 9
m = 8
A = np.bmat([[eye, h * eye, zeros], [zeros, eye, h * eye], [zeros, zeros,
                                                            eye]])
C = np.bmat([[eye, zeros, zeros], [zeros, zeros, eye],
             [np.zeros((2, 3)), np.eye(2),
              np.zeros((2, 4))]])
W_neg_sqrt = np.eye(n)
V_neg_sqrt = .01 * np.eye(m)
params_initial = auto_ks.KalmanSmootherParameters(np.array(A),
                                                  np.array(W_neg_sqrt),
                                                  np.array(C),
                                                  np.array(V_neg_sqrt))


# proximal operator for r
def prox(params, t):
    r = 0.0
    W_neg_sqrt = params.W_neg_sqrt / (t * alpha + 1.0)
    idx = np.arange(W_neg_sqrt.shape[0])
    W_neg_sqrt[idx, idx] = 0.0
    r += alpha * np.sum(np.square(W_neg_sqrt))
    W_neg_sqrt[idx, idx] = np.diag(params.W_neg_sqrt)

    V_neg_sqrt = params.V_neg_sqrt / (t * alpha + 1.0)
    idx = np.arange(V_neg_sqrt.shape[0])
    V_neg_sqrt[idx, idx] = 0.0