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
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]
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):
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)
# # 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)