gpt4 book ai didi

python - 使用 `LKJCorr` 先验 : PositiveDefiniteError using `NUTS` 在 PyMC3 中修改 BPMF

转载 作者:太空狗 更新时间:2023-10-30 00:10:33 26 4
gpt4 key购买 nike

我之前实现了原始的 Bayesian Probabilistic Matrix Factorization (BPMF) pymc3 中的模型。 See my previous question供引用、数据源和问题设置。根据@twiecki 对该问题的回答,我已经使用 LKJCorr 先验相关矩阵和标准差统一先验实现了模型的变体。在原始模型中,协方差矩阵是从 Wishart 分布中提取的,但是由于 pymc3 当前的限制,无法从 Wishart 分布中正确采样。 This answer对一个松散相关的问题提供了对 LKJCorr 先验选择的简洁解释。新模型如下。

import pymc3 as pm
import numpy as np
import theano.tensor as t


n, m = train.shape
dim = 10 # dimensionality
beta_0 = 1 # scaling factor for lambdas; unclear on its use
alpha = 2 # fixed precision for likelihood function
std = .05 # how much noise to use for model initialization

# We will use separate priors for sigma and correlation matrix.
# In order to convert the upper triangular correlation values to a
# complete correlation matrix, we need to construct an index matrix:
n_elem = dim * (dim - 1) / 2
tri_index = np.zeros([dim, dim], dtype=int)
tri_index[np.triu_indices(dim, k=1)] = np.arange(n_elem)
tri_index[np.triu_indices(dim, k=1)[::-1]] = np.arange(n_elem)

logging.info('building the BPMF model')
with pm.Model() as bpmf:
# Specify user feature matrix
sigma_u = pm.Uniform('sigma_u', shape=dim)
corr_triangle_u = pm.LKJCorr(
'corr_u', n=1, p=dim,
testval=np.random.randn(n_elem) * std)

corr_matrix_u = corr_triangle_u[tri_index]
corr_matrix_u = t.fill_diagonal(corr_matrix_u, 1)
cov_matrix_u = t.diag(sigma_u).dot(corr_matrix_u.dot(t.diag(sigma_u)))
lambda_u = t.nlinalg.matrix_inverse(cov_matrix_u)

mu_u = pm.Normal(
'mu_u', mu=0, tau=beta_0 * lambda_u, shape=dim,
testval=np.random.randn(dim) * std)
U = pm.MvNormal(
'U', mu=mu_u, tau=lambda_u,
shape=(n, dim), testval=np.random.randn(n, dim) * std)

# Specify item feature matrix
sigma_v = pm.Uniform('sigma_v', shape=dim)
corr_triangle_v = pm.LKJCorr(
'corr_v', n=1, p=dim,
testval=np.random.randn(n_elem) * std)

corr_matrix_v = corr_triangle_v[tri_index]
corr_matrix_v = t.fill_diagonal(corr_matrix_v, 1)
cov_matrix_v = t.diag(sigma_v).dot(corr_matrix_v.dot(t.diag(sigma_v)))
lambda_v = t.nlinalg.matrix_inverse(cov_matrix_v)

mu_v = pm.Normal(
'mu_v', mu=0, tau=beta_0 * lambda_v, shape=dim,
testval=np.random.randn(dim) * std)
V = pm.MvNormal(
'V', mu=mu_v, tau=lambda_v,
testval=np.random.randn(m, dim) * std)

# Specify rating likelihood function
R = pm.Normal(
'R', mu=t.dot(U, V.T), tau=alpha * np.ones((n, m)),
observed=train)

# `start` is the start dictionary obtained from running find_MAP for PMF.
# See the previous post for PMF code.
for key in bpmf.test_point:
if key not in start:
start[key] = bpmf.test_point[key]

with bpmf:
step = pm.NUTS(scaling=start)

此重新实现的目标是生成一个可以使用 NUTS 采样器进行估计的模型。不幸的是,我在最后一行仍然遇到同样的错误:

PositiveDefiniteError: Scaling is not positive definite. Simple check failed. Diagonal contains negatives. Check indexes [   0    1    2    3    ...   1030 1031 1032 1033 1034   ]

我已经在 this gist 中提供了 PMF、BPMF 和这个修改后的 BPMF 的所有代码。使复制错误变得简单。您需要做的就是下载数据(也在要点中引用)。

最佳答案

看起来您正在将完整的精度矩阵传递给正态分布:

mu_u = pm.Normal(
'mu_u', mu=0, tau=beta_0 * lambda_u, shape=dim,
testval=np.random.randn(dim) * std)

我假设您只想传递对角线值:

mu_u = pm.Normal(
'mu_u', mu=0, tau=beta_0 * t.diag(lambda_u), shape=dim,
testval=np.random.randn(dim) * std)

这是否更改为 mu_umu_v 会为您修复它?

关于python - 使用 `LKJCorr` 先验 : PositiveDefiniteError using `NUTS` 在 PyMC3 中修改 BPMF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29759789/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com