def harmonic_fit_mcmc_arn(time, X, frq, arn=1, mask=None, axis=0, basetime=None,  **kwargs):
    """
    Harmonic fitting using Bayesian inference
    
    Model the errors using an auto-regressive model
    """
    tday = 86400.
    # Convert the time to days
    dtime = SecondsSince(time, basetime=basetime )
    nt = dtime.shape[0]
    dtime /= tday
    
    # Convert the frequencies to radians / day
    omega = [ff*tday for ff in frq]
    #omega = frq
    
    # Number of parameters
    n_params = 2*len(omega) + 1
    
    print('Number of Parametrs: %d\n'%n_params, omega)

    with pm.Model() as my_model:
        ###
        # Create priors for each of our variables
        BoundNormal = pm.Bound(pm.Normal, lower=0.0)

        # Mean
        beta_mean = pm.Normal('beta_mean', mu=0, sd=1)
        beta_s=[beta_mean]

        # Harmonics
        for n in range(0,2*len(omega),2):
            beta_s.append(pm.Normal('beta_%d_re'%(n//2), mu=1., sd = 5.))
            beta_s.append(pm.Normal('beta_%d_im'%(n//2), mu=1., sd = 5.))

        ###
        # Generate the likelihood function using the deterministic variable as the mean
        mu_x = sine_model_notrend(beta_s, omega, dtime)

        
        # Use an autoregressive model for the error term
        beta = pm.Normal('beta', mu=0, sigma=1., shape=arn)
        #sigma = pm.InverseGamma('sigma',1,1)
        sigma = pm.HalfNormal('sigma',1)

        X_obs = pm.AR('X_obs', beta, sigma=sigma, observed=X - mu_x)
        

        
        # Inference step...
        step = None
        start = None
        trace = pm.sample(500, tune=1000, start = start, step=step, cores=2,
                         return_inferencedata=False)#nuts_kwargs=dict(target_accept=0.95, max_treedepth=16, k=0.5))

    # Return the trace and the parameter stats
    return trace,  my_model, omega, dtime
Exemplo n.º 2
0
def ar_model_pred_advi_dynamic(X, ar_order):
    # prepare training dataset
    train_size = int(X.shape[0] * 0.66)
    train, test = X.iloc[0:train_size], X.iloc[train_size:]
    history = [x for x in train]
    # make predictions
    predictions = list()
    for t in range(test.shape[0]):
        tau = 0.001

        model = pm.Model()
        with model:

            beta = pm.Uniform('beta', lower=-1, upper=1, shape=ar_order)
            y_obs = pm.AR('y_obs', rho=beta, tau=tau, observed=history)
            #trace = pm.sample(2000, tune=1000)
            step = step = pm.ADVI()

            n_draws, n_chains = 3000, 3
            n_sim = n_draws * n_chains

            advi_fit = pm.fit(method=pm.ADVI(), n=30000)

            # Consider 3000 draws and 2 chains.
            advi_trace = advi_fit.sample(10000)

        values = history[len(history) - ar_order:]
        values = values[::-1]
        yhat = np.dot(get_coef_from_trace(advi_trace), values)
        predictions.append(yhat)
        history.append(test[t])
        history = history[1:]
    # calculate out of sample error
    #error = mean_squared_error(test, predictions)
    predictions = pd.DataFrame(predictions)
    predictions.set_index(X[train_size:X.shape[0]].index,
                          inplace=True,
                          drop=True)
    return predictions[0]
Exemplo n.º 3
0
jpfont = FontProperties(fname=FontPath)
#%% ノイズを含むAR(1)過程からデータを生成
n = 500
np.random.seed(99)
x = np.empty(n)
x[0] = st.norm.rvs() # 定常分布の分散 = 0.19/(1 - 0.9**2) = 1.0
for t in range(1, n):
    x[t] = 0.9 * x[t-1] + st.norm.rvs(scale=np.sqrt(0.19))
y = x + st.norm.rvs(scale=0.5, size=n)
#%% 事後分布の設定
ar1_model = pm.Model()
with ar1_model:
    sigma = pm.HalfCauchy('sigma', beta=1.0)
    rho = pm.Uniform('rho', lower=-1.0, upper=1.0)
    omega = pm.HalfCauchy('omega', beta=1.0)
    ar1 = pm.AR('ar1', rho, sigma=omega, shape=n,
                init=pm.Normal.dist(sigma=omega/pm.math.sqrt(1 - rho**2)))
    observation = pm.Normal('y', mu=ar1, sigma=sigma, observed=y)
#%% 事後分布からのサンプリング
n_draws = 5000
n_chains = 4
n_tune = 1000
with ar1_model:
    trace = pm.sample(draws=n_draws, chains=n_chains, tune=n_tune,
                      random_seed=123)
    param_names = ['sigma', 'rho', 'omega']
    print(pm.summary(trace, var_names=param_names))
#%% 事後分布のグラフの作成
labels = ['$\\sigma$', '$\\rho$', '$\\omega$']
k = len(labels)
fig, ax = plt.subplots(k, 2, num=1, figsize=(8, 1.5*k), facecolor='w')
for index in range(k):
Exemplo n.º 4
0
    http://fx.sauder.ubc.ca/data.html
"""
data = pd.read_csv('dollaryen.csv', index_col=0)
y = 100 * np.diff(np.log(data.values.ravel()))
n = y.size
series_date = pd.to_datetime(data.index[1:])
#%% SVモデルの設定
sv_model = pm.Model()
with sv_model:
    nu = pm.Exponential('nu', 0.2)
    sigma = pm.HalfCauchy('sigma', beta=1.0)
    rho = pm.Uniform('rho', lower=-1.0, upper=1.0)
    omega = pm.HalfCauchy('omega', beta=1.0)
    log_vol = pm.AR('log_vol',
                    rho,
                    sd=omega,
                    shape=n,
                    init=pm.Normal.dist(sd=omega / pm.math.sqrt(1 - rho**2)))
    observation = pm.StudentT('y',
                              nu,
                              sd=sigma * pm.math.exp(log_vol),
                              observed=y)
#%% 事後分布からのサンプリング
n_draws = 5000
n_chains = 4
n_tune = 2000
with sv_model:
    trace = pm.sample(draws=n_draws,
                      chains=n_chains,
                      tune=n_tune,
                      random_seed=123,
    http://www.fepc.or.jp/library/data/tokei/index.html
"""
data = pd.read_csv('electricity.csv', index_col=0)
y0 = np.log(data.values.reshape((data.shape[0]//3, 3)).sum(axis=1))
y = 100 * (y0 - y0[0])
n = y.size
series_date = pd.date_range(start='1/1/1989', periods=n, freq='Q')
#%% 確率的トレンド+季節変動
trend_coef = np.array([2.0, -1.0])
seasonal_coef = np.array([-1.0, -1.0, -1.0])
timeseries_decomp = pm.Model()
with timeseries_decomp:
    sigma = pm.HalfCauchy('sigma', beta=1.0)
    tau = pm.HalfCauchy('tau', beta=1.0)
    omega = pm.HalfCauchy('omega', beta=1.0)
    trend = pm.AR('trend', trend_coef, sigma=tau, shape=n)
    seasonal = pm.AR('seasonal', seasonal_coef, sigma=omega, shape=n)
    observation = pm.Normal('y', mu=trend+seasonal, sigma=sigma, observed=y)
#%% 事後分布からのサンプリング
n_draws = 5000
n_chains = 4
n_tune = 2000
with timeseries_decomp:
    trace = pm.sample(draws=n_draws, chains=n_chains, tune=n_tune,
                      target_accept=0.95, random_seed=123)
    param_names = ['sigma', 'tau', 'omega']
    print(pm.summary(trace, var_names=param_names))
#%% 事後分布のグラフの作成
series_name = ['原系列', '平滑値', 'トレンド', '季節変動', 'ノイズ']
labels = ['$\\sigma$', '$\\tau$', '$\\omega$']
k = len(labels)
Exemplo n.º 6
0
#
# clark_sigmaT = np.mean(trace['sigmaT'])
# clark_mu = np.mean(trace['mu'])
#
# print "Clark (1973) model parameters:"
# print "SigmaT = ", clark_sigmaT
# print "Mu = ", clark_mu
clark_sigmaT = 0.57
clark_mu = -4.91

with pm.Model() as taylor_model:
    sigmaT = pm.Uniform('sigmaT', lower=0.001, upper=.2, testval=0.05)
    rhos = pm.Uniform('rhos', lower=-1., upper=1., shape=5)
    mu = pm.Uniform('mu', lower=-7., upper=-3., testval=-5.)

    time_process = pm.AR('time_process', rho=rhos, sd=sigmaT, shape=N)

    pm.Normal('obs',
              mu=0.,
              sd=pm.math.exp(mu + time_process),
              observed=returns)

    mean_field = pm.fit(30000,
                        method='advi',
                        obj_optimizer=pm.adam(learning_rate=0.01))
    trace = mean_field.sample(1000)

taylor_sigmaT = np.mean(trace['sigmaT'])
taylor_mu = np.mean(trace['mu'])
taylor_rhos = np.mean(trace['rhos'], axis=0)