Skip to content

Instantly share code, notes, and snippets.

@yamaguchiyuto
Last active September 25, 2017 06:47
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yamaguchiyuto/25334f067098786d3edfb84f08491f0a to your computer and use it in GitHub Desktop.
Save yamaguchiyuto/25334f067098786d3edfb84f08491f0a to your computer and use it in GitHub Desktop.
Probabilistic matrix factorization using Edward
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import tensorflow as tf\n",
"import edward as ed\n",
"import numpy as np\n",
"\n",
"from edward.models import Normal\n",
"\n",
"ed.set_seed(42)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"def build_dataset(U, V, n_samples):\n",
" N = U.shape[0]\n",
" M = V.shape[0]\n",
" K = U.shape[1]\n",
" X = []\n",
" sampled = set()\n",
" \n",
" for _ in range(n_samples):\n",
" i = np.random.randint(N)\n",
" j = np.random.randint(N)\n",
" while (i, j) in sampled:\n",
" i = np.random.randint(N)\n",
" j = np.random.randint(N)\n",
" sampled.add((i, j))\n",
" X.append([i, j])\n",
" \n",
" X = np.array(X)\n",
" y = np.random.normal(loc = np.sum(U[X[:, 0]] * V[X[:, 1]], axis=1), scale = 1.0)\n",
" \n",
" return X, y\n",
"\n",
"def train_test_split(X, y, test_ratio):\n",
" n_samples = X.shape[0]\n",
" test_indices = np.random.binomial(1, test_ratio, size = n_samples)\n",
" return X[test_indices==0], y[test_indices==0], X[test_indices==1], y[test_indices==1]\n",
" \n",
"N = 30\n",
"M = 40\n",
"K = 5 # number of latent dimensions\n",
"n_samples = 300\n",
"U_true = np.random.normal(loc = 0.0, scale = 1.0, size = (N, K))\n",
"V_true = np.random.normal(loc = 0.0, scale = 1.0, size = (M, K))\n",
"X_data, y_data = build_dataset(U_true, V_true, n_samples)\n",
"\n",
"test_ratio = 0.1\n",
"X_train, y_train, X_test, y_test = train_test_split(X_data, y_data, test_ratio)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# Building the model\n",
"\n",
"X_ph = tf.placeholder(tf.int32, [None, 2])\n",
"\n",
"U = Normal(loc = tf.zeros([N, K]), scale = tf.ones([N, K]))\n",
"V = Normal(loc = tf.zeros([M, K]), scale = tf.ones([M, K]))\n",
"y = Normal(loc = tf.reduce_sum(tf.gather(U, X_ph[:, 0]) * tf.gather(V, X_ph[:, 1]), axis=1), scale = tf.ones_like(tf.reduce_sum(tf.gather(U, X_ph[:, 0]) * tf.gather(V, X_ph[:, 1]), axis=1)))"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# Building the variational model\n",
"\n",
"qU = Normal(loc = tf.Variable(tf.random_normal([N, K])), scale = tf.nn.softplus(tf.Variable(tf.random_normal([N, K]))))\n",
"qV = Normal(loc = tf.Variable(tf.random_normal([M, K])), scale = tf.nn.softplus(tf.Variable(tf.random_normal([M, K]))))"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1000/1000 [100%] ██████████████████████████████ Elapsed: 3s | Loss: 710.425\n"
]
}
],
"source": [
"# Inference\n",
"\n",
"inference = ed.KLqp({U: qU, V: qV}, data = {X_ph: X_train, y: y_train})\n",
"inference.run(n_iter = 1000)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Mean squared error of posterior: 3.83919\n",
"Mean squared error of prior: 6.11875\n"
]
}
],
"source": [
"# Evaluation\n",
"\n",
"y_prior = y\n",
"y_post = Normal(loc = tf.reduce_sum(tf.gather(qU, X_ph[:, 0]) * tf.gather(qV, X_ph[:, 1]), axis=1), scale = tf.ones_like(tf.reduce_sum(tf.gather(qU, X_ph[:, 0]) * tf.gather(qV, X_ph[:, 1]), axis=1)))\n",
"\n",
"print(\"Mean squared error of posterior: \", ed.evaluate(\"mean_squared_error\", data = {X_ph: X_test, y_post: y_test}))\n",
"print(\"Mean squared error of prior: \", ed.evaluate(\"mean_squared_error\", data = {X_ph: X_test, y_prior: y_test}))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment