Quantifying Defensive Sloppiness in Basketball
I present the Basketball Defensive Sloppiness index, a new method to visualize and quantify Defensive Sloppiness in a game time situation, to make data-driven player rotational decisions. There is lack of research, currently, that presents how teams
could utilize defensive statistics to evaluate a player’s defensive sloppiness, and eventually make team decisions that will determine the outcome of basketball games.
Defensive Sloppiness is defined as the lack of execution by a team, while the team does not have possession of the ball. Of all the defensive factors in a basketball game, there are three factors that are indicated by the ANOVA test that have significant
correlations to whether a team won the game: blocks, steals and personal fouls.
The generated model assigned respective weights to each of the three factors which creates the Basketball Defensive Sloppiness Index, using play by play data aggregated from the 2016-2017 NBA season (All three factors were checked with
Pearson correlation test for multicollinearity and residual normality). The generated model creates an index from 0 to 1, 1 being the most defensively sloppy and 0 being the least defensively sloppy.
Game 5 of the 2016-2017 NBA Finals, is a close (+/- 5 point) game, where the Basketball Defensive Sloppiness Index can be effectively used. In this game, Golden State was leading 98-95 after the end of the third quarter. To choose the optimal players
to play in the fourth quarter and maintain their lead, the Warriors’ coach must determine which of his players would be the least defensively sloppy, and most accurate in their free throws. Therefore, Defensive Sloppiness Index is the control variable,
to reduce opportunities for the Cavaliers to score and overcome and the Warriors’ lead. The Season Free Throw % for each player will be the most effective dependent variable to visualize with Defensive Sloppiness Index in this scenario, because the Cavaliers will try to slow down the pace of the game by fouling the Warriors, which would lead to free throw opportunities for the Warriors (See Figure 1).
On the plot shown below, the players who are least defensive sloppy and most likely to score free throws when they are on offense, are indicated in the upper right corner. This visualization of the Basketball Defensive Sloppiness Index helps the Golden State coach choose which player to put in during this critical part of the game, to increase the Warriors’ probability to win.
While this example uses FT% (Free Throw) as the dependent variable, this variable can be interchangeable with any other
variable such as, FG%(Field Goal), PPG (Average Points Per Game), depending on the circumstances of the game that the coach wants to decide on.
In conclusion, the Basketball Defensive Sloppiness can provide a much more sophisticated, yet interpretable lens into basketball player-tracking data, to better manage risks in each basketball game, and eventually financially impact the team franchise.
(Word Count: 483)

Capturebball

CODE:

sampledata <- read.csv(file = “C:/Users/peace/OneDrive/Documents/SLOAN’18/sampledata.csv”,header=TRUE, sep=”,”)

sampleGSroster <-read.csv(file = “C:/Users/peace/OneDrive/Documents/SLOAN’18/GSroster.csv”,header=TRUE, sep=”,”)

#reads in data sets

 

warplayer_ros <-sampleGSroster$Warriors

cavsplayer_ros <-sampleGSroster$Cavs

player_id <- sampledata$player

block_id <- sampledata$block

steals_id <- sampledata$steal

pfouls_id <- sampledata$reason

charges_id <-sampledata$reason

#assigns each column to a variable

 

#BLOCK DATA FOR GOLDEN STATE WARRIORS

gs_block <- intersect(warplayer_ros, block_id)

#filters sample data into team

block_freq <- table(gs_block)

#shows how many blocks per player from a particular team

block_freq

#displays the blocks per playersas.data.frame(table(gs_block))

as.data.frame(table(gs_block))

#formats the frequency table

gs_nonblock <- setdiff(warplayer_ros, gs_block)

#shows players with no blocks

block_f <- as.data.frame(table(gs_block))

block_f <- block_f[,2]

#pulls frequency from data set

blockdata <- cbind(gs_block, block_f)

#players with blocks and the frequency

nonblockdata <-cbind(gs_nonblock, 0)

#players with no blocks

gsblockdata <- rbind(blockdata, nonblockdata)

gsblockdata

#combines the rows of all the players and their blocks

 

#BLOCK DATA FOR CLEVELAND CAVALIERS

cld_block <- intersect(cavsplayer_ros, block_id)

#filters sample data into team

cldblock_freq <- table(cld_block)

#shows how many blocks per player from a particular team

cldblock_freq

#displays the blocks per playersas.data.frame(table(gs_block))

as.data.frame(table(cld_block))

#formats the frequency table

cld_nonblock <- setdiff(cavsplayer_ros, cld_block)

#shows players with no blocks

cldblock_f <- as.data.frame(table(cld_block))

cldblock_f <- cldblock_f[,2]

#pulls frequency from data set

cldblockdata <- cbind(cld_block, cldblock_f)

#players with blocks and the frequency

cldnonblockdata <-cbind(cld_nonblock, 0)

#players with no blocks

cldblockdata <- rbind(cldblockdata, cldnonblockdata)

cldblockdata

#combines the rows of all the players and their blocks

 

#STEALS DATA FOR GOLDEN STATE WARRIORS

gs_steal <- intersect(warplayer_ros, steals_id)

#filters sample data into team

gssteal_freq <- table(gs_steal)

#shows how many steals per player from a particular team

gssteal_freq

#displays the steals per playersas.data.frame(table(gs_steal))

as.data.frame(table(gs_steal))

#formats the frequency table

gs_nonsteal <- setdiff(warplayer_ros, gs_steal)

#shows players with no steals

gssteal_f <- as.data.frame(table(gs_steal))

gssteal_f <- gssteal_f[,2]

#pulls frequency from data set

gsstealdata <- cbind(gs_steal, gssteal_f)

#players with steals and the frequency

gsnonstealdata <-cbind(gs_nonsteal, 0)

#players with no steals

gsstealdata <- rbind(gsstealdata, gsnonstealdata)

gsstealdata

#combines the rows of all the players and their steals

 

#STEALS DATA FOR CLEVELAND CAVALIERS

cld_steal <- intersect(cavsplayer_ros, steals_id)

#filters sample data into team

cldsteal_freq <- table(cld_steal)

#shows how many steals per player from a particular team

cldsteal_freq

#displays the steals per playersas.data.frame(table(gs_steal))

as.data.frame(table(cld_steal))

#formats the frequency table

cld_nonsteal <- setdiff(cavsplayer_ros, cld_steal)

#shows players with no steals

cldsteal_f <- as.data.frame(table(cld_steal))

cldsteal_f <- cldsteal_f[,2]

#pulls frequency from data set

cldstealdata <- cbind(cld_steal, cldsteal_f)

#players with steals and the frequency

cldnonstealdata <-cbind(cld_nonsteal, 0)

#players with no steals

cldstealdata <- rbind(cldstealdata, cldnonstealdata)

cldstealdata

#combines the rows of all the players and their steals

 

#P. FOULS DATA FOR GOLDEN STATE WARRIORS

player_id

#vector of players associated with certain actions

all_pfouls <- which(c(as.character(pfouls_id)) == “p.foul”)

#vector of where there were “p.fouls” in reason column

all_pfouls

#vector of the positions

player_pfouls <-player_id [all_pfouls]

gs_pfoul <- intersect(warplayer_ros, player_pfouls)

#filters sample data into team

gspfoul_freq <- table(gs_pfoul)

#shows how many personal fouls per player from a particular team

gspfoul_freq

#displays the personal fouls per playersas.data.frame(table(gs_pfoul))

as.data.frame(table(gs_pfoul))

#formats the frequency table

gs_nonpfoul <- setdiff(warplayer_ros, gs_pfoul)

#shows players with no personal fouls

gspfoul_f <- as.data.frame(table(gs_pfoul))

gsppfoul_f <- gspfoul_f[,2]

#pulls frequency from data set

gspfouldata <- cbind(gs_pfoul, gsppfoul_f)

#players with personal fouls and the frequency

gsnonpfouldata <-cbind(gs_nonpfoul, 0)

#players with no personal fouls

goldspfouldata <- rbind(gspfouldata, gsnonpfouldata)

goldspfouldata

#combines the rows of all the players and their personal fouls

 

#P. FOULS DATA FOR CLEVELAND CAVALIERS

cld_pfoul <- intersect(cavsplayer_ros, player_pfouls)

#filters sample data into team

cldpfoul_freq <- table(cld_pfoul)

#shows how many personal fouls per player from a particular team

cldpfoul_freq

#displays the personal fouls per playersas.data.frame(table(cld_pfoul))

as.data.frame(table(cld_pfoul))

#formats the frequency table

cld_nonpfoul <- setdiff(cavsplayer_ros, cld_pfoul)

#shows players with no personal fouls

cldpfoul_f <- as.data.frame(table(cld_pfoul))

cldppfoul_f <- cldpfoul_f[,2]

#pulls frequency from data set

cldpfouldata <- cbind(cld_pfoul, cldppfoul_f)

#players with personal fouls and the frequency

cldnonpfouldata <-cbind(cld_nonpfoul, 0)

#players with no personal fouls

clevpfouldata <- rbind(cldpfouldata, cldnonpfouldata)

clevpfouldata

#combines the rows of all the players and their personal fouls

 

#GOLDEN STATE DEFENSIVE SLOPPINESS DATA

goldenstate_defslop <- cbind(gsblockdata,gsstealdata,goldspfouldata)

goldenstate_defslop

 

#CLEVELAND DEFENSIVE SLOPPINESS DATA

cleveland_defslop <- cbind(cldblockdata, cldstealdata,clevpfouldata)

cleveland_defslop

 

Advertisements