1

emcee2 つのデータ母集団間の最適な境界を見つけるために、定義済みの尤度関数を使用して Python で MCMC サンプリングを実装しようとしています。

参照emcee: http://dfm.io/emcee/current/user/line/

尤度関数は、線形境界線が与えられた場合に真陽性と真陰性の分類を計算し、2 つの値の差を最小化しながら合計を最大化するために使用されます。

このようにして、それぞれ 1 の TP および TN レートは 1 の尤度値を与え、0 の TP および TN レートは 0 の尤度値を返すと想像できます。

しかし、 と のパラメーター空間、勾配とオフセット (またはバイアス) を境界線でサンプリングしようとするmb、ウォークに対して非常に大きな値や小さな値が得られます。

以下にサンプル コードを示します。これは、適切に分割された母集団を生成し、次にパラメータ値の初期推定値の周りに 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 パラメータ値を表します。

ここに画像の説明を入力

4

0 に答える 0