我正在玩这个用于单变量线性混合效果建模的代码。数据集表示:
在R的lme4包的语法中(Bates等,2015),实现的模型可以概括为:
y ~ 1 + (1|students) + (1|instructor) + (1|dept) + service
其中1表示截距项,(1 | x)表示x的随机效应,x表示固定效应。
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import edward as ed
import pandas as pd
import tensorflow as tf
import matplotlib.pyplot as plt
from edward.models import Normal
from observations import insteval
data = pd.DataFrame(data, columns=metadata['columns'])
train = data.sample(frac=0.8)
test = data.drop(train.index)
train.head()
s_train = train['s'].values
d_train = train['dcodes'].values
dept_train = train['deptcodes'].values
y_train = train['y'].values
service_train = train['service'].values
n_obs_train = train.shape[0]
s_test = test['s'].values
d_test = test['dcodes'].values
dept_test = test['deptcodes'].values
y_test = test['y'].values
service_test = test['service'].values
n_obs_test = test.shape[0]
n_s = max(s_train) + 1 # number of students
n_d = max(d_train) + 1 # number of instructors
n_dept = max(dept_train) + 1 # number of departments
n_obs = train.shape[0] # number of observations
# 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.get_variable("mu", [])
service = tf.get_variable("service", [])
sigma_s = tf.sqrt(tf.exp(tf.get_variable("sigma_s", [])))
sigma_d = tf.sqrt(tf.exp(tf.get_variable("sigma_d", [])))
sigma_dept = tf.sqrt(tf.exp(tf.get_variable("sigma_dept", [])))
# 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))
#Inference
q_eta_s = Normal(
loc=tf.get_variable("q_eta_s/loc", [n_s]),
scale=tf.nn.softplus(tf.get_variable("q_eta_s/scale", [n_s])))
q_eta_d = Normal(
loc=tf.get_variable("q_eta_d/loc", [n_d]),
scale=tf.nn.softplus(tf.get_variable("q_eta_d/scale", [n_d])))
q_eta_dept = Normal(
loc=tf.get_variable("q_eta_dept/loc", [n_dept]),
scale=tf.nn.softplus(tf.get_variable("q_eta_dept/scale", [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)
这在线性混合效果建模的单变量情况下工作正常。我试图将这种方法扩展到多变量情况。任何想法都非常受欢迎。
答案 0 :(得分:0)
有多种方法可以在 Python 中进行线性混合效应模型。看起来您已经调整了 Tensorflow approach,但如果这不是硬性要求,那么还有其他几个可能更方便的选项。
您可以使用 LMER 的 Statsmodels implementation,它很方便地包含在 Python 中,但语法与 R 的 LMER 中的传统公式表达式略有不同。看起来您正在使用 python 将数据拆分为训练集和测试集,因此您还可以编写一个循环来调用
您还可以在本地计算机上安装 R 和 rpy2,并从 Python 环境调用 LMER 包。这使您可以熟悉在 R 中工作,但允许您在 Python 中完成其他所有工作。您所要做的就是在 Jupyter Notebooks 的单元格块中使用 rmagic %%R 或(%R 表示内联)在 Python 和 R 之间传递变量和模型。如果您传递训练/测试数据,后者会很有用您将 Python 拆分为 R 以运行 lmer 并在循环中检索参数。
最后,另一种选择是使用 Pymer4,它是 rpy2 的包装器,允许您在 R 中直接调用 LMER,而无需处理 rmagic。
我wrote a tutorial了解如何将 LMER 与这些方法中的每一种一起使用,这些方法也适用于 Google Colab 等云设置。这些方法都将允许您运行多变量方法,就像您要求在 R 中使用 LMER 但在 Python 环境中一样。