Я пытаюсь реализовать алгоритм, взятый у Альберта и Чиба, для выборки со скрытым полиномиальным распределением.Кажется, код работает до тех пор, пока я не попытаюсь обновить ковариационную матрицу: тогда я не могу сгенерировать нормальное случайное число.
def gibbs_u(x,y,sim):
x = x.values #need transform as it is a dataframe
y = y.values #same
n,k = x.shape
#Get true number of categories:
J = np.max(y)+1
#initialize beta to MLE values and rho to 0:
rho = 0.01
beta = 0.238
#initialize Z to empty array
Z = np.empty((n,J))
#conditional distribution of Z:
cov_mat = np.identity(J)
cov_mat[0,1] = rho
cov_mat[1,0] = rho
betaSim = np.empty((sim+1, 1)) #Matrice de retour avec tous les beta simulés
betaSim[0,] = beta
rhoSim = np.empty((sim+1, 1)) #Matrice de retour avec tous les rho simulés
rhoSim[0,] = rho
for i in range(sim):
#Update Z
for j in range(n):
x = np.reshape(x, (n,J), order='C')
Z = np.reshape(Z, (n,J), order='C')
meanZ = x[j,:]*beta
while True:
Z[j,:] = np.random.multivariate_normal(meanZ.T, cov_mat)
if np.argmax(Z[j,:]) == y[j]:
break
# Update beta:
x = np.reshape(x, (n*J, 1), order='C')
Z = np.reshape(Z, (n*J, 1), order='C')
Omega = np.kron(np.identity(n), cov_mat)
xTOx = np.linalg.inv(np.dot(x.T,np.dot(np.linalg.inv(Omega), x)))
beta_Z = np.dot(xTOx,np.dot(x.T, np.dot(np.linalg.inv(Omega), Z)))
beta = np.random.normal(beta_Z[0][0], xTOx)[0][0]
#Update rho:
w = Z - x*beta
S_w1 = np.sum((w[::3]-np.mean(w[::3]))**2)
S_w1w2 = np.sum((w[::3]-np.mean(w[::3]))*(w[1::3]-np.mean(w[1::3])))
S_w2 = np.sum((w[1::3]-np.mean(w[1::3]))**2)
#from Lee 1989, chap.6:
r = S_w1w2/(np.sqrt(S_w1*S_w2))
rho = (1-rho**2)**((n-1)/2)/(1-rho*r)**(n-(3/2))
print(rho)
# and of covariance w/ new rho:
#cov_mat[0,1] = round(rho, 4)
#cov_mat[1,0] = round(rho, 4)
betaSim[i+1,] = beta
rhoSim[i+1,] = rho
return(betaSim, rhoSim)
Я попытался использовать округление rho, чтобы убедиться, что ковариация пригодна для использования, ноэто не похоже на работу.Видите ли вы другую стратегию, которую я мог бы использовать?