Python 将PyMC2代码移植到PyMC3-用于体育分析的分层模型
我尝试了以下代码,但遇到了问题。 我想。值是个问题,但我如何将其编码为Theano对象呢 以下是我的数据源Python 将PyMC2代码移植到PyMC3-用于体育分析的分层模型,python,pymc,pymc3,Python,Pymc,Pymc3,我尝试了以下代码,但遇到了问题。 我想。值是个问题,但我如何将其编码为Theano对象呢 以下是我的数据源 home_team,away_team,home_score,away_score Wales,Italy,23,15 France,England,26,24 Ireland,Scotland,28,6 Ireland,Wales,26,3 Scotland,England,0,20 France,Italy,30,10 Wales,France,27,6 Italy,Scotland,
home_team,away_team,home_score,away_score
Wales,Italy,23,15
France,England,26,24
Ireland,Scotland,28,6
Ireland,Wales,26,3
Scotland,England,0,20
France,Italy,30,10
Wales,France,27,6
Italy,Scotland,20,21
England,Ireland,13,10
Ireland,Italy,46,7
Scotland,France,17,19
England,Wales,29,18
Italy,England,11,52
Wales,Scotland,51,3
France,Ireland,20,22
以下是PyMC2代码,它可以工作:
数据文件=数据目录+结果文件2014.csv
df = pd.read_csv(data_file, sep=',')
# Or whatever it takes to get this into a data frame.
teams = df.home_team.unique()
teams = pd.DataFrame(teams, columns=['team'])
teams['i'] = teams.index
df = pd.merge(df, teams, left_on='home_team', right_on='team', how='left')
df = df.rename(columns = {'i': 'i_home'}).drop('team', 1)
df = pd.merge(df, teams, left_on='away_team', right_on='team', how='left')
df = df.rename(columns = {'i': 'i_away'}).drop('team', 1)
observed_home_goals = df.home_score.values
observed_away_goals = df.away_score.values
home_team = df.i_home.values
away_team = df.i_away.values
num_teams = len(df.i_home.drop_duplicates())
num_games = len(home_team)
g = df.groupby('i_away')
att_starting_points = np.log(g.away_score.mean())
g = df.groupby('i_home')
def_starting_points = -np.log(g.away_score.mean())
#hyperpriors
home = pymc.Normal('home', 0, .0001, value=0)
tau_att = pymc.Gamma('tau_att', .1, .1, value=10)
tau_def = pymc.Gamma('tau_def', .1, .1, value=10)
intercept = pymc.Normal('intercept', 0, .0001, value=0)
#team-specific parameters
atts_star = pymc.Normal("atts_star",
mu=0,
tau=tau_att,
size=num_teams,
value=att_starting_points.values)
defs_star = pymc.Normal("defs_star",
mu=0,
tau=tau_def,
size=num_teams,
value=def_starting_points.values)
# trick to code the sum to zero constraint
@pymc.deterministic
def atts(atts_star=atts_star):
atts = atts_star.copy()
atts = atts - np.mean(atts_star)
return atts
@pymc.deterministic
def defs(defs_star=defs_star):
defs = defs_star.copy()
defs = defs - np.mean(defs_star)
return defs
@pymc.deterministic
def home_theta(home_team=home_team,
away_team=away_team,
home=home,
atts=atts,
defs=defs,
intercept=intercept):
return np.exp(intercept +
home +
atts[home_team] +
defs[away_team])
@pymc.deterministic
def away_theta(home_team=home_team,
away_team=away_team,
home=home,
atts=atts,
defs=defs,
intercept=intercept):
return np.exp(intercept +
atts[away_team] +
defs[home_team])
home_points = pymc.Poisson('home_points',
mu=home_theta,
value=observed_home_goals,
observed=True)
away_points = pymc.Poisson('away_points',
mu=away_theta,
value=observed_away_goals,
observed=True)
mcmc = pymc.MCMC([home, intercept, tau_att, tau_def,
home_theta, away_theta,
atts_star, defs_star, atts, defs,
home_points, away_points])
map_ = pymc.MAP( mcmc )
map_.fit()
mcmc.sample(200000, 40000, 20)
我尝试移植到PyMC3:)
我包括了争吵的代码。
我定义了自己的数据目录等
data_file = DATA_DIR + 'results_2014.csv'
df = pd.read_csv(data_file, sep=',')
# Or whatever it takes to get this into a data frame.
teams = df.home_team.unique()
teams = pd.DataFrame(teams, columns=['team'])
teams['i'] = teams.index
df = pd.merge(df, teams, left_on='home_team', right_on='team', how='left')
df = df.rename(columns = {'i': 'i_home'}).drop('team', 1)
df = pd.merge(df, teams, left_on='away_team', right_on='team', how='left')
df = df.rename(columns = {'i': 'i_away'}).drop('team', 1)
observed_home_goals = df.home_score.values
observed_away_goals = df.away_score.values
home_team = df.i_home.values
away_team = df.i_away.values
num_teams = len(df.i_home.drop_duplicates())
num_games = len(home_team)
g = df.groupby('i_away')
att_starting_points = np.log(g.away_score.mean())
g = df.groupby('i_home')
def_starting_points = -np.log(g.away_score.mean())
import theano.tensor as T
import pymc3 as pm3
#hyperpriors
x = att_starting_points.values
y = def_starting_points.values
model = pm.Model()
with pm3.Model() as model:
home3 = pm3.Normal('home', 0, .0001)
tau_att3 = pm3.Gamma('tau_att', .1, .1)
tau_def3 = pm3.Gamma('tau_def', .1, .1)
intercept3 = pm3.Normal('intercept', 0, .0001)
#team-specific parameters
atts_star3 = pm3.Normal("atts_star",
mu=0,
tau=tau_att3,
observed=x)
defs_star3 = pm3.Normal("defs_star",
mu=0,
tau=tau_def3,
observed=y)
#Seems to be the error here.
atts = pm3.Deterministic('regression',
atts_star3 - np.mean(atts_star3))
home_theta3 = pm3.Deterministic('regression',
T.exp(intercept3 + atts[away_team] + defs[home_team]))
atts = pm3.Deterministic('regression', atts_star3 - np.mean(atts_star3))
home_theta3 = pm3.Deterministic('regression', T.exp(intercept3 + atts[away_team] + defs[home_team]))
# Unknown model parameters
home_points3 = pm3.Poisson('home_points', mu=home_theta3, observed=observed_home_goals)
away_points3 = pm3.Poisson('away_points', mu=home_theta3, observed=observed_away_goals)
start = pm3.find_MAP()
step = pm3.NUTS(state=start)
trace = pm3.sample(2000, step, start=start, progressbar=True)
pm3.traceplot(trace)
我得到一个错误,比如值不是Theano对象。
我想这就是上面的价值观部分。但我不知道如何把它转换成Theano张量。张量让我困惑:)
为了清楚起见,这个错误是因为我误解了PyMC3语法中的某些内容
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-71-ce51c1a64412> in <module>()
23
24 #Seems to be the error here.
---> 25 atts = pm3.Deterministic('regression', atts_star3 - np.mean(atts_star3))
26 home_theta3 = pm3.Deterministic('regression', T.exp(intercept3 + atts[away_team] + defs[home_team]))
27
/Users/peadarcoyle/anaconda/lib/python3.4/site-packages/numpy/core/fromnumeric.py in mean(a, axis, dtype, out, keepdims)
2733
2734 return _methods._mean(a, axis=axis, dtype=dtype,
-> 2735 out=out, keepdims=keepdims)
2736
2737 def std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
/Users/peadarcoyle/anaconda/lib/python3.4/site-packages/numpy/core/_methods.py in _mean(a, axis, dtype, out, keepdims)
71 ret = ret.dtype.type(ret / rcount)
72 else:
---> 73 ret = ret / rcount
74
75 return ret
TypeError: unsupported operand type(s) for /: 'ObservedRV' and 'int'
---------------------------------------------------------------------------
TypeError回溯(最近一次调用上次)
在()
23
24#似乎是这里的错误。
--->25 atts=pm3.确定性('回归',atts_star3-np.平均值(atts_star3))
26 home_theta3=pm3.Deterministic('回归',T.exp(截距3+atts[客场团队]+defs[主场团队])
27
/Users/peadarcoyle/anaconda/lib/python3.4/site-packages/numpy/core/fromnumeric.py的平均值(a、axis、dtype、out、keepdims)
2733
2734返回方法。平均值(a,axis=axis,dtype=dtype,
->2735 out=out,keepdims=keepdims)
2736
2737 def std(a,轴=无,数据类型=无,输出=无,ddof=0,keepdims=假):
/Users/peadarcoyle/anaconda/lib/python3.4/site-packages/numpy/core//u methods.py in\u mean(a、axis、dtype、out、keepdims)
71 ret=ret.dtype.type(ret/rcount)
72其他:
--->73 ret=ret/rcount
74
75返回ret
TypeError:/:“ObservedRV”和“int”的操作数类型不受支持
您的模型失败,因为您无法在无张量上使用NumPy函数。因此
np.mean(atts_star3)
会给你一个错误。您可以删除atts\u star3=pm3.Normal(“atts\u star”,…)
并直接使用NumPy数组atts\u star3=x
我认为您也不需要显式地建模tau_att3
,tau_def3
或defs_star
或者,如果你想保留这些变量,你可以将
np.mean
替换为theano.tensor.mean
,这应该是可行的。它不是我以前版本的直接端口,但它给了我一个答案。有人有任何反馈吗
import os
import math
import warnings
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import pymc3 as pm3# I know folks are switching to "as pm" but I'm just not there yet
%matplotlib inline
import seaborn as sns
from IPython.core.pylabtools import figsize
import seaborn as sns
import theano.tensor as T
figsize(12, 12)
DATA_DIR = os.path.join(os.getcwd(), 'data/')
data_file = DATA_DIR + 'results_2014.csv'
df = pd.read_csv(data_file, sep=',')
# Or whatever it takes to get this into a data frame.
teams = df.home_team.unique()
teams = pd.DataFrame(teams, columns=['team'])
teams['i'] = teams.index
df = pd.merge(df, teams, left_on='home_team', right_on='team', how='left')
df = df.rename(columns = {'i': 'i_home'}).drop('team', 1)
df = pd.merge(df, teams, left_on='away_team', right_on='team', how='left')
df = df.rename(columns = {'i': 'i_away'}).drop('team', 1)
observed_home_goals = df.home_score.values
observed_away_goals = df.away_score.values
home_team = df.i_home.values
away_team = df.i_away.values
num_teams = len(df.i_home.drop_duplicates())
num_games = len(home_team)
g = df.groupby('i_away')
att_starting_points = np.log(g.away_score.mean())
g = df.groupby('i_home')
def_starting_points = -np.log(g.away_score.mean())
import theano.tensor as T
import pymc3 as pm3
#hyperpriors
'''
def atts3(atts_star3=atts_star3):
atts3 = atts_star.copy()
atts3 = atts3 - np.mean(atts_star)
return atts3
def defs3(defs_star3=defs_star3):
defs3 = defs_star3.copy()
defs3 = defs3 - np.mean(defs_star3)
return defs
'''
model = pm3.Model()
with pm3.Model() as model:
home3 = pm3.Normal('home', 0, .0001)
tau_att3 = pm3.Gamma('tau_att', .1, .1)
tau_def3 = pm3.Gamma('tau_def', .1, .1)
intercept3 = pm3.Normal('intercept', 0, .0001)
#team-specific parameters
atts_star3 = pm3.Normal("atts_star",
mu=0,
tau=tau_att3,
shape=num_teams,
observed=att_starting_points.values)
defs_star3 = pm3.Normal("defs_star",
mu=0,
tau=tau_def3,
shape=num_teams,
observed=def_starting_points.values)
#home_theta3 = atts3 + defs3
#away_theta3 = atts3 + defs3
# Unknown model parameters
home_points3 = pm3.Poisson('home_points', mu=1, observed=observed_home_goals)
away_points3 = pm3.Poisson('away_points', mu=1, observed=observed_away_goals)
start = pm3.find_MAP()
step = pm3.NUTS(state=start)
trace = pm3.sample(2000, step, start=start, progressbar=True)
pm3.traceplot(trace)
以下是我对PyMC2模型的翻译:
model = pm.Model()
with pm.Model() as model:
# global model parameters
home = pm.Normal('home', 0, .0001)
tau_att = pm.Gamma('tau_att', .1, .1)
tau_def = pm.Gamma('tau_def', .1, .1)
intercept = pm.Normal('intercept', 0, .0001)
# team-specific model parameters
atts_star = pm.Normal("atts_star",
mu =0,
tau =tau_att,
shape=num_teams)
defs_star = pm.Normal("defs_star",
mu =0,
tau =tau_def,
shape=num_teams)
atts = pm.Deterministic('atts', atts_star - tt.mean(atts_star))
defs = pm.Deterministic('defs', defs_star - tt.mean(defs_star))
home_theta = tt.exp(intercept + home + atts[home_team] + defs[away_team]
away_theta = tt.exp(intercept + atts[away_team] + defs[home_team])
# likelihood of observed data
home_points = pm.Poisson('home_points', mu=home_theta, observed=observed_home_goals)
away_points = pm.Poisson('away_points', mu=away_theta, observed=observed_away_goals)
在我看来,PyMC2和PyMC3模型构建之间的最大区别在于PyMC2中初始值的整个业务不包括在PyMC3的模型构建中。它被推入代码的模型拟合部分
这是一个笔记本,它将此模型与您的数据和一些拟合代码放在一起:您能添加数据以便我重现您的错误吗?一个小的模拟示例就可以了,只要它引起与实际数据相同的错误。亚伯拉罕我修正了这个并添加了这个。谢谢你的提醒。不需要将数组转换成张量。我还是看不出你到底犯了什么错误。您正在运行最新的PyMC3吗?我只得到“NameError:name'defs'未定义”,这是有意义的,因为它未定义。此外,除非您缺少值或您真的关心“tau_att3”或“tau_def3”(但您不使用它们),否则我认为没有必要对“atts_star”和“defs_star”进行正态分布建模,你可以直接使用这些数据。谢谢你的回答。我试过了,我发现RV不能与int一起工作。我认为这个模型使用了atts_star3等的正态分布,因为这是我基于代码的论文中提到的。我想我需要对代码进行一些重构,然后看看接下来会发生什么。所以在遵循您的建议之后。但现在我得到了这个错误<代码>类型错误回溯(最近一次调用)in()67 68--->69 home\u theta3=pm3.Deterministic('regression',T.exp(intercept3+atts3[way\u team]+defs3[home\u team])70-way\u theta3=pm3.Deterministic('regression',T.exp(intercept3+atts3[way\u team]+defs3[home\u team]))71#未知模型参数TypeError:“function”对象不可下标看起来atts3或defs2实际上是一个函数。也许你运行了上面注释掉的代码?是的,我注释掉了代码,自己添加了一个mu,它为我运行。今天晚些时候我会再调查一下。但我认为它是PyMC3强大功能的一个“黑客”例子。你觉得怎么样?我会发布你的PyMC2代码的翻译,这有点不同。酷:)我很想看看。我接受了你的版本。我的话写得不太好:)谢谢亚伯拉罕。我会把这个添加到我在伦敦的PyData演讲中,但我一定会提到你:)。很好,你能发送幻灯片或演讲录音吗?听起来很有趣。我知道这很古老,但我尝试复制结果,Pymc3的后验概率非常不同(例如,主系数约为0.0)。注意,此代码中存在错误。home_theta的行必须读home_theta=tt.exp(intercept+home+atts[home_team]+defs[away_team],如果没有修复,您会得到与pymc2不同的结果。我花了一段时间才找到这个!这可能也解释了fsocity的问题。