Given a series of past horse races results, and the attributes of each horse which participate in a race, I would like to how to fit the data model to something like glm() in R so as to predict the probability of a horse winning a race. Obviously, in a race, there will be only one winning horse and all the remaining horses are losers. I wonder if I need a hierarchical model using lmer() to fit the properties of the race conditions such as distances, as well as the attributes of a horse participating in the race, such as age, weight-carrying and etc. Any suggestions?

  • 2
    $\begingroup$ Why don't try to predict how much time each horse is going to take to complete the race instead of which is going to win? This way you ignore the horses interactions during the race but maybe it's enough to get you started. $\endgroup$ – João Almeida Apr 13 '16 at 10:12
  • $\begingroup$ I think it is a good suggestion, but I choose to predict the winning probability as my past experience is that there is indeed interactions between the horses, and there might be slow-pacing and fast-pacing races which might affect the finishing time. $\endgroup$ – nikademus Apr 14 '16 at 2:35
  • $\begingroup$ That is going to be very very hard to model, statistically. You'd need a database of races with the types of horses and their styles and then you'd need to try to find some way of rating those. $\endgroup$ – Peter Flom - Reinstate Monica Apr 14 '16 at 10:53

I think you need a two step process. First, estimate the speed of each horse and have distance as one of the factors in the model.

You can then use a multilevel model (hence lmer) with repeated measures on the horses.

Then you have a set of projected speeds for each race (one for each horse). These projected speeds can be used in step 2 to model the probabilities of winning the race. Each speed will have estimated errors, so you could use those.


I have implemented a piece of code which provides me with coefficients later plugged into the logistic equation to create theoretical odds. It is inspired from Developing Statistical Models Of Horse Racing Outcomes Using R written by Dr Alun Owen from the SmartSigger uk magazine starting January 2014

Below the R code :


horse.data$deferre<-as.factor(horse.data$deferre) ‘  

unshoed harness horse ………………………………..


which provides :

Frequencies of alternatives:
         1          2          3          4          5          6          7          8          9         10 
0.05183612 0.06257807 0.06557582 0.06832376 0.07556832 0.07669248 0.07406945 0.07819136 0.07007245 0.06907320 
        11         12         13         14         15         16         17         18         19         20 
0.06657507 0.06107919 0.05296028 0.04871346 0.03235074 0.02810392 0.00924307 0.00811891 0.00037472 0.00049963 
nr method
5 iterations, 0h:1m:7s     g'(-H)^-1g = 6.38E-07       gradient close to zero 

Coefficients :
                   Estimate  Std. Error  t-value  Pr(>|t|)    
sexe2           -4.0103e-01  4.4405e-02  -9.0312 < 2.2e-16 ***
sexe3           -1.4602e-01  3.7419e-02  -3.9021 9.535e-05 ***
age             -2.7558e-01  2.7615e-02  -9.9794 < 2.2e-16 ***
nbVic            4.6575e-02  6.3964e-03   7.2814 3.304e-13 ***
nbPlac          -2.0636e-02  4.8074e-03  -4.2926 1.766e-05 
pcVict           7.3494e-01  1.1072e-01   6.6377 3.185e-11 *
deferre1         3.9375e-01  1.1473e-01   3.4320 0.0005991 ***
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Log-Likelihood: -17661

Then, using the most significant coefficients, I plug them with the following vba code (excerpt):

Private Sub ComputeCteThForOneRace(ByVal idebCourse As Long, ByVal ifinCourse As Long)
    Dim wfd As Worksheet
    Dim icol, irow, i, j, k, m, n, t, v
    Dim Vtemp, tmp1, nbEmptyLines, musique
    Dim curParam As String
    Dim totExpV, ExpV
    Set wfd = Worksheets("Fdata")
    For i = idebCourse To ifinCourse
          v = 0
          If wfd.Cells(i, iChevMusique) <> "Inédit" Then ‘ has never raced
             For j = iChevSexe To ioDiffAlloc
              ‘ Vtemp is assigned with significant coefficient values found earlier  
Vtemp = 0
                 curParam = wfd.Cells(i, j)  ‘ current parameter
                 Select Case j
                     Case iChevSexe
                         Select Case curParam
                             Case "F"
                                 Vtemp = -0.40105
                             Case "H"
                                 Vtemp = -0.14503
                             Case Else
                         End Select
                     Case iChevAge
                          If IsNumeric(curParam) Then
                                 Vtemp = -0.27329 * curParam
                          End If
                     Case iChevNbVict
                          If IsNumeric(curParam) Then
                                 Vtemp = 0.04659 * curParam
                          End If
                       Case Else
                         End Select
                 End Select
                 wfd.Cells(i, iV) = Vtemp  
                 v = v + Vtemp  ‘ logistic equation is built 

             wfd.Cells(i, iV) = v
             wfd.Cells(i, iexpV) = Exp(v)
             totExpV = totExpV + Exp(v)
          Else  ' Inédit (new horse)
             wfd.Cells(i, iexpV) = 0.1
          End If
    For i = idebCourse To ifinCourse
         wfd.Cells(i, iexpV + 1) = wfd.Cells(i, iexpV) / totExpV
         wfd.Cells(i, iCteTh) = 1 + (1 - wfd.Cells(i, iexpV + 1)) / wfd.Cells(i, iexpV + 1)
         If wfd.Cells(i, iCteTh) > 900 Then wfd.Cells(i, iCteTh) = 900
    For i = idebCourse To ifinCourse  ' ranking cteTh
wfd.Cells(i, ioCteTh) = Application.WorksheetFunction.Rank(wfd.Cells(i, iCteTh),   wfd.Range(wfd.Cells(idebCourse, iCteTh), wfd.Cells(ifinCourse, iCteTh)), 1)

Finally, the wfd.Cells(i, iCteTh) and wfd.Cells(i, ioCteTh) columns contain the Theoretical odds and their rank At the last minute, the wfd.Cells(i, iCteLive) column is filled with the odds (done by a program) before the race starts. Only horses whose wfd.Cells(i, iCteLive) / wfd.Cells(i, iCteTh) ratio is at least >1 are considered for a bet.

  • $\begingroup$ thanks for your effort! indeed after searching days for relevant papers i have reached a conclusion to use clogit in the survival package for doing simliar things $\endgroup$ – nikademus Aug 30 '17 at 2:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.