# load german football-league (Bundesliga) data
library("ordBTL")
library("wikibooks")
data(Bundesliga)
str(Bundesliga)
## 'data.frame': 13406 obs. of 10 variables:
## $ Saison : Factor w/ 44 levels "1963/1964","1964/1965",..: 1 1 1 1 1 1 1 1 1 1 ...
## $ Spieltag : int 1 1 1 1 1 1 1 1 2 2 ...
## $ Datum : Date, format: "1963-08-24" "1963-08-24" ...
## $ Anpfiff : Factor w/ 31 levels "14:00","14:15",..: 13 13 13 13 13 13 13 13 13 13 ...
## $ Heim : Factor w/ 50 levels "1. FC Kaiserslautern",..: 27 40 16 29 43 33 4 20 15 10 ...
## $ Gast : Factor w/ 50 levels "1. FC Kaiserslautern",..: 3 10 1 32 15 24 2 47 33 43 ...
## $ Tore.Heim : int 1 3 1 1 1 1 0 2 1 3 ...
## $ Tore.Gast : int 1 2 1 4 1 1 2 0 0 3 ...
## $ Tore.Heim.Halbzeit: int 0 1 1 0 1 0 0 2 1 2 ...
## $ Tore.Gast.Halbzeit: int 1 1 1 3 0 0 2 0 0 1 ...
# add new variable Y3 reflecting the response which is coded as
# 1 if the home team wins
# 2 if the game ends up with a tie
# 3 if the home team loses
diff = Bundesliga$Tore.Heim - Bundesliga$Tore.Gast
Bundesliga$Y3 = as.ordered(ifelse(diff >= 1, 1, ifelse(diff <= -1, 3, 2)))
buli0506 = subset(Bundesliga, Saison=="2005/2006")
str(buli0506)
## 'data.frame': 306 obs. of 11 variables:
## $ Saison : Factor w/ 44 levels "1963/1964","1964/1965",..: 43 43 43 43 43 43 43 43 43 43 ...
## $ Spieltag : int 1 1 1 1 1 1 1 1 1 2 ...
## $ Datum : Date, format: "2005-08-05" "2005-08-06" ...
## $ Anpfiff : Factor w/ 31 levels "14:00","14:15",..: 28 6 6 6 6 6 6 15 15 6 ...
## $ Heim : Factor w/ 50 levels "1. FC Kaiserslautern",..: 18 2 31 24 49 40 25 20 16 8 ...
## $ Gast : Factor w/ 50 levels "1. FC Kaiserslautern",..: 11 5 47 3 10 7 27 1 8 18 ...
## $ Tore.Heim : int 3 1 1 3 2 5 2 2 1 2 ...
## $ Tore.Gast : int 0 0 1 0 2 2 2 1 4 5 ...
## $ Tore.Heim.Halbzeit: int 1 0 1 2 1 3 0 0 1 1 ...
## $ Tore.Gast.Halbzeit: int 0 0 1 0 0 2 0 1 1 3 ...
## $ Y3 : Ord.factor w/ 3 levels "1"<"2"<"3": 1 1 2 1 2 1 2 1 3 3 ...
As the bradley-terry model is just a logit model (binary target), we can
extend this for multiclass target using, e.g., a cummulative logit
model. The ordBTL
function does exactly this and uses internally the
VGAM
package.
# Create design matrix for ordinal Bradley-Terry model
des.nohome = design(buli0506, var1="Heim", var2="Gast",
use.vars="Y3", home.advantage="no", reference="GAMMA.MSV.Duisburg")
# first game is bayern vs. moenchengladbach
buli0506[1,]
## Saison Spieltag Datum Anpfiff Heim
## 12795 2005/2006 1 2005-08-05 20:30 FC Bayern Muenchen
## Gast Tore.Heim Tore.Gast Tore.Heim.Halbzeit
## 12795 Borussia Moenchengladbach 3 0 1
## Tore.Gast.Halbzeit Y3
## 12795 0 1
# the design-matrix for the ordinal BTL model looks like this
des.nohome[1,]
## GAMMA.1.FC.Kaiserslautern GAMMA.1.FC.Koeln GAMMA.1.FC.Nuernberg
## 12795 0 0 0
## GAMMA.1.FSV.Mainz.05 GAMMA.Arminia.Bielefeld GAMMA.Bayer.Leverkusen
## 12795 0 0 0
## GAMMA.Borussia.Dortmund GAMMA.Borussia.Moenchengladbach
## 12795 0 -1
## GAMMA.Eintracht.Frankfurt GAMMA.FC.Bayern.Muenchen GAMMA.FC.Schalke.04
## 12795 0 1 0
## GAMMA.Hamburger.SV GAMMA.Hannover.96 GAMMA.Hertha.BSC.Berlin
## 12795 0 0 0
## GAMMA.SV.Werder.Bremen GAMMA.VfB.Stuttgart GAMMA.VfL.Wolfsburg Y3
## 12795 0 0 0 1
mod.nohome = ordBTL(Y3~., data=des.nohome)
# team 'abilities' (should be approximately the ranking of the final standings)
getRank(mod.nohome, prefix="GAMMA", reference="GAMMA.MSV.Duisburg")
## Estimate Std. Error z value Pr(>|z|)
## GAMMA.FC.Bayern.Muenchen 2.15183470 0.4894014 4.3968712 1.098225e-05
## GAMMA.SV.Werder.Bremen 1.97066756 0.4805982 4.1004475 4.123520e-05
## GAMMA.Hamburger.SV 1.85128996 0.4755611 3.8928539 9.907181e-05
## GAMMA.FC.Schalke.04 1.53694777 0.4650047 3.3052306 9.489829e-04
## GAMMA.Bayer.Leverkusen 1.11218303 0.4562407 2.4377114 1.478057e-02
## GAMMA.Hertha.BSC.Berlin 0.96890640 0.4545961 2.1313565 3.305978e-02
## GAMMA.Borussia.Dortmund 0.88674951 0.4539380 1.9534594 5.076519e-02
## GAMMA.VfB.Stuttgart 0.84283463 0.4536699 1.8578147 6.319534e-02
## GAMMA.Borussia.Moenchengladbach 0.73609299 0.4532612 1.6239928 1.043773e-01
## GAMMA.1.FC.Nuernberg 0.69608421 0.4531961 1.5359449 1.245519e-01
## GAMMA.Hannover.96 0.67862317 0.4531825 1.4974611 1.342733e-01
## GAMMA.1.FSV.Mainz.05 0.46470092 0.4537577 1.0241170 3.057800e-01
## GAMMA.VfL.Wolfsburg 0.37696046 0.4543918 0.8295935 4.067687e-01
## GAMMA.Eintracht.Frankfurt 0.33368265 0.4547928 0.7337027 4.631300e-01
## GAMMA.Arminia.Bielefeld 0.29518165 0.4551965 0.6484708 5.166805e-01
## GAMMA.1.FC.Kaiserslautern 0.17249245 0.4567996 0.3776108 7.057198e-01
## GAMMA.1.FC.Koeln 0.06391278 0.4586289 0.1393562 8.891687e-01
## GAMMA.MSV.Duisburg 0.00000000 NA NA 0.000000e+00
# for more examples see ?ordBTL