Я пытаюсь реализовать emcee
выборку MCMC в Python с помощью предопределенной функции правдоподобия, чтобы найти наилучшую границу между двумя группами данных.
Для emcee
см .: http://dfm.io/emcee/current/user/line/
Функция правдоподобия вычисляет истинные положительные и истинно отрицательные классификации, учитывая некоторую линейную граничную линию, и используется для минимизации разницы между двумя значениямив то время как максимизировать их сумму.
Таким образом, вы можете представить себе, что значения TP и TN, равные 1, соответственно, дадут значение вероятности 1, в то время как значения TP и TN, равные 0, вернут значение вероятности, равное 0.
Но когда яПопытка выбрать пространство параметров для m
и b
, градиента и смещения (или смещения) для линии границы, я получаю некоторые дико большие и / или маленькие значения для прогулок.
Iниже приведен пример кода, который генерирует несколько хорошо разделенных групп населения, а затем MCMC вокруг начальных предположений значений параметров.Я не уверен, почему цепочки MCMC не сходятся здесь к подходящему значению, поэтому любая помощь будет принята с благодарностью.
Следующий код должен запускаться «из коробки».
import emcee
import numpy as np
from sklearn.metrics import confusion_matrix
import matplotlib.pyplot as plt
#generate some test x and y data
folded_xy_train = np.random.uniform(0,1,10000) #test x data
folded_z_train = np.random.uniform(0,1,10000) #test y data
#define the true gradient and offset for the boundary line
m_true, b_true = 5,-2.5
#generate labels for the test data
rounded_labels_train = np.ones(len(folded_z_train))
model = (m_true*folded_xy_train) + b_true
difference = model - folded_z_train
rounded_labels_train[difference<0] = 0
#show the test data
plt.figure()
plt.scatter(folded_xy_train,folded_z_train,c=rounded_labels_train,s=1.0)
#define a likelihood function for the boundary line
def lnlike(theta, x, y, labels):
m, b = theta
model = (m*x) + b
difference = model - y
classifications = np.ones(len(y))
classifications[difference<0]=0
cfm = confusion_matrix(labels,classifications)
cm = cfm.astype('float') / cfm.sum(axis=1)[:, np.newaxis]
tn, fp, fn, tp = cm.ravel()
likelihood_val = (0.5*(tp+tn))/(1+np.abs(tp-tn))
ln_like = -np.log(likelihood_val)
return ln_like
#define a wide flat prior
def lnprior(theta):
m, b, = theta
if 0 < m < 10 and -20 < b < 5:
return 0.0
return -np.inf
#define the posterior
def lnprob(p, x, y, labels):
lp = lnprior(p)
if not np.isfinite(lp):
return 0
return lp + lnlike(p, x, y, labels)
#setup the MCMC sampling
nwalkers = 4
ndim = 2
p0 = np.array([4.2,-2]) + [np.random.rand(ndim) for i in range(nwalkers)]
sampler = emcee.EnsembleSampler(nwalkers, ndim, lnprob, args=(folded_xy_train, folded_z_train, rounded_labels_train))
sampler.run_mcmc(p0, 500)
#extract the MCMC paramater value chains
samples = sampler.chain[:, 50:, :].reshape((-1, ndim))
#view the parameter chains
plt.figure()
plt.subplot(211)
plt.plot(samples[:,0])
plt.subplot(212)
plt.plot(samples[:,1])
Исходные тестовые данные, показывающие очевидную граничную линию для данных xy (закрашены меткой двоичного класса):
Образец идет, показывая странную выборку для параметра градиента (вверху) и параметра смещения (внизу).Ось x обозначает номер шага обхода MCMC, а ось y обозначает значения параметров MCMC на данном шаге: