Próbuję zaimplementować Bayesa regresji liniowej modele używając PyMC3
z rzeczywistych danych (to znaczy nie od funkcji liniowej + szum Gaussa) z zestawów danych w sklearn.datasets
. Wybrałem zbiór danych regresji o najmniejszej liczbie atrybutów (tj. load_diabetes()
), którego kształt to (442, 10)
; to jest 442 samples
i .przewidywania PyMC3 Bayesa regresji liniowej z sklearn.datasets
Wierzę, że mam działający model, a posteriors wyglądają na dość przyzwoicie, aby spróbować przewidzieć, jak to działa, ale ... Zdałem sobie sprawę, że nie mam pojęcia, jak przewidzieć z tymi modelami Bayesian! Staram się unikać notacji glm
i patsy
, ponieważ trudno mi zrozumieć, co faktycznie dzieje się podczas korzystania z tego.
Próbowałem następujące: Generating predictions from inferred parameters in pymc3 a także http://pymc-devs.github.io/pymc3/posterior_predictive/ ale mój model jest albo bardzo straszny w przewidywaniu czy robię to źle.
Jeśli właściwie wykonuję przewidywanie (co prawdopodobnie nie jest), to każdy może mi pomóc zoptymalizować mój model. Nie wiem, czy najmniej mean squared error
, absolute error
, lub coś podobnego działa w frameworkach Bayesian. Idealnie chciałbym uzyskać tablicę number_of_rows = ilość wierszy w moim zestawie testów atrybutów/danych X_te
oraz liczbę kolumn, które mają być próbkami z rozkładu wstecznego.
import pymc3 as pm
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns; sns.set()
from scipy import stats, optimize
from sklearn.datasets import load_diabetes
from sklearn.cross_validation import train_test_split
from theano import shared
np.random.seed(9)
%matplotlib inline
#Load the Data
diabetes_data = load_diabetes()
X, y_ = diabetes_data.data, diabetes_data.target
#Split Data
X_tr, X_te, y_tr, y_te = train_test_split(X,y_,test_size=0.25, random_state=0)
#Shapes
X.shape, y_.shape, X_tr.shape, X_te.shape
#((442, 10), (442,), (331, 10), (111, 10))
#Preprocess data for Modeling
shA_X = shared(X_tr)
#Generate Model
linear_model = pm.Model()
with linear_model:
# Priors for unknown model parameters
alpha = pm.Normal("alpha", mu=0,sd=10)
betas = pm.Normal("betas", mu=0,#X_tr.mean(),
sd=10,
shape=X.shape[1])
sigma = pm.HalfNormal("sigma", sd=1)
# Expected value of outcome
mu = alpha + np.array([betas[j]*shA_X[:,j] for j in range(X.shape[1])]).sum()
# Likelihood (sampling distribution of observations)
likelihood = pm.Normal("likelihood", mu=mu, sd=sigma, observed=y_tr)
# Obtain starting values via Maximum A Posteriori Estimate
map_estimate = pm.find_MAP(model=linear_model, fmin=optimize.fmin_powell)
# Instantiate Sampler
step = pm.NUTS(scaling=map_estimate)
# MCMC
trace = pm.sample(1000, step, start=map_estimate, progressbar=True, njobs=1)
#Traceplot
pm.traceplot(trace)
# Prediction
shA_X.set_value(X_te)
ppc = pm.sample_ppc(trace, model=linear_model, samples=1000)
#What's the shape of this?
list(ppc.items())[0][1].shape #(1000, 111) it looks like 1000 posterior samples for the 111 test samples (X_te) I gave it
#Looks like I need to transpose it to get `X_te` samples on rows and posterior distribution samples on cols
for idx in [0,1,2,3,4,5]:
predicted_yi = list(ppc.items())[0][1].T[idx].mean()
actual_yi = y_te[idx]
print(predicted_yi, actual_yi)
# 158.646772735 321.0
# 160.054730647 215.0
# 149.457889418 127.0
# 139.875149489 64.0
# 146.75090354 175.0
# 156.124314452 275.0
brzmi dobrze, na pewno zrozumie. Teraz to zrobię –
Zrobione już, i dzięki! – halfer