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
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
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.timeis 5000 only when
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?