I'm building a model (random forest) in R to predict a rare event (scoring a goal in soccer). I have event-level data, which provides a log of all the actions (pass, tackle, foul, save, shot, goal) that takes place in each match, and their locations on the pitch. I am filtering this data for shots, and using them to build the model. I want to predict which shots are likely to end as a goal. I'm also interested in the probability that my model will assign to each shot.

To predict this, I'm using a variable called tb.flag, which indicates whether an action called 'throughball' took place in the sequence before a shot was taken. It has either TRUE or FALSE. I believe shots which are taken after throughball happens, are more likely to end as a goal. Whenever throughball happens before a shot, I calculated the seconds between the throughball and the shot (called it tb.to.shot.time) and include this variable in the model too. I believe that shots which are taken straight away after a throughball are more likely to end as a goal than shots which take place a few seconds after a throughball.

My problem is, tb.to.shot.time is a numerical column that will have NAs, every time a shot was taken without the action called throughball happening before it, i.e., wherever tb.flag is FALSE. But the package I am using to build the model (caret), does not accept NA values in the training data provided to it.

I have experience in imputing missing values, but this is a peculiar scenario I have not come across before. tb.to.shot.time should be NA if a throughball event did not take place. But I cannot leave it as NA. How do I impute values without dangerously misleading the model? Ideally, I would not model or impute the NAs, as the the presence of an absence is actually informative. A few scenarios I considered are:

  • Impute 0. This does not make sense, as I believe shots which are taken straight away after a throughball are more likely to end as a goal. 0 and values close to 0 mean something in this context.

  • Impute an arbitrary high constant value, like 5000. tb.to.shot.time, when valid, has a range of 1.83 seconds to 22.94 seconds, so it will never be as high as 5000. I can hope that the model will figure out that tb.to.shot.time is 5000 only when tb.flag is FALSE, and does not provide any useful information in that case.

This is how my data looks:

structure(list(id = c("39a36403-5d15-4b45-bda6-41e1b60a0fae", 
"743f3a0b-4e1e-4618-af18-4b60018df7a3", "352c1fec-8c92-4beb-ab47-3108d5a48319", 
"44a91256-b691-4011-864f-9d00d46096a5", "2a8e9f4f-21c0-4438-8a6c-57b592003f5a", 
"47dd1972-c989-4f7a-82e4-6e25eb5e873c"), tb.flag = c(FALSE, FALSE, 
FALSE, FALSE, TRUE, FALSE), tb.to.shot.time = c(NA_real_, NA_real_, 
NA_real_, NA_real_, 3.51, NA_real_), is.goal = c("NoGoal", 
"NoGoal", "NoGoal", "NoGoal", "NoGoal", "Goal")), row.names = c(NA, 
-6L), class = c("tbl_df", "tbl", "data.frame"))

Is there a way to make a random forest treat a NA value as a valid one in R? If not, what is the accepted ways to address this problem?

  • 1
    $\begingroup$ It seems to me that if you chose scenario 2 - which is what we do where I work - you would be able to drop tb.flag, as a split on tb.to.shot.time > 1000 would be equivalent to a split on tb.flag = TRUE (or FALSE), so you don't need both. That, too, is how we handle those situations, not to say that's the best way, though. $\endgroup$ – jbowman Apr 16 at 2:37
  • $\begingroup$ Dropping tb.flag makes sense, as all the information I need is present in tb.to.shot.time. Have you encountered any misinterpretations or unexpected outcomes due to this practice? $\endgroup$ – sgk Apr 16 at 18:26
  • $\begingroup$ Well, it's not entirely clear to us whether the dummy value should be at the "end" of the variable which we would expect to have values closest to what happens when there's an NA or the other "end". In the latter case, it's easier for an RF or GBM to split off just the NA values, but in the former case, it's easier to split off "NA or no effect" values into their own branch of the tree. Probably situational, as with many things. $\endgroup$ – jbowman Apr 16 at 18:36

Your Answer

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

Browse other questions tagged or ask your own question.