In [1]:
# !pip install edward
# !pip install --upgrade tensorflow
In [2]:
%matplotlib inline
import edward as ed
import pandas as pd
import tensorflow as tf
import matplotlib.pyplot as plt
from edward.models import Normal
plt.style.use('ggplot')
ed.set_seed(1087)
In [5]:
# load data from this url
data = pd.read_csv('insteval.csv')
data['dcodes'] = data['d'].astype('category').cat.codes
data['deptcodes'] = data['dept'].astype('category').cat.codes
data['s'] = data['s'] - 1
train = data.sample(frac=0.8)
test = data.drop(train.index)
train.head()
Out[5]:
In [6]:
s_train = train['s'].values.astype(int)
d_train = train['dcodes'].values.astype(int)
dept_train = train['deptcodes'].values.astype(int)
y_train = train['y'].values.astype(float)
service_train = train['service'].values.astype(int)
n_obs_train = train.shape[0]
s_test = test['s'].values.astype(int)
d_test = test['dcodes'].values.astype(int)
dept_test = test['deptcodes'].values.astype(int)
y_test = test['y'].values.astype(float)
service_test = test['service'].values.astype(int)
n_obs_test = test.shape[0]
In [7]:
n_s = 2972 # number of students
n_d = 1128 # number of instructors
n_dept = 14 # number of departments
n_obs = train.shape[0] # number of observations
In [8]:
# Set up placeholders for the data inputs.
s_ph = tf.placeholder(tf.int32, [None])
d_ph = tf.placeholder(tf.int32, [None])
dept_ph = tf.placeholder(tf.int32, [None])
service_ph = tf.placeholder(tf.float32, [None])
# Set up fixed effects.
mu = tf.Variable(tf.random_normal([]))
service = tf.Variable(tf.random_normal([]))
sigma_s = tf.sqrt(tf.exp(tf.Variable(tf.random_normal([]))))
sigma_d = tf.sqrt(tf.exp(tf.Variable(tf.random_normal([]))))
sigma_dept = tf.sqrt(tf.exp(tf.Variable(tf.random_normal([]))))
# Set up random effects.
eta_s = Normal(loc=tf.zeros(n_s), scale=sigma_s * tf.ones(n_s))
eta_d = Normal(loc=tf.zeros(n_d), scale=sigma_d * tf.ones(n_d))
eta_dept = Normal(loc=tf.zeros(n_dept), scale=sigma_dept * tf.ones(n_dept))
yhat = tf.gather(eta_s, s_ph) + \
tf.gather(eta_d, d_ph) + \
tf.gather(eta_dept, dept_ph) + \
mu + service * service_ph
y = Normal(loc=yhat, scale=tf.ones(n_obs))
In [9]:
q_eta_s = Normal(
loc=tf.Variable(tf.random_normal([n_s])),
scale=tf.nn.softplus(tf.Variable(tf.random_normal([n_s]))))
q_eta_d = Normal(
loc=tf.Variable(tf.random_normal([n_d])),
scale=tf.nn.softplus(tf.Variable(tf.random_normal([n_d]))))
q_eta_dept = Normal(
loc=tf.Variable(tf.random_normal([n_dept])),
scale=tf.nn.softplus(tf.Variable(tf.random_normal([n_dept]))))
latent_vars = {
eta_s: q_eta_s,
eta_d: q_eta_d,
eta_dept: q_eta_dept}
data = {
y: y_train,
s_ph: s_train,
d_ph: d_train,
dept_ph: dept_train,
service_ph: service_train}
inference = ed.KLqp(latent_vars, data)
In [10]:
yhat_test = ed.copy(yhat, {
eta_s: q_eta_s.mean(),
eta_d: q_eta_d.mean(),
eta_dept: q_eta_dept.mean()})
In [12]:
inference.initialize(n_print=20, n_iter=100)
tf.global_variables_initializer().run()
for _ in range(inference.n_iter):
# Update and print progress of algorithm.
info_dict = inference.update()
inference.print_progress(info_dict)
t = info_dict['t']
if t == 1 or t % inference.n_print == 0:
# Make predictions on test data.
yhat_vals = yhat_test.eval(feed_dict={
s_ph: s_test,
d_ph: d_test,
dept_ph: dept_test,
service_ph: service_test})
# Form residual plot.
plt.title("Residuals for Predicted Ratings on Test Set")
plt.xlim(-4, 4)
plt.ylim(0, 800)
plt.hist(yhat_vals - y_test, 75)
plt.show()
In [ ]: