6 votos

Implementación de PyMC3 de Factorización de Matriz Probabilística (FMP): MAP produce todo 0s

He comenzado a trabajar con pymc3 en los últimos días, y después de tener una idea de lo básico, intenté implementar el modelo Probabilistic Matrix Factorization.

Para la validación, utilizo un subconjunto del conjunto de datos Jester. Tomo los primeros 100 usuarios que calificaron todos los 100 chistes. Utilizo los primeros 20 chistes y dejo las calificaciones sin cambios; están en el rango [-10, 10] para todos los chistes. Para mayor comodidad, he puesto a disposición este subconjunto aquí.

import pymc3 as pm
import numpy as np
import pandas as pd
import theano

data = pd.read_csv('jester-dense-subset-100x20.csv')    
n, m = data.shape
test_size = m / 10
train_size = m - test_size

train = data.copy()
train.ix[:,train_size:] = np.nan  # remove test set data
train[train.isnull()] = train.mean().mean()  # mean value imputation
train = train.values

test = data.copy()
test.ix[:,:train_size] = np.nan  # remove train set data
test = test.values    

# Low precision reflects uncertainty; prevents overfitting
alpha_u = alpha_v = 1/np.var(train)
alpha = np.ones((n,m)) * 2  # fixed precision for likelihood function
dim = 10  # dimensionality

# Specify the model.
with pm.Model() as pmf:
    pmf_U = pm.MvNormal('U', mu=0, tau=alpha_u * np.eye(dim),
                        shape=(n, dim))
    pmf_V = pm.MvNormal('V', mu=0, tau=alpha_v * np.eye(dim),
                        shape=(m, dim))
    pmf_R = pm.Normal('R', mu=theano.tensor.dot(pmf_U, pmf_V.T),
                      tau=alpha, observed=train)

    # Find mode of posterior using optimization
    start = pm.find_MAP()  # Find starting values by optimization

Todo parece funcionar espléndidamente, pero los valores producidos por find_MAP terminan siendo todos 0s tanto para U como para V, lo cual se puede ver al ejecutar:

(start['U'] == 0).all()
(start['V'] == 0).all()

Soy relativamente nuevo tanto en modelado bayesiano como en pymc, así que podría estar pasando por alto algo obvio aquí. ¿Por qué obtengo todos 0s?

5voto

superuser Puntos 133

Hice dos cosas para arreglar tu código. Una fue inicializar el modelo lejos de cero, la otra fue usar un optimizador no basado en gradientes:

import pymc3 as pm
import numpy as np
import pandas as pd
import theano
import scipy as sp

data = pd.read_csv('jester-dense-subset-100x20.csv')    
n, m = data.shape
test_size = m / 10
train_size = m - test_size

train = data.copy()
train.ix[:,train_size:] = np.nan  # remover datos del conjunto de pruebas
train[train.isnull()] = train.mean().mean()  # imputación del valor medio
train = train.values

test = data.copy()
test.ix[:,:train_size] = np.nan  # remover datos del conjunto de entrenamiento
test = test.values    

# La baja precisión refleja incertidumbre; previene el sobreajuste
alpha_u = alpha_v = 1/np.var(train)
alpha = np.ones((n,m)) * 2  # precisión fija para la función de verosimilitud
dim = 10  # dimensionalidad

# Especificar el modelo.
with pm.Model() as pmf:
    pmf_U = pm.MvNormal('U', mu=0, tau=alpha_u * np.eye(dim),
                        shape=(n, dim), testval=np.random.randn(n, dim)*.01)
    pmf_V = pm.MvNormal('V', mu=0, tau=alpha_v * np.eye(dim),
                        shape=(m, dim), testval=np.random.randn(m, dim)*.01)
    pmf_R = pm.Normal('R', mu=theano.tensor.dot(pmf_U, pmf_V.T),
                      tau=alpha, observed=train)

    # Encontrar el modo de la posterior utilizando optimización
    start = pm.find_MAP(fmin=sp.optimize.fmin_powell)  # Encontrar valores de inicio mediante optimización

    step = pm.NUTS(scaling=start)
    trace = pm.sample(500, step, start=start)

Este es un modelo interesante que sería una gran contribución. Por favor considera agregar esto, una vez que estés seguro de que funciona como se desea, a la carpeta de ejemplos y haz una solicitud de extracción (pull request).

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X