无法为 X 设置跟踪监视器。未找到变量 X

问题描述 投票:0回答:1

我正在尝试实施贝叶斯模型来预测足球比分(英超联赛)。我假设分数的数量遵循参数为 lambda 的泊松分布,这是一般公式:

log(home_lambda) = mu + hfa + home_attack -away_def

log(away_lambda) = mu +away_attack - home_def

其中 mu 和 hfa 分别是拦截优势和主场优势。这是我的数据 (380 x 8)

所以基本上我有380x2的方程和42个参数(mu,hfa,20支球队的攻击能力和20支球队的防守能力)。以第一场比赛为例:

FTHG[1] ~ dpois(home_lambda[1]) # FTHG is full time home goal
log(home_lambda[1]) = mu + hfa + att_Crystal_Palace - att_Arsenal

FTAG[1] ~ dpois(lam_a[1]) # FTAG is full time away goal
log(away_lambda[1]) = mu + att_Arsenal - def_Crystal_Palace

下面是我的整个代码

bayes_mod_string = " model{
  
  for (i in 1:380){
  
    FTHG[i] ~ dpois(lam_h[i])
    log(lam_h[i]) = mu + hfa + h_att[i] - a_def[i]
    FTAG[i] ~ dpois(lam_a[i])
    log(lam_a[i]) = mu + a_att[i] - h_def[i]
    
    h_att[i] ~ dnorm(0, 1/1e6) # the attack and defence ability of each team follows a Normal distribution
    a_def[i] ~ dnorm(0, 1/1e6)
    a_att[i] ~ dnorm(0, 1/1e6)
    h_def[i] ~ dnorm(0, 1/1e6)

  }
  
  mu ~ dnorm(0, 1/1e6)
  hfa ~ dnorm(0, 1/1e6)
  
}"

data_jags = as.list(test_set)

params = c('mu', 'hfa', unique(test_set$h_att), unique(test_set$a_def)) # 42 in total

bayes_mod_string = jags.model(textConnection(bayes_mod_string), 
                              data = data_jags, n.chains = 3)
update(bayes_mod_string, 1e3)

bayes_mod_sim = coda.samples(model = bayes_mod_string,
                             variable.names = params, n.iter = 1e3)
bayes_mod_csim = as.mcmc(do.call(rbind, bayes_mod_sim))

错误信息是

警告:无法为 att_Crystal_Palace 设置跟踪监视器 未找到变量 att_Crystal_Palace

不仅包含“att_Crystal_Palace”参数,还包含所有参数。

我尝试分别输入每个团队的攻击和防御能力,将它们放入和取出for循环

att_Crystal_Palace  ~ dnorm(0, 1/1e6)
  att_Fulham  ~ dnorm(0, 1/1e6)
  att_Bournemouth  ~ dnorm(0, 1/1e6)
  att_Leeds  ~ dnorm(0, 1/1e6)
  att_Newcastle  ~ dnorm(0, 1/1e6)
  att_Tottenham  ~ dnorm(0, 1/1e6)
  att_Everton  ~ dnorm(0, 1/1e6)
  att_Leicester  ~ dnorm(0, 1/1e6)  
  att_Man_United  ~ dnorm(0, 1/1e6)
  att_West_Ham  ~ dnorm(0, 1/1e6)
  att_Aston_Villa  ~ dnorm(0, 1/1e6)
  att_Arsenal  ~ dnorm(0, 1/1e6)
  att_Brighton  ~ dnorm(0, 1/1e6)
  att_Man_City  ~ dnorm(0, 1/1e6)
  att_Southampton  ~ dnorm(0, 1/1e6)
  att_Wolves  ~ dnorm(0, 1/1e6)
  att_Brentford  ~ dnorm(0, 1/1e6)
  att_Nottm_Forest  ~ dnorm(0, 1/1e6)
  att_Chelsea  ~ dnorm(0, 1/1e6)
  att_Liverpool ~ dnorm(0, 1/1e6)
  
  def_Crystal_Palace  ~ dnorm(0, 1/1e6)
  def_Fulham  ~ dnorm(0, 1/1e6)
  def_Bournemouth  ~ dnorm(0, 1/1e6)
  def_Leeds  ~ dnorm(0, 1/1e6)
  def_Newcastle  ~ dnorm(0, 1/1e6)
  def_Tottenham  ~ dnorm(0, 1/1e6)
  def_Everton  ~ dnorm(0, 1/1e6)
  def_Leicester  ~ dnorm(0, 1/1e6)  
  def_Man_United  ~ dnorm(0, 1/1e6)
  def_West_Ham  ~ dnorm(0, 1/1e6)
  def_Aston_Villa  ~ dnorm(0, 1/1e6)
  def_Arsenal  ~ dnorm(0, 1/1e6)
  def_Brighton  ~ dnorm(0, 1/1e6)
  def_Man_City  ~ dnorm(0, 1/1e6)
  def_Southampton  ~ dnorm(0, 1/1e6)
  def_Wolves  ~ dnorm(0, 1/1e6)
  def_Brentford  ~ dnorm(0, 1/1e6)
  def_Nottm_Forest  ~ dnorm(0, 1/1e6)
  def_Chelsea  ~ dnorm(0, 1/1e6)
  def_Liverpool ~ dnorm(0, 1/1e6)

这次的错误是

运行时错误: 第 50 行出现编译错误。 尝试重新定义节点 def_Liverpool[1]

问题到底是什么?我该如何解决? 如果您想获取数据,请点击此处 https://www.football-data.co.uk/englandm.php,2022/2023 赛季

r bayesian jags
1个回答
0
投票

您的首要问题就在这里

log(lam_h[i]) = mu + hfa + h_att[i] - a_def[i]
正如您所说,

h_att[i]
解析为
att_Arsenal
,但您没有定义名为
att_Arsenal
的节点(变量)。您对
h_def
a_att
a_def
也有同样的问题。

处理如此数量的预测变量的最简单方法是使用数组而不是独立标量。我使用了您提供的链接中 2023/24 赛季的数据。我的输入数据如下所示:

df
# A tibble: 39 × 7
   Div   Date       Time  HomeTeam AwayTeam  FTHG  FTAG
   <chr> <chr>      <chr>    <int>    <int> <int> <int>
 1 E0    11/08/2023 20:00        6       13     0     3
 2 E0    12/08/2023 12:30        1       16     2     1
 3 E0    12/08/2023 15:00        3       19     1     1
 4 E0    12/08/2023 15:00        5       12     4     1
 5 E0    12/08/2023 15:00        9       10     0     1
 6 E0    12/08/2023 15:00       17        8     0     1
 7 E0    12/08/2023 17:30       15        2     5     1
 8 E0    13/08/2023 14:00        4       18     2     2
 9 E0    13/08/2023 16:30        7       11     1     1
10 E0    14/08/2023 20:00       14       20     1     0
# … with 29 more rows

我按字母顺序对

HomeTeam
AwayTeam
进行了索引。所以,阿森纳是
1
,狼队是
20

然后我可以将模型字符串写为

bayes_mod_string = " 
data {
  mu ~ dnorm(0, 1/1e6)
  hfa ~ dnorm(0, 1/1e6)
  for (j in 1:nTeams) {
    h_att[j] ~ dnorm(0, 1/1e6) 
    a_def[j] ~ dnorm(0, 1/1e6)
    a_att[j] ~ dnorm(0, 1/1e6)
    h_def[j] ~ dnorm(0, 1/1e6)
    log(lam_h[j]) = mu + hfa + h_att[j] - a_def[j]
    log(lam_a[j]) = mu + a_att[j] - h_def[j]
  }
}

model {
  for (i in 1:nMatches) {
    FTHG[i] ~ dpois(lam_h[home[i]])
    FTAG[i] ~ dpois(lam_a[away[i]])
  }
}
"

注意模型块中

lam_a
lam_h
的双索引。

我更新模型并获取样本

library(rjags)

bayes_model = jags.model(textConnection(bayes_mod_string), 
                              data = data_jags, n.chains = 3)
data_jags <- list(
  nTeams = 20,
  nMatches = nrow(df),
  FTHG = df$FTHG,
  FTAG = df$FTAG,
  home = df$HomeTeam,
  away = df$AwayTeam
)

update(bayes_model, 1e3)

samples <- jags.samples(
  model = bayes_model,
  variable.names = c('mu', 'hfa', paste0("h_att[", 1:20, "]"), paste0("a_def[", 1:20, "]")), 
  n.iter = 1e3
)

请注意,我已将

coda.samples
更改为
jags.samples

我省略了打印

samples
,因为输出相当长。

就我个人而言,我更喜欢

runjags
而不是
rjags
。您可以直接使用模型字符串,而不是通过文本连接传递或写入文件,模型拟合代码更紧凑,我觉得输出更紧凑,信息更丰富。

library(runjags)

run.jags(
  bayes_mod_string, 
  data = data_jags,
  monitor = c('mu', 'hfa', paste0("h_att[", 1:20, "]"), paste0("a_def[", 1:20, "]"))
)
Compiling rjags model...
Calling the simulation using the rjags method...
Note: the model did not require adaptation
Burning in the model for 4000 iterations...
  |**************************************************| 100%
Running the model for 10000 iterations...
  |**************************************************| 100%
Simulation complete
Calculating summary statistics...
Note: The monitored variables 'mu', 'hfa', 'h_att[1]', 'h_att[2]', 'h_att[3]', 'h_att[4]', 'h_att[5]', 'h_att[6]', 'h_att[7]', 'h_att[8]', 'h_att[9]',
'h_att[10]', 'h_att[11]', 'h_att[12]', 'h_att[13]', 'h_att[14]', 'h_att[15]', 'h_att[16]', 'h_att[17]', 'h_att[18]', 'h_att[19]', 'h_att[20]', 'a_def[1]',
'a_def[2]', 'a_def[3]', 'a_def[4]', 'a_def[5]', 'a_def[6]', 'a_def[7]', 'a_def[8]', 'a_def[9]', 'a_def[10]', 'a_def[11]', 'a_def[12]', 'a_def[13]',
'a_def[14]', 'a_def[15]', 'a_def[16]', 'a_def[17]', 'a_def[18]', 'a_def[19]' and 'a_def[20]' appear to be non-stochastic; they will not be included in the
convergence diagnostic
Finished running the simulation

JAGS model summary statistics from 20000 samples (chains = 2; adapt+burnin = 5000):
                                                                         
          Lower95 Upper95    Mean SD Mode MCerr MC%ofSD SSeff Lag.10 psrf
mu         827.99  827.99  827.99  0   --    --      --    --     --   --
hfa        1122.6  1122.6  1122.6  0   --    --      --    --     --   --
h_att[1]   287.62  287.62  287.62  0   --    --      --    --     --   --
h_att[2]  -696.89 -696.89 -696.89  0   --    --      --    --     --   --
h_att[3]   332.89  332.89  332.89  0   --    --      --    --     --   --
h_att[4]   941.39  941.39  941.39  0   --    --      --    --     --   --
h_att[5]   795.37  795.37  795.37  0   --    --      --    --     --   --
<further output omitted>

重要输出缺乏可变性表明模型规范或我的实现存在问题。就我个人而言,我会采用分层模型。我现在没有时间进一步探索,但至少我已经为您提供了如何继续的线索。

© www.soinside.com 2019 - 2024. All rights reserved.