# Load necessary libraries
library(dplyr)
library(data.table)
library(knitr)
# To input model predicted spreads
predict_ncaa_round <- function(round){
# Subset data by round
if(round == 0){rows <- c(1:4)}
if(round == 1){rows <- c(5:36)}
if(round == 2){rows <- c(37:52)}
if(round == 3){rows <- c(53:60)}
if(round == 4){rows <- c(61:64)}
if(round == 5){rows <- c(65:66)}
if(round == 6){rows <- 67}
# Append model predicted spread for higher seeds
bracket <- bracket[rows,] %>%
left_join(select(PredictionData, TeamName.x, TeamName.y, Prediction, Win_Prob), by = c('TeamName.x' = 'TeamName.x', 'TeamName.y'= 'TeamName.y'))
# Get the rows of lesser seeds
na_rows <- which(is.na(bracket$Prediction))
# Impute prediction data from lesser seeds
for (i in na_rows) {
bracket[i, 7] <- -PredictionData[which(bracket[i, 5] == PredictionData$TeamName.y & bracket[i,6] == PredictionData$TeamName.x), 9]
bracket[i, 8] <- 1 - PredictionData[which(bracket[i, 5] == PredictionData$TeamName.y & bracket[i,6] == PredictionData$TeamName.x), 10]
}
bracket
}
# To determine who model would bet on
ATSchoice <- function(bracket){
bracket$ModelChoice <- NA
for (i in c(1:length(bracket$Diff))){
if(bracket$Diff[i] < -2)
{bracket$ModelChoice[i] <- bracket$TeamName.y[i]}
if(bracket$Diff[i] > 2)
{bracket$ModelChoice[i] <- bracket$TeamName.x[i]}
if(bracket$Diff[i] <= 2 & bracket$Diff[i] >= -2)
{bracket$ModelChoice[i] <- "No choice"}
}
bracket
}
ATSresults <- function(bracket){
# Determine ATS winner
bracket$ATSWinner <- NA
for (i in c(1:length(bracket$Diff))){
FinalDiff <- bracket$Team.x.score[i] - bracket$Team.y.score[i]
if(!is.na(FinalDiff)) {
if(FinalDiff < bracket$Spread[i])
{bracket$ATSWinner[i] <- bracket$TeamName.y[i]}
if(FinalDiff > bracket$Spread[i])
{bracket$ATSWinner[i] <- bracket$TeamName.x[i]}
if(FinalDiff == bracket$Spread[i])
{bracket$ATSWinner[i] <- "Push"}
}
}
# Determine if Model Prediction was Correct, Incorrect, or Not Made
bracket$Accuracy <- NA
for (i in c(1:length(bracket$Diff))){
if(!is.na(bracket$ATSWinner[i])) {
if(bracket$ModelChoice[i] == bracket$ATSWinner[i])
{bracket$Accuracy[i] <- "Correct"}
if(bracket$ModelChoice[i] != bracket$ATSWinner[i])
{bracket$Accuracy[i] <- "Incorrect"}
if(bracket$ATSWinner[i] == "Push")
{bracket$Accuracy[i] <- "Push"}
}
if(is.na(bracket$ATSWinner[i]))
{bracket$Accuracy[i] <- NA}
if(bracket$ModelChoice[i] == "No choice")
{bracket$Accuracy[i] <- NA}
}
bracket
}
# Function to advance winners from "x" final bracket into "bracket" object
advance_winners <- function(x){
for (i in c(1:length(x$Slot))){
slot <- x$Slot[i]
if(x$Team.x.score[i] > x$Team.y.score[i]) {
winner <- x$TeamName.x[i]
} else{
winner <- x$TeamName.y[i]
}
rownum <- which(bracket[,c(3:4)] == slot, arr.ind = TRUE)[1]
colnum <- which(bracket[,c(3:4)] == slot, arr.ind = TRUE)[2]
if(colnum == 1)
{bracket$TeamName.x[rownum] <- winner}
else
{bracket$TeamName.y[rownum] <- winner}
}
bracket
}
The prediction model is a XGBoost model with 5-fold cross validation. The cleaning and preparation of the data and the training and testing of that model are in a script which can be found here [insert link here]. The prediction data for all possible pairs of opponents are in the file “saferesults.Rds”.
# Load prediction data from model
PredictionData <- readRDS("saferesults.Rds")
#kable(head(PredictionData))
# Load the 2018 bracket data and team names
tourneyslots <- fread("NCAATourneySlots.csv") %>% filter(Season == 2018)
tourneySeeds <- fread('NCAATourneySeeds.csv') %>% filter(Season == 2018)
teams <- fread('teams.csv')
# Attach team names to seed info
tourneySeeds <- tourneySeeds %>%
left_join(teams, by = 'TeamID') %>%
select(Season, Seed, TeamID, TeamName)
# Manually set the play-in winners
tourneyslots[5,4] <- "W16b"
tourneyslots[10,4] <- "W11a"
tourneyslots[18, 4] <- "X11b"
tourneyslots[29, 4] <- "Z16b"
# Complete Bracket
bracket <- tourneyslots %>%
left_join(select(tourneySeeds, -c(Season, TeamID)), by=c('StrongSeed'='Seed')) %>%
left_join(select(tourneySeeds, -c(Season, TeamID)), by=c('WeakSeed'='Seed'))
# Append model predicted spreads
playin <- predict_ncaa_round(round = 0)
# All Play-in Spreads are retroactive
# Spreads are positive if strong seed is favored, negative if underdogs
playinspreads <- data.frame(
matrix(
c(
"St Bonaventure", -3.5,
"Long Island", -4.5,
"Arizona St", 1,
"NC Central", -4.5),
ncol = 2, byrow = TRUE), stringsAsFactors = FALSE
)
names(playinspreads) <- c("Team", "Spread")
playinspreads$Spread <- as.numeric(playinspreads$Spread)
# Append spreads on to bracket
playin <- playin %>%
left_join(playinspreads, by = c('TeamName.x' = 'Team')) %>%
mutate(Diff = Prediction - Spread)
A team needs to have a predicted spread more than 2 points beyond the sportsbook spread in order to have greater than a 55% chance of winning ATS (against the spread), which is the minimum winning percent needed to break even. In the ModelChoice variable, the model will return “No Choice” if the model prediction is within 2 points of the sportsbook spread or otherwise return which team the model predicts has a > 55% chance to cover the spread.
# Determine who model would bet on ATS
playin <- ATSchoice(playin)
Note: The Prediction variable outputs how many points the StrongSeed is expected to beat the WeakSeed by. So Prediction will be 3 if the StrongSeed team is favored by 3 points. This is the opposite of conventional wagering notation (-3). The Spread variable is not the conventional spread, but gives how many points the StrongSeed team is favored over the WeakSeed team by. The Win_Prob variable is the probability of the StrongSeed team winning the game straight up.
#### Output of Model Predictions ATS
playinpredictionstable <- playin[1:4,] %>% select(StrongSeed, TeamName.x, WeakSeed, TeamName.y, Spread, Prediction, ModelChoice, Diff)
kable(playinpredictionstable)
StrongSeed | TeamName.x | WeakSeed | TeamName.y | Spread | Prediction | ModelChoice | Diff |
---|---|---|---|---|---|---|---|
W11a | St Bonaventure | W11b | UCLA | -3.5 | 2.6 | St Bonaventure | 6.1 |
W16a | Long Island | W16b | Radford | -4.5 | 0.9 | Long Island | 5.4 |
X11a | Arizona St | X11b | Syracuse | 1.0 | 1.3 | No choice | 0.3 |
Z16a | NC Central | Z16b | TX Southern | -4.5 | 9.3 | NC Central | 13.8 |
# Input Game Results Manually
# Eventually I need to scrape this data from web
playinresults <- data.frame(
matrix(
c(
"St Bonaventure", 65, 58,
"Long Island", 61, 71,
"Arizona St", 56, 60,
"NC Central", 46, 64), ncol = 3, byrow = TRUE), stringsAsFactors = FALSE)
names(playinresults) <- c("Team", "Team.x.score", "Team.y.score")
playinresults$Team.x.score <- as.numeric(playinresults$Team.x.score)
playinresults$Team.y.score <- as.numeric(playinresults$Team.y.score)
# Append Game Results to Bracket
playin <- playin %>%
left_join(playinresults, by = c('TeamName.x' = 'Team'))
# Determine Model Accuracy
playin <- ATSresults(playin)
# Table of all outcomes
output_table_0 <- playin[1:4,] %>%
filter(!is.na(TeamName.x)) %>%
select(StrongSeed, TeamName.x, WeakSeed, TeamName.y, Spread, Prediction, ModelChoice, Team.x.score, Team.y.score, ATSWinner, Accuracy)
kable(output_table_0)
StrongSeed | TeamName.x | WeakSeed | TeamName.y | Spread | Prediction | ModelChoice | Team.x.score | Team.y.score | ATSWinner | Accuracy |
---|---|---|---|---|---|---|---|---|---|---|
W11a | St Bonaventure | W11b | UCLA | -3.5 | 2.6 | St Bonaventure | 65 | 58 | St Bonaventure | Correct |
W16a | Long Island | W16b | Radford | -4.5 | 0.9 | Long Island | 61 | 71 | Radford | Incorrect |
X11a | Arizona St | X11b | Syracuse | 1.0 | 1.3 | No choice | 56 | 60 | Syracuse | NA |
Z16a | NC Central | Z16b | TX Southern | -4.5 | 9.3 | NC Central | 46 | 64 | TX Southern | Incorrect |
# Summary of results
table(output_table_0$Accuracy)
##
## Correct Incorrect
## 1 2
The model’s record was 1-2 ATS for the play-in games.
# Append model predicted spreads
round1 <- predict_ncaa_round(1)
# All Round 1 Spreads as of 12:30pm Thursday
# Spreads are positive if strong seed is favored, negative if underdogs
round1spreads <- data.frame(
matrix(
c(
"Rhode Island", 1.5,
"Tennessee", 11.5,
"Gonzaga", 13.5,
"Kansas", 14.5,
"Duke", 20,
"Miami FL", 2,
"Ohio St", 8,
"Seton Hall", 3,
"Villanova", 23,
"Kentucky", 5,
"Houston", 4,
"Texas Tech", 11,
"Virginia Tech", 2.5,
"Arizona", 8.5,
"Michigan", 10,
"Florida", 5.5,
"Texas A&M", 2.5,
"Purdue", 20.5,
"Wichita St", 11.5,
"Cincinnati", 14,
"North Carolina", 19.5,
"Arkansas", -1.5,
"West Virginia", 10.5,
"Nevada", 0,
"Creighton", 1,
"Michigan St", 14.5,
"Xavier", 19.5,
"Auburn", 9,
"Virginia", 21,
"TCU", 4,
"Missouri", -1.5,
"Clemson", 4.5),
ncol = 2, byrow = TRUE), stringsAsFactors = FALSE
)
names(round1spreads) <- c("Team", "Spread")
round1spreads$Spread <- as.numeric(round1spreads$Spread)
# Append spreads on to bracket
round1 <- round1 %>%
left_join(round1spreads, by = c('TeamName.x' = 'Team')) %>%
mutate(Diff = Prediction - Spread)
A team needs to have a predicted spread more than 2 points beyond the sportsbook spread in order to have greater than a 55% chance of winning ATS (against the spread), which is the minimum winning percent needed to break even. In the ModelChoice variable, the model will return “No Choice” if the model prediction is within 2 points of the sportsbook spread or otherwise return which team the model predicts has a > 55% chance to cover the spread.
# Determine who model would bet on ATS
round1 <- ATSchoice(round1)
There is something wrong with my predictions for the top seeds, especially 1s and 2s, so I stayed away from following my model on any of those. Other kagglers have had this same issue and have manually input values for them, some trouble I didn’t want to bother with until I had the rest of the model running well. I’ll focus on that at some point in the future. For now, I’m going to manually input “No Choice” for all 1 and 2 seeds of Villanova, Kansas, Duke, Purdue, Cincinnati, Xavier, UNC, and Virginia.
# Manually set 1 and 2 seeds to no choice
round1$ModelChoice[c(1,2,9,10,17,18,25,26)] <- "No choice"
# Output of Model Predictions ATS
round1predictionstable <- round1 %>% select(StrongSeed, TeamName.x, WeakSeed, TeamName.y, Spread, Prediction, ModelChoice, Diff)
kable(round1predictionstable)
StrongSeed | TeamName.x | WeakSeed | TeamName.y | Spread | Prediction | ModelChoice | Diff |
---|---|---|---|---|---|---|---|
W01 | Villanova | W16b | Radford | 23.0 | 9.5 | No choice | -13.5 |
W02 | Purdue | W15 | CS Fullerton | 20.5 | 13.4 | No choice | -7.1 |
W03 | Texas Tech | W14 | SF Austin | 11.0 | 11.4 | No choice | 0.4 |
W04 | Wichita St | W13 | Marshall | 11.5 | 4.3 | Marshall | -7.2 |
W05 | West Virginia | W12 | Murray St | 10.5 | 1.1 | Murray St | -9.4 |
W06 | Florida | W11a | St Bonaventure | 5.5 | 8.0 | Florida | 2.5 |
W07 | Arkansas | W10 | Butler | -1.5 | -1.4 | No choice | 0.1 |
W08 | Virginia Tech | W09 | Alabama | 2.5 | 9.2 | Virginia Tech | 6.7 |
X01 | Kansas | X16 | Penn | 14.5 | 6.8 | No choice | -7.7 |
X02 | Duke | X15 | Iona | 20.0 | 15.0 | No choice | -5.0 |
X03 | Michigan St | X14 | Bucknell | 14.5 | 7.8 | Bucknell | -6.7 |
X04 | Auburn | X13 | Col Charleston | 9.0 | -0.1 | Col Charleston | -9.1 |
X05 | Clemson | X12 | New Mexico St | 4.5 | -0.3 | New Mexico St | -4.8 |
X06 | TCU | X11b | Syracuse | 4.0 | 1.0 | Syracuse | -3.0 |
X07 | Rhode Island | X10 | Oklahoma | 1.5 | 4.7 | Rhode Island | 3.2 |
X08 | Seton Hall | X09 | NC State | 3.0 | 1.1 | No choice | -1.9 |
Y01 | Virginia | Y16 | UMBC | 21.0 | 3.5 | No choice | -17.5 |
Y02 | Cincinnati | Y15 | Georgia St | 14.0 | 7.1 | No choice | -6.9 |
Y03 | Tennessee | Y14 | Wright St | 11.5 | 5.4 | Wright St | -6.1 |
Y04 | Arizona | Y13 | Buffalo | 8.5 | -7.1 | Buffalo | -15.6 |
Y05 | Kentucky | Y12 | Davidson | 5.0 | 1.7 | Davidson | -3.3 |
Y06 | Miami FL | Y11 | Loyola-Chicago | 2.0 | 6.7 | Miami FL | 4.7 |
Y07 | Nevada | Y10 | Texas | 0.0 | 6.2 | Nevada | 6.2 |
Y08 | Creighton | Y09 | Kansas St | 1.0 | -1.1 | Kansas St | -2.1 |
Z01 | Xavier | Z16b | TX Southern | 19.5 | 15.6 | No choice | -3.9 |
Z02 | North Carolina | Z15 | Lipscomb | 19.5 | 13.1 | No choice | -6.4 |
Z03 | Michigan | Z14 | Montana | 10.0 | 5.2 | Montana | -4.8 |
Z04 | Gonzaga | Z13 | UNC Greensboro | 13.5 | 7.8 | UNC Greensboro | -5.7 |
Z05 | Ohio St | Z12 | S Dakota St | 8.0 | 8.9 | No choice | 0.9 |
Z06 | Houston | Z11 | San Diego St | 4.0 | 5.1 | No choice | 1.1 |
Z07 | Texas A&M | Z10 | Providence | 2.5 | 2.3 | No choice | -0.2 |
Z08 | Missouri | Z09 | Florida St | -1.5 | -11.0 | Florida St | -9.5 |
The model recommendations for round 1 are:
# Input Game Results Manually
# Eventually I need to scrape this data from web
round1results <- data.frame(
matrix(
c(
"St Bonaventure", 65, 58,
"Long Island", 61, 71,
"Arizona St", 56, 60,
"NC Central", 46, 64,
"Rhode Island", 83, 78,
"Tennessee", 73, 47,
"Gonzaga", 68, 64,
"Kansas", 76, 60,
"Duke", 89, 67,
"Miami FL", 62, 64,
"Ohio St", 81, 73,
"Seton Hall", 94, 83,
"Villanova", 87, 61,
"Kentucky", 78, 73,
"Houston", 67, 65,
"Texas Tech", 70, 60,
"Virginia Tech", 83, 86,
"Arizona", 68, 89,
"Michigan", 61, 47,
"Florida", 77, 62,
"Texas A&M", 73, 69,
"Purdue", 74, 48,
"Wichita St", 75, 81,
"Cincinnati", 68, 53,
"North Carolina", 84, 66,
"Arkansas", 62, 79,
"West Virginia", 85, 68,
"Nevada", 87, 83,
"Creighton", 59, 69,
"Michigan St", 82, 78,
"Xavier", 91, 72,
"Auburn", 62, 58,
"Virginia", 54, 74,
"TCU", 52, 57,
"Missouri", 54, 67,
"Clemson", 79, 68), ncol = 3, byrow = TRUE), stringsAsFactors = FALSE)
names(round1results) <- c("Team", "Team.x.score", "Team.y.score")
round1results$Team.x.score <- as.numeric(round1results$Team.x.score)
round1results$Team.y.score <- as.numeric(round1results$Team.y.score)
# Append Game Results to Bracket
round1 <- round1 %>%
left_join(round1results, by = c('TeamName.x' = 'Team'))
# Determine Model's Accuracy ATS
round1 <- ATSresults(round1)
Note: The Prediction variable outputs how many points the StrongSeed is expected to beat the WeakSeed by. So Prediction will be 3 if the StrongSeed team is favored by 3 points. This is the opposite of conventional wagering notation (-3). The Spread variable is not the conventional spread, but gives how many points the StrongSeed team is favored over the WeakSeed team by. The Win_Prob variable is the probability of the StrongSeed team winning the game straight up.
# TABLE OF ALL RESULTS
output_table_1 <- round1 %>%
filter(!is.na(TeamName.x)) %>%
select(StrongSeed, TeamName.x, WeakSeed, TeamName.y, Spread, Prediction, ModelChoice, Team.x.score, Team.y.score, ATSWinner, Accuracy)
output_table_1 <- rbind(output_table_0, output_table_1)
kable(output_table_1)
StrongSeed | TeamName.x | WeakSeed | TeamName.y | Spread | Prediction | ModelChoice | Team.x.score | Team.y.score | ATSWinner | Accuracy |
---|---|---|---|---|---|---|---|---|---|---|
W11a | St Bonaventure | W11b | UCLA | -3.5 | 2.6 | St Bonaventure | 65 | 58 | St Bonaventure | Correct |
W16a | Long Island | W16b | Radford | -4.5 | 0.9 | Long Island | 61 | 71 | Radford | Incorrect |
X11a | Arizona St | X11b | Syracuse | 1.0 | 1.3 | No choice | 56 | 60 | Syracuse | NA |
Z16a | NC Central | Z16b | TX Southern | -4.5 | 9.3 | NC Central | 46 | 64 | TX Southern | Incorrect |
W01 | Villanova | W16b | Radford | 23.0 | 9.5 | No choice | 87 | 61 | Villanova | NA |
W02 | Purdue | W15 | CS Fullerton | 20.5 | 13.4 | No choice | 74 | 48 | Purdue | NA |
W03 | Texas Tech | W14 | SF Austin | 11.0 | 11.4 | No choice | 70 | 60 | SF Austin | NA |
W04 | Wichita St | W13 | Marshall | 11.5 | 4.3 | Marshall | 75 | 81 | Marshall | Correct |
W05 | West Virginia | W12 | Murray St | 10.5 | 1.1 | Murray St | 85 | 68 | West Virginia | Incorrect |
W06 | Florida | W11a | St Bonaventure | 5.5 | 8.0 | Florida | 77 | 62 | Florida | Correct |
W07 | Arkansas | W10 | Butler | -1.5 | -1.4 | No choice | 62 | 79 | Butler | NA |
W08 | Virginia Tech | W09 | Alabama | 2.5 | 9.2 | Virginia Tech | 83 | 86 | Alabama | Incorrect |
X01 | Kansas | X16 | Penn | 14.5 | 6.8 | No choice | 76 | 60 | Kansas | NA |
X02 | Duke | X15 | Iona | 20.0 | 15.0 | No choice | 89 | 67 | Duke | NA |
X03 | Michigan St | X14 | Bucknell | 14.5 | 7.8 | Bucknell | 82 | 78 | Bucknell | Correct |
X04 | Auburn | X13 | Col Charleston | 9.0 | -0.1 | Col Charleston | 62 | 58 | Col Charleston | Correct |
X05 | Clemson | X12 | New Mexico St | 4.5 | -0.3 | New Mexico St | 79 | 68 | Clemson | Incorrect |
X06 | TCU | X11b | Syracuse | 4.0 | 1.0 | Syracuse | 52 | 57 | Syracuse | Correct |
X07 | Rhode Island | X10 | Oklahoma | 1.5 | 4.7 | Rhode Island | 83 | 78 | Rhode Island | Correct |
X08 | Seton Hall | X09 | NC State | 3.0 | 1.1 | No choice | 94 | 83 | Seton Hall | NA |
Y01 | Virginia | Y16 | UMBC | 21.0 | 3.5 | No choice | 54 | 74 | UMBC | NA |
Y02 | Cincinnati | Y15 | Georgia St | 14.0 | 7.1 | No choice | 68 | 53 | Cincinnati | NA |
Y03 | Tennessee | Y14 | Wright St | 11.5 | 5.4 | Wright St | 73 | 47 | Tennessee | Incorrect |
Y04 | Arizona | Y13 | Buffalo | 8.5 | -7.1 | Buffalo | 68 | 89 | Buffalo | Correct |
Y05 | Kentucky | Y12 | Davidson | 5.0 | 1.7 | Davidson | 78 | 73 | Push | Push |
Y06 | Miami FL | Y11 | Loyola-Chicago | 2.0 | 6.7 | Miami FL | 62 | 64 | Loyola-Chicago | Incorrect |
Y07 | Nevada | Y10 | Texas | 0.0 | 6.2 | Nevada | 87 | 83 | Nevada | Correct |
Y08 | Creighton | Y09 | Kansas St | 1.0 | -1.1 | Kansas St | 59 | 69 | Kansas St | Correct |
Z01 | Xavier | Z16b | TX Southern | 19.5 | 15.6 | No choice | 91 | 72 | TX Southern | NA |
Z02 | North Carolina | Z15 | Lipscomb | 19.5 | 13.1 | No choice | 84 | 66 | Lipscomb | NA |
Z03 | Michigan | Z14 | Montana | 10.0 | 5.2 | Montana | 61 | 47 | Michigan | Incorrect |
Z04 | Gonzaga | Z13 | UNC Greensboro | 13.5 | 7.8 | UNC Greensboro | 68 | 64 | UNC Greensboro | Correct |
Z05 | Ohio St | Z12 | S Dakota St | 8.0 | 8.9 | No choice | 81 | 73 | Push | NA |
Z06 | Houston | Z11 | San Diego St | 4.0 | 5.1 | No choice | 67 | 65 | San Diego St | NA |
Z07 | Texas A&M | Z10 | Providence | 2.5 | 2.3 | No choice | 73 | 69 | Texas A&M | NA |
Z08 | Missouri | Z09 | Florida St | -1.5 | -11.0 | Florida St | 54 | 67 | Florida St | Correct |
# Summary of results
table(output_table_1$Accuracy)
##
## Correct Incorrect Push
## 12 8 1
The model’s record was 11-6-1 ATS in round 1 action and is 12-8-1 ATS over the entire tournament. The model would have been 3-5 in the 1 and 2 seeded games.
One last interesting note is that a lot of 1 seeds seemed to not cover the first half spread. I heard this has some historical traction to it. Something to keep in mind next year.
# Recording Round 1 Winners into Round 2
bracket <- advance_winners(round1)
# Model Predictions for Round 2
round2 <- predict_ncaa_round(2)
# All Round 2 Spreads as of 1:00am Saturday
# Spreads are positive if strong seed is favored, negative if underdogs
round2spreads <- data.frame(
matrix(
c(
"Villanova", 11,
"Purdue", 3.5,
"Texas Tech", 0,
"Marshall", -11,
"Kansas", 4.5,
"Duke", 10,
"Michigan St", 9,
"Auburn", 1,
"UMBC", -12,
"Cincinnati", 7,
"Tennessee", 6,
"Buffalo", -7.5,
"Xavier", 4,
"North Carolina", 6,
"Michigan", 3,
"Gonzaga", 2.5),
ncol = 2, byrow = TRUE), stringsAsFactors = FALSE
)
names(round2spreads) <- c("Team", "Spread")
round2spreads$Spread <- as.numeric(round2spreads$Spread)
# Append spreads on to bracket
round2 <- round2 %>%
left_join(round2spreads, by = c('TeamName.x' = 'Team')) %>%
mutate(Diff = Prediction - Spread)
Here are the model predictions for all round 2 games.
# Determine who model would bet on ATS
round2 <- ATSchoice(round2)
# Output of model recommendations
round2_output_table <- round2 %>%
select(StrongSeed, WeakSeed, TeamName.x, TeamName.y, Spread, Prediction, Diff, Win_Prob, ModelChoice)
kable(round2_output_table)
StrongSeed | WeakSeed | TeamName.x | TeamName.y | Spread | Prediction | Diff | Win_Prob | ModelChoice |
---|---|---|---|---|---|---|---|---|
R1W1 | R1W8 | Villanova | Alabama | 11.0 | 8.3 | -2.7 | 0.737 | Alabama |
R1W2 | R1W7 | Purdue | Butler | 3.5 | 8.1 | 4.6 | 0.734 | Purdue |
R1W3 | R1W6 | Texas Tech | Florida | 0.0 | -0.7 | -0.7 | 0.479 | No choice |
R1W4 | R1W5 | Marshall | West Virginia | -11.0 | -4.6 | 6.4 | 0.368 | Marshall |
R1X1 | R1X8 | Kansas | Seton Hall | 4.5 | 2.2 | -2.3 | 0.563 | Seton Hall |
R1X2 | R1X7 | Duke | Rhode Island | 10.0 | 3.8 | -6.2 | 0.610 | Rhode Island |
R1X3 | R1X6 | Michigan St | Syracuse | 9.0 | 5.2 | -3.8 | 0.649 | Syracuse |
R1X4 | R1X5 | Auburn | Clemson | 1.0 | -0.6 | -1.6 | 0.482 | No choice |
R1Y1 | R1Y8 | UMBC | Kansas St | -12.0 | -3.5 | 8.5 | 0.399 | UMBC |
R1Y2 | R1Y7 | Cincinnati | Nevada | 7.0 | 9.1 | 2.1 | 0.762 | Cincinnati |
R1Y3 | R1Y6 | Tennessee | Loyola-Chicago | 6.0 | 5.8 | -0.2 | 0.666 | No choice |
R1Y4 | R1Y5 | Buffalo | Kentucky | -7.5 | 2.2 | 9.7 | 0.565 | Buffalo |
R1Z1 | R1Z8 | Xavier | Florida St | 4.0 | -0.2 | -4.2 | 0.492 | Florida St |
R1Z2 | R1Z7 | North Carolina | Texas A&M | 6.0 | 3.3 | -2.7 | 0.596 | Texas A&M |
R1Z3 | R1Z6 | Michigan | Houston | 3.0 | 3.5 | 0.5 | 0.601 | No choice |
R1Z4 | R1Z5 | Gonzaga | Ohio St | 2.5 | 10.6 | 8.1 | 0.803 | Gonzaga |
The model is still picking against all #1 seeds, but no longer against all #2 seeds. So I’m going to start evaluating model on all recommendations, while still hesitant to wager on #1 seed games. The recommendations are:
# Manual input of round 2 results
# Need to automate this!
round2results <- data.frame(
matrix(
c(
"Villanova", 81, 58,
"Texas Tech", 69, 66,
"Duke", 87, 62,
"Tennessee", 62, 63,
"Buffalo", 75, 95,
"Michigan", 64, 63,
"Gonzaga", 90, 84,
"Kansas", 83, 79,
"Purdue", 76, 73,
"Michigan St", 53, 55,
"North Carolina", 65, 86,
"Cincinnati", 73, 75,
"Auburn", 53, 84,
"UMBC", 43, 50,
"Xavier", 70, 75,
"Marshall", 71, 94),
ncol = 3, byrow = TRUE), stringsAsFactors = FALSE
)
names(round2results) <- c("Team", "Team.x.score", "Team.y.score")
round2results$Team.x.score <- as.numeric(round2results$Team.x.score)
round2results$Team.y.score <- as.numeric(round2results$Team.y.score)
# Append Game Results to Bracket
round2 <- round2 %>%
left_join(round2results, by = c('TeamName.x' = 'Team'))
# Determine Model's Accuracy ATS
round2 <- ATSresults(round2)
# Table of results
output_table_2 <- round2 %>%
select(StrongSeed, TeamName.x, WeakSeed, TeamName.y, Spread, Prediction, ModelChoice, Team.x.score, Team.y.score, ATSWinner, Accuracy)
output_table_2 <- rbind(output_table_1, output_table_2)
kable(output_table_2)
StrongSeed | TeamName.x | WeakSeed | TeamName.y | Spread | Prediction | ModelChoice | Team.x.score | Team.y.score | ATSWinner | Accuracy |
---|---|---|---|---|---|---|---|---|---|---|
W11a | St Bonaventure | W11b | UCLA | -3.5 | 2.6 | St Bonaventure | 65 | 58 | St Bonaventure | Correct |
W16a | Long Island | W16b | Radford | -4.5 | 0.9 | Long Island | 61 | 71 | Radford | Incorrect |
X11a | Arizona St | X11b | Syracuse | 1.0 | 1.3 | No choice | 56 | 60 | Syracuse | NA |
Z16a | NC Central | Z16b | TX Southern | -4.5 | 9.3 | NC Central | 46 | 64 | TX Southern | Incorrect |
W01 | Villanova | W16b | Radford | 23.0 | 9.5 | No choice | 87 | 61 | Villanova | NA |
W02 | Purdue | W15 | CS Fullerton | 20.5 | 13.4 | No choice | 74 | 48 | Purdue | NA |
W03 | Texas Tech | W14 | SF Austin | 11.0 | 11.4 | No choice | 70 | 60 | SF Austin | NA |
W04 | Wichita St | W13 | Marshall | 11.5 | 4.3 | Marshall | 75 | 81 | Marshall | Correct |
W05 | West Virginia | W12 | Murray St | 10.5 | 1.1 | Murray St | 85 | 68 | West Virginia | Incorrect |
W06 | Florida | W11a | St Bonaventure | 5.5 | 8.0 | Florida | 77 | 62 | Florida | Correct |
W07 | Arkansas | W10 | Butler | -1.5 | -1.4 | No choice | 62 | 79 | Butler | NA |
W08 | Virginia Tech | W09 | Alabama | 2.5 | 9.2 | Virginia Tech | 83 | 86 | Alabama | Incorrect |
X01 | Kansas | X16 | Penn | 14.5 | 6.8 | No choice | 76 | 60 | Kansas | NA |
X02 | Duke | X15 | Iona | 20.0 | 15.0 | No choice | 89 | 67 | Duke | NA |
X03 | Michigan St | X14 | Bucknell | 14.5 | 7.8 | Bucknell | 82 | 78 | Bucknell | Correct |
X04 | Auburn | X13 | Col Charleston | 9.0 | -0.1 | Col Charleston | 62 | 58 | Col Charleston | Correct |
X05 | Clemson | X12 | New Mexico St | 4.5 | -0.3 | New Mexico St | 79 | 68 | Clemson | Incorrect |
X06 | TCU | X11b | Syracuse | 4.0 | 1.0 | Syracuse | 52 | 57 | Syracuse | Correct |
X07 | Rhode Island | X10 | Oklahoma | 1.5 | 4.7 | Rhode Island | 83 | 78 | Rhode Island | Correct |
X08 | Seton Hall | X09 | NC State | 3.0 | 1.1 | No choice | 94 | 83 | Seton Hall | NA |
Y01 | Virginia | Y16 | UMBC | 21.0 | 3.5 | No choice | 54 | 74 | UMBC | NA |
Y02 | Cincinnati | Y15 | Georgia St | 14.0 | 7.1 | No choice | 68 | 53 | Cincinnati | NA |
Y03 | Tennessee | Y14 | Wright St | 11.5 | 5.4 | Wright St | 73 | 47 | Tennessee | Incorrect |
Y04 | Arizona | Y13 | Buffalo | 8.5 | -7.1 | Buffalo | 68 | 89 | Buffalo | Correct |
Y05 | Kentucky | Y12 | Davidson | 5.0 | 1.7 | Davidson | 78 | 73 | Push | Push |
Y06 | Miami FL | Y11 | Loyola-Chicago | 2.0 | 6.7 | Miami FL | 62 | 64 | Loyola-Chicago | Incorrect |
Y07 | Nevada | Y10 | Texas | 0.0 | 6.2 | Nevada | 87 | 83 | Nevada | Correct |
Y08 | Creighton | Y09 | Kansas St | 1.0 | -1.1 | Kansas St | 59 | 69 | Kansas St | Correct |
Z01 | Xavier | Z16b | TX Southern | 19.5 | 15.6 | No choice | 91 | 72 | TX Southern | NA |
Z02 | North Carolina | Z15 | Lipscomb | 19.5 | 13.1 | No choice | 84 | 66 | Lipscomb | NA |
Z03 | Michigan | Z14 | Montana | 10.0 | 5.2 | Montana | 61 | 47 | Michigan | Incorrect |
Z04 | Gonzaga | Z13 | UNC Greensboro | 13.5 | 7.8 | UNC Greensboro | 68 | 64 | UNC Greensboro | Correct |
Z05 | Ohio St | Z12 | S Dakota St | 8.0 | 8.9 | No choice | 81 | 73 | Push | NA |
Z06 | Houston | Z11 | San Diego St | 4.0 | 5.1 | No choice | 67 | 65 | San Diego St | NA |
Z07 | Texas A&M | Z10 | Providence | 2.5 | 2.3 | No choice | 73 | 69 | Texas A&M | NA |
Z08 | Missouri | Z09 | Florida St | -1.5 | -11.0 | Florida St | 54 | 67 | Florida St | Correct |
R1W1 | Villanova | R1W8 | Alabama | 11.0 | 8.3 | Alabama | 81 | 58 | Villanova | Incorrect |
R1W2 | Purdue | R1W7 | Butler | 3.5 | 8.1 | Purdue | 76 | 73 | Butler | Incorrect |
R1W3 | Texas Tech | R1W6 | Florida | 0.0 | -0.7 | No choice | 69 | 66 | Texas Tech | NA |
R1W4 | Marshall | R1W5 | West Virginia | -11.0 | -4.6 | Marshall | 71 | 94 | West Virginia | Incorrect |
R1X1 | Kansas | R1X8 | Seton Hall | 4.5 | 2.2 | Seton Hall | 83 | 79 | Seton Hall | Correct |
R1X2 | Duke | R1X7 | Rhode Island | 10.0 | 3.8 | Rhode Island | 87 | 62 | Duke | Incorrect |
R1X3 | Michigan St | R1X6 | Syracuse | 9.0 | 5.2 | Syracuse | 53 | 55 | Syracuse | Correct |
R1X4 | Auburn | R1X5 | Clemson | 1.0 | -0.6 | No choice | 53 | 84 | Clemson | NA |
R1Y1 | UMBC | R1Y8 | Kansas St | -12.0 | -3.5 | UMBC | 43 | 50 | UMBC | Correct |
R1Y2 | Cincinnati | R1Y7 | Nevada | 7.0 | 9.1 | Cincinnati | 73 | 75 | Nevada | Incorrect |
R1Y3 | Tennessee | R1Y6 | Loyola-Chicago | 6.0 | 5.8 | No choice | 62 | 63 | Loyola-Chicago | NA |
R1Y4 | Buffalo | R1Y5 | Kentucky | -7.5 | 2.2 | Buffalo | 75 | 95 | Kentucky | Incorrect |
R1Z1 | Xavier | R1Z8 | Florida St | 4.0 | -0.2 | Florida St | 70 | 75 | Florida St | Correct |
R1Z2 | North Carolina | R1Z7 | Texas A&M | 6.0 | 3.3 | Texas A&M | 65 | 86 | Texas A&M | Correct |
R1Z3 | Michigan | R1Z6 | Houston | 3.0 | 3.5 | No choice | 64 | 63 | Houston | NA |
R1Z4 | Gonzaga | R1Z5 | Ohio St | 2.5 | 10.6 | Gonzaga | 90 | 84 | Gonzaga | Correct |
# Summary of results
table(output_table_2$Accuracy)
##
## Correct Incorrect Push
## 18 14 1
In round 2, the model was 6-6 ATS. In total, the model is 18-14-1 through the first two rounds of the tournament for an overall success rate of 56.25%.
# Recording Round 2 Winners into Round 3
bracket <- advance_winners(round2)
# Model Predictions for Round 3
round3 <- predict_ncaa_round(3)
# All Round 3 Spreads as of 7:00pm Monday
# Spreads are positive if strong seed is favored, negative if underdogs
round3spreads <- data.frame(
matrix(
c(
"Villanova", 5.5,
"Purdue", 1.5,
"Kansas", 4.5,
"Duke", 11,
"Kansas St", -6,
"Nevada", 1.5,
"Florida St", -5.5,
"Texas A&M", -2.5),
ncol = 2, byrow = TRUE), stringsAsFactors = FALSE
)
names(round3spreads) <- c("Team", "Spread")
round3spreads$Spread <- as.numeric(round3spreads$Spread)
# Append spreads on to bracket
round3 <- round3 %>%
left_join(round3spreads, by = c('TeamName.x' = 'Team')) %>%
mutate(Diff = Prediction - Spread)
Here are the model predictions for all round 3 games.
# Determine who model would bet on ATS
round3 <- ATSchoice(round3)
# Output of model recommendations
round3_predictions <- round3 %>%
select(StrongSeed, WeakSeed, TeamName.x, TeamName.y, Spread, Prediction, Diff, Win_Prob, ModelChoice)
kable(round3_predictions)
StrongSeed | WeakSeed | TeamName.x | TeamName.y | Spread | Prediction | Diff | Win_Prob | ModelChoice |
---|---|---|---|---|---|---|---|---|
R2W1 | R2W4 | Villanova | West Virginia | 5.5 | 2.9 | -2.6 | 0.583 | West Virginia |
R2W2 | R2W3 | Purdue | Texas Tech | 1.5 | 0.6 | -0.9 | 0.518 | No choice |
R2X1 | R2X4 | Kansas | Clemson | 4.5 | 8.2 | 3.7 | 0.735 | Kansas |
R2X2 | R2X3 | Duke | Syracuse | 11.0 | 4.3 | -6.7 | 0.625 | Syracuse |
R2Y1 | R2Y4 | Kansas St | Kentucky | -6.0 | -2.3 | 3.7 | 0.435 | Kansas St |
R2Y2 | R2Y3 | Nevada | Loyola-Chicago | 1.5 | -0.8 | -2.3 | 0.477 | Loyola-Chicago |
R2Z1 | R2Z4 | Florida St | Gonzaga | -5.5 | -5.9 | -0.4 | 0.330 | No choice |
R2Z2 | R2Z3 | Texas A&M | Michigan | -2.5 | -2.9 | -0.4 | 0.416 | No choice |
The model recommendations for round 3 are not as strong as in previous rounds. The recommendations in order of strength are:
Fringe picks:
To be updated after games are played.
# Manual input of round 3 results
# Need to automate this!
round3results <- data.frame(
matrix(
c(
"Villanova", 90, 78,
"Purdue", 65, 78,
"Kansas", 80, 76,
"Duke", 69, 65,
"Kansas St", 61, 58,
"Nevada", 68, 69,
"Florida St", 75, 60,
"Texas A&M", 72, 99),
ncol = 3, byrow = TRUE), stringsAsFactors = FALSE
)
names(round3results) <- c("Team", "Team.x.score", "Team.y.score")
round3results$Team.x.score <- as.numeric(round3results$Team.x.score)
round3results$Team.y.score <- as.numeric(round3results$Team.y.score)
# Append Game Results to Bracket
round3 <- round3 %>%
left_join(round3results, by = c('TeamName.x' = 'Team'))
# Determine Model's Accuracy ATS
round3 <- ATSresults(round3)
# Table of results
round3_results_table <- round3 %>%
select(StrongSeed, TeamName.x, WeakSeed, TeamName.y, Spread, Prediction, ModelChoice, Team.x.score, Team.y.score, ATSWinner, Accuracy)
round3_results_table <- rbind(output_table_2, round3_results_table)
kable(round3_results_table)
StrongSeed | TeamName.x | WeakSeed | TeamName.y | Spread | Prediction | ModelChoice | Team.x.score | Team.y.score | ATSWinner | Accuracy |
---|---|---|---|---|---|---|---|---|---|---|
W11a | St Bonaventure | W11b | UCLA | -3.5 | 2.6 | St Bonaventure | 65 | 58 | St Bonaventure | Correct |
W16a | Long Island | W16b | Radford | -4.5 | 0.9 | Long Island | 61 | 71 | Radford | Incorrect |
X11a | Arizona St | X11b | Syracuse | 1.0 | 1.3 | No choice | 56 | 60 | Syracuse | NA |
Z16a | NC Central | Z16b | TX Southern | -4.5 | 9.3 | NC Central | 46 | 64 | TX Southern | Incorrect |
W01 | Villanova | W16b | Radford | 23.0 | 9.5 | No choice | 87 | 61 | Villanova | NA |
W02 | Purdue | W15 | CS Fullerton | 20.5 | 13.4 | No choice | 74 | 48 | Purdue | NA |
W03 | Texas Tech | W14 | SF Austin | 11.0 | 11.4 | No choice | 70 | 60 | SF Austin | NA |
W04 | Wichita St | W13 | Marshall | 11.5 | 4.3 | Marshall | 75 | 81 | Marshall | Correct |
W05 | West Virginia | W12 | Murray St | 10.5 | 1.1 | Murray St | 85 | 68 | West Virginia | Incorrect |
W06 | Florida | W11a | St Bonaventure | 5.5 | 8.0 | Florida | 77 | 62 | Florida | Correct |
W07 | Arkansas | W10 | Butler | -1.5 | -1.4 | No choice | 62 | 79 | Butler | NA |
W08 | Virginia Tech | W09 | Alabama | 2.5 | 9.2 | Virginia Tech | 83 | 86 | Alabama | Incorrect |
X01 | Kansas | X16 | Penn | 14.5 | 6.8 | No choice | 76 | 60 | Kansas | NA |
X02 | Duke | X15 | Iona | 20.0 | 15.0 | No choice | 89 | 67 | Duke | NA |
X03 | Michigan St | X14 | Bucknell | 14.5 | 7.8 | Bucknell | 82 | 78 | Bucknell | Correct |
X04 | Auburn | X13 | Col Charleston | 9.0 | -0.1 | Col Charleston | 62 | 58 | Col Charleston | Correct |
X05 | Clemson | X12 | New Mexico St | 4.5 | -0.3 | New Mexico St | 79 | 68 | Clemson | Incorrect |
X06 | TCU | X11b | Syracuse | 4.0 | 1.0 | Syracuse | 52 | 57 | Syracuse | Correct |
X07 | Rhode Island | X10 | Oklahoma | 1.5 | 4.7 | Rhode Island | 83 | 78 | Rhode Island | Correct |
X08 | Seton Hall | X09 | NC State | 3.0 | 1.1 | No choice | 94 | 83 | Seton Hall | NA |
Y01 | Virginia | Y16 | UMBC | 21.0 | 3.5 | No choice | 54 | 74 | UMBC | NA |
Y02 | Cincinnati | Y15 | Georgia St | 14.0 | 7.1 | No choice | 68 | 53 | Cincinnati | NA |
Y03 | Tennessee | Y14 | Wright St | 11.5 | 5.4 | Wright St | 73 | 47 | Tennessee | Incorrect |
Y04 | Arizona | Y13 | Buffalo | 8.5 | -7.1 | Buffalo | 68 | 89 | Buffalo | Correct |
Y05 | Kentucky | Y12 | Davidson | 5.0 | 1.7 | Davidson | 78 | 73 | Push | Push |
Y06 | Miami FL | Y11 | Loyola-Chicago | 2.0 | 6.7 | Miami FL | 62 | 64 | Loyola-Chicago | Incorrect |
Y07 | Nevada | Y10 | Texas | 0.0 | 6.2 | Nevada | 87 | 83 | Nevada | Correct |
Y08 | Creighton | Y09 | Kansas St | 1.0 | -1.1 | Kansas St | 59 | 69 | Kansas St | Correct |
Z01 | Xavier | Z16b | TX Southern | 19.5 | 15.6 | No choice | 91 | 72 | TX Southern | NA |
Z02 | North Carolina | Z15 | Lipscomb | 19.5 | 13.1 | No choice | 84 | 66 | Lipscomb | NA |
Z03 | Michigan | Z14 | Montana | 10.0 | 5.2 | Montana | 61 | 47 | Michigan | Incorrect |
Z04 | Gonzaga | Z13 | UNC Greensboro | 13.5 | 7.8 | UNC Greensboro | 68 | 64 | UNC Greensboro | Correct |
Z05 | Ohio St | Z12 | S Dakota St | 8.0 | 8.9 | No choice | 81 | 73 | Push | NA |
Z06 | Houston | Z11 | San Diego St | 4.0 | 5.1 | No choice | 67 | 65 | San Diego St | NA |
Z07 | Texas A&M | Z10 | Providence | 2.5 | 2.3 | No choice | 73 | 69 | Texas A&M | NA |
Z08 | Missouri | Z09 | Florida St | -1.5 | -11.0 | Florida St | 54 | 67 | Florida St | Correct |
R1W1 | Villanova | R1W8 | Alabama | 11.0 | 8.3 | Alabama | 81 | 58 | Villanova | Incorrect |
R1W2 | Purdue | R1W7 | Butler | 3.5 | 8.1 | Purdue | 76 | 73 | Butler | Incorrect |
R1W3 | Texas Tech | R1W6 | Florida | 0.0 | -0.7 | No choice | 69 | 66 | Texas Tech | NA |
R1W4 | Marshall | R1W5 | West Virginia | -11.0 | -4.6 | Marshall | 71 | 94 | West Virginia | Incorrect |
R1X1 | Kansas | R1X8 | Seton Hall | 4.5 | 2.2 | Seton Hall | 83 | 79 | Seton Hall | Correct |
R1X2 | Duke | R1X7 | Rhode Island | 10.0 | 3.8 | Rhode Island | 87 | 62 | Duke | Incorrect |
R1X3 | Michigan St | R1X6 | Syracuse | 9.0 | 5.2 | Syracuse | 53 | 55 | Syracuse | Correct |
R1X4 | Auburn | R1X5 | Clemson | 1.0 | -0.6 | No choice | 53 | 84 | Clemson | NA |
R1Y1 | UMBC | R1Y8 | Kansas St | -12.0 | -3.5 | UMBC | 43 | 50 | UMBC | Correct |
R1Y2 | Cincinnati | R1Y7 | Nevada | 7.0 | 9.1 | Cincinnati | 73 | 75 | Nevada | Incorrect |
R1Y3 | Tennessee | R1Y6 | Loyola-Chicago | 6.0 | 5.8 | No choice | 62 | 63 | Loyola-Chicago | NA |
R1Y4 | Buffalo | R1Y5 | Kentucky | -7.5 | 2.2 | Buffalo | 75 | 95 | Kentucky | Incorrect |
R1Z1 | Xavier | R1Z8 | Florida St | 4.0 | -0.2 | Florida St | 70 | 75 | Florida St | Correct |
R1Z2 | North Carolina | R1Z7 | Texas A&M | 6.0 | 3.3 | Texas A&M | 65 | 86 | Texas A&M | Correct |
R1Z3 | Michigan | R1Z6 | Houston | 3.0 | 3.5 | No choice | 64 | 63 | Houston | NA |
R1Z4 | Gonzaga | R1Z5 | Ohio St | 2.5 | 10.6 | Gonzaga | 90 | 84 | Gonzaga | Correct |
R2W1 | Villanova | R2W4 | West Virginia | 5.5 | 2.9 | West Virginia | 90 | 78 | Villanova | Incorrect |
R2W2 | Purdue | R2W3 | Texas Tech | 1.5 | 0.6 | No choice | 65 | 78 | Texas Tech | NA |
R2X1 | Kansas | R2X4 | Clemson | 4.5 | 8.2 | Kansas | 80 | 76 | Clemson | Incorrect |
R2X2 | Duke | R2X3 | Syracuse | 11.0 | 4.3 | Syracuse | 69 | 65 | Syracuse | Correct |
R2Y1 | Kansas St | R2Y4 | Kentucky | -6.0 | -2.3 | Kansas St | 61 | 58 | Kansas St | Correct |
R2Y2 | Nevada | R2Y3 | Loyola-Chicago | 1.5 | -0.8 | Loyola-Chicago | 68 | 69 | Loyola-Chicago | Correct |
R2Z1 | Florida St | R2Z4 | Gonzaga | -5.5 | -5.9 | No choice | 75 | 60 | Florida St | NA |
R2Z2 | Texas A&M | R2Z3 | Michigan | -2.5 | -2.9 | No choice | 72 | 99 | Michigan | NA |
# Summary of results
table(round3_results_table$Accuracy)
##
## Correct Incorrect Push
## 21 16 1
The model went 3-2 ATS in the Sweet 16 and is now 21-16-1 throughout the tourney.
# Recording Round 3 Winners into Round 4
bracket <- advance_winners(round3)
# Model Predictions for Round 4
round4 <- predict_ncaa_round(4)
# All Round 4 Spreads as of 7:00pm Monday
# Spreads are positive if strong seed is favored, negative if underdogs
round4spreads <- data.frame(
matrix(
c(
"Villanova", 7,
"Kansas", -3.5,
"Kansas St", 1.5,
"Florida St", -4.5),
ncol = 2, byrow = TRUE), stringsAsFactors = FALSE
)
names(round4spreads) <- c("Team", "Spread")
round4spreads$Spread <- as.numeric(round4spreads$Spread)
# Append spreads on to bracket
round4 <- round4 %>%
left_join(round4spreads, by = c('TeamName.x' = 'Team')) %>%
mutate(Diff = Prediction - Spread)
Here are the model predictions for all round 4 games.
# Determine who model would bet on ATS
round4 <- ATSchoice(round4)
# Output of model recommendations
round4_predictions <- round4 %>%
select(StrongSeed, WeakSeed, TeamName.x, TeamName.y, Spread, Prediction, Diff, Win_Prob, ModelChoice)
kable(round4_predictions)
StrongSeed | WeakSeed | TeamName.x | TeamName.y | Spread | Prediction | Diff | Win_Prob | ModelChoice |
---|---|---|---|---|---|---|---|---|
R3W1 | R3W2 | Villanova | Texas Tech | 7.0 | -5.1 | -12.1 | 0.353 | Texas Tech |
R3X1 | R3X2 | Kansas | Duke | -3.5 | -3.4 | 0.1 | 0.402 | No choice |
R3Y1 | R3Y2 | Kansas St | Loyola-Chicago | 1.5 | -1.9 | -3.4 | 0.445 | Loyola-Chicago |
R3Z1 | R3Z2 | Florida St | Michigan | -4.5 | -1.7 | 2.8 | 0.453 | Florida St |
The model recommendations for round 4 are …
To be updated after games are played.
# Manual input of round 4 results
# Need to automate this!
round4results <- data.frame(
matrix(
c(
"Villanova", 71, 59,
"Kansas", 85, 81,
"Kansas St", 62, 78,
"Florida St", 54, 58),
ncol = 3, byrow = TRUE), stringsAsFactors = FALSE
)
names(round4results) <- c("Team", "Team.x.score", "Team.y.score")
round4results$Team.x.score <- as.numeric(round4results$Team.x.score)
round4results$Team.y.score <- as.numeric(round4results$Team.y.score)
# Append Game Results to Bracket
round4 <- round4 %>%
left_join(round4results, by = c('TeamName.x' = 'Team'))
# Determine Model's Accuracy ATS
round4 <- ATSresults(round4)
# Table of results
round4_results_table <- round4 %>%
select(StrongSeed, TeamName.x, WeakSeed, TeamName.y, Spread, Prediction, ModelChoice, Team.x.score, Team.y.score, ATSWinner, Accuracy)
round4_results_table <- rbind(round3_results_table, round4_results_table)
kable(round4_results_table)
StrongSeed | TeamName.x | WeakSeed | TeamName.y | Spread | Prediction | ModelChoice | Team.x.score | Team.y.score | ATSWinner | Accuracy |
---|---|---|---|---|---|---|---|---|---|---|
W11a | St Bonaventure | W11b | UCLA | -3.5 | 2.6 | St Bonaventure | 65 | 58 | St Bonaventure | Correct |
W16a | Long Island | W16b | Radford | -4.5 | 0.9 | Long Island | 61 | 71 | Radford | Incorrect |
X11a | Arizona St | X11b | Syracuse | 1.0 | 1.3 | No choice | 56 | 60 | Syracuse | NA |
Z16a | NC Central | Z16b | TX Southern | -4.5 | 9.3 | NC Central | 46 | 64 | TX Southern | Incorrect |
W01 | Villanova | W16b | Radford | 23.0 | 9.5 | No choice | 87 | 61 | Villanova | NA |
W02 | Purdue | W15 | CS Fullerton | 20.5 | 13.4 | No choice | 74 | 48 | Purdue | NA |
W03 | Texas Tech | W14 | SF Austin | 11.0 | 11.4 | No choice | 70 | 60 | SF Austin | NA |
W04 | Wichita St | W13 | Marshall | 11.5 | 4.3 | Marshall | 75 | 81 | Marshall | Correct |
W05 | West Virginia | W12 | Murray St | 10.5 | 1.1 | Murray St | 85 | 68 | West Virginia | Incorrect |
W06 | Florida | W11a | St Bonaventure | 5.5 | 8.0 | Florida | 77 | 62 | Florida | Correct |
W07 | Arkansas | W10 | Butler | -1.5 | -1.4 | No choice | 62 | 79 | Butler | NA |
W08 | Virginia Tech | W09 | Alabama | 2.5 | 9.2 | Virginia Tech | 83 | 86 | Alabama | Incorrect |
X01 | Kansas | X16 | Penn | 14.5 | 6.8 | No choice | 76 | 60 | Kansas | NA |
X02 | Duke | X15 | Iona | 20.0 | 15.0 | No choice | 89 | 67 | Duke | NA |
X03 | Michigan St | X14 | Bucknell | 14.5 | 7.8 | Bucknell | 82 | 78 | Bucknell | Correct |
X04 | Auburn | X13 | Col Charleston | 9.0 | -0.1 | Col Charleston | 62 | 58 | Col Charleston | Correct |
X05 | Clemson | X12 | New Mexico St | 4.5 | -0.3 | New Mexico St | 79 | 68 | Clemson | Incorrect |
X06 | TCU | X11b | Syracuse | 4.0 | 1.0 | Syracuse | 52 | 57 | Syracuse | Correct |
X07 | Rhode Island | X10 | Oklahoma | 1.5 | 4.7 | Rhode Island | 83 | 78 | Rhode Island | Correct |
X08 | Seton Hall | X09 | NC State | 3.0 | 1.1 | No choice | 94 | 83 | Seton Hall | NA |
Y01 | Virginia | Y16 | UMBC | 21.0 | 3.5 | No choice | 54 | 74 | UMBC | NA |
Y02 | Cincinnati | Y15 | Georgia St | 14.0 | 7.1 | No choice | 68 | 53 | Cincinnati | NA |
Y03 | Tennessee | Y14 | Wright St | 11.5 | 5.4 | Wright St | 73 | 47 | Tennessee | Incorrect |
Y04 | Arizona | Y13 | Buffalo | 8.5 | -7.1 | Buffalo | 68 | 89 | Buffalo | Correct |
Y05 | Kentucky | Y12 | Davidson | 5.0 | 1.7 | Davidson | 78 | 73 | Push | Push |
Y06 | Miami FL | Y11 | Loyola-Chicago | 2.0 | 6.7 | Miami FL | 62 | 64 | Loyola-Chicago | Incorrect |
Y07 | Nevada | Y10 | Texas | 0.0 | 6.2 | Nevada | 87 | 83 | Nevada | Correct |
Y08 | Creighton | Y09 | Kansas St | 1.0 | -1.1 | Kansas St | 59 | 69 | Kansas St | Correct |
Z01 | Xavier | Z16b | TX Southern | 19.5 | 15.6 | No choice | 91 | 72 | TX Southern | NA |
Z02 | North Carolina | Z15 | Lipscomb | 19.5 | 13.1 | No choice | 84 | 66 | Lipscomb | NA |
Z03 | Michigan | Z14 | Montana | 10.0 | 5.2 | Montana | 61 | 47 | Michigan | Incorrect |
Z04 | Gonzaga | Z13 | UNC Greensboro | 13.5 | 7.8 | UNC Greensboro | 68 | 64 | UNC Greensboro | Correct |
Z05 | Ohio St | Z12 | S Dakota St | 8.0 | 8.9 | No choice | 81 | 73 | Push | NA |
Z06 | Houston | Z11 | San Diego St | 4.0 | 5.1 | No choice | 67 | 65 | San Diego St | NA |
Z07 | Texas A&M | Z10 | Providence | 2.5 | 2.3 | No choice | 73 | 69 | Texas A&M | NA |
Z08 | Missouri | Z09 | Florida St | -1.5 | -11.0 | Florida St | 54 | 67 | Florida St | Correct |
R1W1 | Villanova | R1W8 | Alabama | 11.0 | 8.3 | Alabama | 81 | 58 | Villanova | Incorrect |
R1W2 | Purdue | R1W7 | Butler | 3.5 | 8.1 | Purdue | 76 | 73 | Butler | Incorrect |
R1W3 | Texas Tech | R1W6 | Florida | 0.0 | -0.7 | No choice | 69 | 66 | Texas Tech | NA |
R1W4 | Marshall | R1W5 | West Virginia | -11.0 | -4.6 | Marshall | 71 | 94 | West Virginia | Incorrect |
R1X1 | Kansas | R1X8 | Seton Hall | 4.5 | 2.2 | Seton Hall | 83 | 79 | Seton Hall | Correct |
R1X2 | Duke | R1X7 | Rhode Island | 10.0 | 3.8 | Rhode Island | 87 | 62 | Duke | Incorrect |
R1X3 | Michigan St | R1X6 | Syracuse | 9.0 | 5.2 | Syracuse | 53 | 55 | Syracuse | Correct |
R1X4 | Auburn | R1X5 | Clemson | 1.0 | -0.6 | No choice | 53 | 84 | Clemson | NA |
R1Y1 | UMBC | R1Y8 | Kansas St | -12.0 | -3.5 | UMBC | 43 | 50 | UMBC | Correct |
R1Y2 | Cincinnati | R1Y7 | Nevada | 7.0 | 9.1 | Cincinnati | 73 | 75 | Nevada | Incorrect |
R1Y3 | Tennessee | R1Y6 | Loyola-Chicago | 6.0 | 5.8 | No choice | 62 | 63 | Loyola-Chicago | NA |
R1Y4 | Buffalo | R1Y5 | Kentucky | -7.5 | 2.2 | Buffalo | 75 | 95 | Kentucky | Incorrect |
R1Z1 | Xavier | R1Z8 | Florida St | 4.0 | -0.2 | Florida St | 70 | 75 | Florida St | Correct |
R1Z2 | North Carolina | R1Z7 | Texas A&M | 6.0 | 3.3 | Texas A&M | 65 | 86 | Texas A&M | Correct |
R1Z3 | Michigan | R1Z6 | Houston | 3.0 | 3.5 | No choice | 64 | 63 | Houston | NA |
R1Z4 | Gonzaga | R1Z5 | Ohio St | 2.5 | 10.6 | Gonzaga | 90 | 84 | Gonzaga | Correct |
R2W1 | Villanova | R2W4 | West Virginia | 5.5 | 2.9 | West Virginia | 90 | 78 | Villanova | Incorrect |
R2W2 | Purdue | R2W3 | Texas Tech | 1.5 | 0.6 | No choice | 65 | 78 | Texas Tech | NA |
R2X1 | Kansas | R2X4 | Clemson | 4.5 | 8.2 | Kansas | 80 | 76 | Clemson | Incorrect |
R2X2 | Duke | R2X3 | Syracuse | 11.0 | 4.3 | Syracuse | 69 | 65 | Syracuse | Correct |
R2Y1 | Kansas St | R2Y4 | Kentucky | -6.0 | -2.3 | Kansas St | 61 | 58 | Kansas St | Correct |
R2Y2 | Nevada | R2Y3 | Loyola-Chicago | 1.5 | -0.8 | Loyola-Chicago | 68 | 69 | Loyola-Chicago | Correct |
R2Z1 | Florida St | R2Z4 | Gonzaga | -5.5 | -5.9 | No choice | 75 | 60 | Florida St | NA |
R2Z2 | Texas A&M | R2Z3 | Michigan | -2.5 | -2.9 | No choice | 72 | 99 | Michigan | NA |
R3W1 | Villanova | R3W2 | Texas Tech | 7.0 | -5.1 | Texas Tech | 71 | 59 | Villanova | Incorrect |
R3X1 | Kansas | R3X2 | Duke | -3.5 | -3.4 | No choice | 85 | 81 | Kansas | NA |
R3Y1 | Kansas St | R3Y2 | Loyola-Chicago | 1.5 | -1.9 | Loyola-Chicago | 62 | 78 | Loyola-Chicago | Correct |
R3Z1 | Florida St | R3Z2 | Michigan | -4.5 | -1.7 | Florida St | 54 | 58 | Florida St | Correct |
# Summary of results
table(round4_results_table$Accuracy)
##
## Correct Incorrect Push
## 23 17 1
The model went 2-1 ATS in the Elite 8 and is now 23-17-1 through the entire tourney for a 57.5% success rate. Considering the sample size of 40 games, a 95% confidence interval for the true model’s accuracy is between 42.2% and 72.8%.
# Recording Round 5 Winners into Round 5
bracket <- advance_winners(round4)
# Model Predictions for Round 5
round5 <- predict_ncaa_round(5)
# All Round 5 Spreads as of 8:30pm Thursday
# Spreads are positive if strong seed is favored, negative if underdogs
round5spreads <- data.frame(
matrix(
c(
"Villanova", 5,
"Loyola-Chicago", -5.5),
ncol = 2, byrow = TRUE), stringsAsFactors = FALSE
)
names(round5spreads) <- c("Team", "Spread")
round5spreads$Spread <- as.numeric(round5spreads$Spread)
# Append spreads on to bracket
round5 <- round5 %>%
left_join(round5spreads, by = c('TeamName.x' = 'Team')) %>%
mutate(Diff = Prediction - Spread)
Here are the model predictions for all round 4 games.
# Determine who model would bet on ATS
round5 <- ATSchoice(round5)
# Output of model recommendations
round5_predictions <- round5 %>%
select(StrongSeed, WeakSeed, TeamName.x, TeamName.y, Spread, Prediction, Diff, Win_Prob, ModelChoice)
kable(round5_predictions)
StrongSeed | WeakSeed | TeamName.x | TeamName.y | Spread | Prediction | Diff | Win_Prob | ModelChoice |
---|---|---|---|---|---|---|---|---|
R4W1 | R4X1 | Villanova | Kansas | 5.0 | 1.9 | -3.1 | 0.554 | Kansas |
R4Y1 | R4Z1 | Loyola-Chicago | Michigan | -5.5 | -6.8 | -1.3 | 0.305 | No choice |
The only model recommendations for the Final Four is Kansas.
To be updated after games are played.