<repo_name>velaraptor/nba_mvp_metric<file_sep>/README.md
NBA MVP Metric
==============
By <NAME> and <NAME>

Introduction
===============
At the end of each season, the National Basketball Association designates the most valuable player
(MVP) based on a voting system whereby broadcasters and journalists rank the ﬁve best performing players. Points are then assigned inversely with rank for each ballot cast. The rank-point
equivalencies are as follows:

<b><center>rank for a given ballot points</b>

1st 10

2nd 7

3rd 5

4th 3

5th 1
</b></center>
The award is given to the player receiving the most points.
In recent years, the MVP has been the subject of much criticism from fans and sports commenta-
tors. Wrote Fansided writer <NAME>: “The NBA fails to concretely deﬁne the criteria for the
Maurice Podoloﬀ Trophy winner. The only criterion is that the MVP is awarded annually to the
’most valuable player.’ Value is not deﬁned. Scope is not limited.” Many have also claimed that
the award has become a function of player popularity and media attention rather than performance.
To investigate voting behavior, we examine historical data from 1986-2012, looking at metrics in
several areas: player age, position, individual performance, contribution in the context of a team
and salary. We assume here that player salary functions as a proxy variable for understanding
popularity and overall market demand for a particular player. We narrow our focus to the sub-
set of players receiving positive point counts (typically a handful of players each season). Our
question of interest can then be distilled to: “Among the top-performing players, which character-
istics best predict total points?” Data pertaining to basketball metrics, player age, position and
MVP voting was drawn from www.basketball-reference.com. Player salary data was taken from
www.eskimo.com/~pbender.

Two seasons of data (1998-1999 and 2011-2012) were excluded from our analysis as player negotia-
tions prevented completion of these seasons’ games. The 1987-1988 and 1990-1991 seasons were also
excluded as player salary data could not be found. Total point counts per player were normalized
by the total number of points available since the total number of ballots cast diﬀers from year to
year, giving a response variable that can be interpreted as the proportion of the vote captured by a
particular player. Player salaries were normalized by the cumulative league salary for the particular
year to account for inﬂation.

After aggregating all of the positive point-receiving players over 23 seasons we are left with a sample
size of n = 374. This method makes two important assumptions. The ﬁrst is that the tastes and
preferences of the sports commentariat are roughly stable over time. To check the validity of this
assumption, we will examine models for both the full 23 seasons as well as for the most recent 10
seasons (n = 166). The second assumption is that the joint distribution of the covariates for players
in the running for MVP are independent from year to year. This assumption becomes important
as there are many recurring players in our sample.

Page with our results can be seen at http://velaraptor.github.io/nba_mvp_metric/



<b>Explanation of Variables:</b>

PER -- Player Efficiency Rating; a measure of per-minute production standardized such that the league average is 15

TS% -- True Shooting Percentage; a measure of shooting effeciency that takes into account 2-point field goals, 3-point field goals, and free throws

eFG% -- Effective Field Goal Percentage; this statistic adjusts for the fact that a 3-point field goal is worth one more point than a 2-point field goal

FTr -- Free Throw Attempt Rate-Number of FT Attempts Per FG Attempt

3PAr -- 3-Point Attempt Rate-Percentage of FG Attempts from 3-Point Range

ORB% -- Offensive Rebound Percentage; an estimate of the percentage of available offensive rebounds a player grabbed while he was on the floor

DRB% -- Defensive Rebound Percentage; an estimate of the percentage of available defensive rebounds a player grabbed while he was on the floor

TRB% -- Total Rebound Percentage; an estimate of the percentage of available rebounds a player grabbed while he was on the floor

AST% -- Assist Percentage; an estimate of the percentage of teammate field goals a player assisted while he was on the floor

STL% -- Steal Percentage; an estimate of the percentage of opponent possessions that end with a steal by the player while he was on the floor

BLK% -- Block Percentage; an estimate of the percentage of opponent two-point field goal attempts blocked by the player while he was on the floor

TOV% -- Turnover Percentage; an estimate of turnovers per 100 plays

USG% -- Usage Percentage; an estimate of the percentage of team plays used by a player while he was on the floor

ORtg -- Offensive Rating: An estimate of points produced (players) or scored (teams) per 100 possession

DRtg -- Defensive Rating: An estimate of points allowed per 100 possessions

OWS -- Offensive Win Shares; an estimate of the number of wins contributed by a player due to his offense

DWS -- Defensive Win Shares; an estimate of the number of wins contributed by a player due to his defense

WS -- Win Shares; an estimate of the number of wins contributed by a player

WS/48 -- Win Shares Per 48 Minutes; an estimate of the number of wins contributed by a player per 48 minutes (league average is approximately .100)

Copyright 2014 <NAME> & <NAME>


<file_sep>/full data tables by year/cleantomvp.R
a<-read.csv("1980.csv")
b<-read.csv("1981.csv")
c<-read.csv("1982.csv")
d<-read.csv("1983.csv")
e<-read.csv("1984.csv")
f<-read.csv("1985.csv")
g<-read.csv("1986.csv")
h<-read.csv("1987.csv")
i<-read.csv("1988.csv")
j<-read.csv("1989.csv")
k<-read.csv("1990.csv")
l<-read.csv("1991.csv")
m<-read.csv("1992.csv")
n<-read.csv("1993.csv")
o<-read.csv("1994.csv")
p<-read.csv("1995.csv")
q<-read.csv("1996.csv")
r<-read.csv("1998.csv")
s<-read.csv("2000.csv")
t<-read.csv("2001.csv")
u<-read.csv("2002.csv")
v<-read.csv("2003.csv")
w<-read.csv("2004.csv")
x<-read.csv("2005.csv")
y<-read.csv("2006.csv")
z<-read.csv("2007.csv")
aa<-read.csv("2008.csv")
ab<-read.csv("2009.csv")
ac<-read.csv("2010.csv")
ad<-read.csv("2011.csv")
a.1<-a[!(a$Pts.Won==0),]
b.1<-b[!(b$Pts.Won==0),]
c.1<-c[!(c$Pts.Won==0),]
d.1<-d[!(d$Pts.Won==0),]
e.1<-e[!(e$Pts.Won==0),]
f.1<-f[!(f$Pts.Won==0),]
g.1<-g[!(g$Pts.Won==0),]
h.1<-h[!(h$Pts.Won==0),]
i.1<-i[!(i$Pts.Won==0),]
j.1<-j[!(j$Pts.Won==0),]
k.1<-k[!(k$Pts.Won==0),]
l.1<-l[!(l$Pts.Won==0),]
m.1<-m[!(m$Pts.Won==0),]
n.1<-n[!(n$Pts.Won==0),]
o.1<-o[!(o$Pts.Won==0),]
p.1<-p[!(p$Pts.Won==0),]
q.1<-q[!(q$Pts.Won==0),]
r.1<-r[!(r$Pts.Won==0),]
s.1<-s[!(s$Pts.Won==0),]
t.1<-t[!(t$Pts.Won==0),]
u.1<-u[!(u$Pts.Won==0),]
v.1<-v[!(v$Pts.Won==0),]
w.1<-w[!(w$Pts.Won==0),]
x.1<-x[!(x$Pts.Won==0),]
y.1<-y[!(y$Pts.Won==0),]
z.1<-z[!(z$Pts.Won==0),]
aa.1<-aa[!(aa$Pts.Won==0),]
ab.1<-ab[!(ab$Pts.Won==0),]
ac.1<-ac[!(ac$Pts.Won==0),]
ad.1<-ad[!(ad$Pts.Won==0),]

a.1$Pts.Won<-a.1$Pts.Won/sum(a.1$Pts.Won)
b.1$Pts.Won<-b.1$Pts.Won/sum(b.1$Pts.Won)
c.1$Pts.Won<-c.1$Pts.Won/sum(c.1$Pts.Won)
d.1$Pts.Won<-d.1$Pts.Won/sum(d.1$Pts.Won)
e.1$Pts.Won<-e.1$Pts.Won/sum(e.1$Pts.Won)
f.1$Pts.Won<-f.1$Pts.Won/sum(f.1$Pts.Won)
g.1$Pts.Won<-g.1$Pts.Won/sum(g.1$Pts.Won)
h.1$Pts.Won<-h.1$Pts.Won/sum(h.1$Pts.Won)
i.1$Pts.Won<-i.1$Pts.Won/sum(i.1$Pts.Won)
j.1$Pts.Won<-j.1$Pts.Won/sum(j.1$Pts.Won)
k.1$Pts.Won<-k.1$Pts.Won/sum(k.1$Pts.Won)
l.1$Pts.Won<-l.1$Pts.Won/sum(l.1$Pts.Won)
m.1$Pts.Won<-m.1$Pts.Won/sum(m.1$Pts.Won)
n.1$Pts.Won<-n.1$Pts.Won/sum(n.1$Pts.Won)
o.1$Pts.Won<-o.1$Pts.Won/sum(o.1$Pts.Won)
p.1$Pts.Won<-p.1$Pts.Won/sum(p.1$Pts.Won)
q.1$Pts.Won<-q.1$Pts.Won/sum(q.1$Pts.Won)
r.1$Pts.Won<-r.1$Pts.Won/sum(r.1$Pts.Won)
s.1$Pts.Won<-s.1$Pts.Won/sum(s.1$Pts.Won)
t.1$Pts.Won<-t.1$Pts.Won/sum(t.1$Pts.Won)
u.1$Pts.Won<-u.1$Pts.Won/sum(u.1$Pts.Won)
v.1$Pts.Won<-v.1$Pts.Won/sum(v.1$Pts.Won)
w.1$Pts.Won<-w.1$Pts.Won/sum(w.1$Pts.Won)
x.1$Pts.Won<-x.1$Pts.Won/sum(x.1$Pts.Won)
y.1$Pts.Won<-y.1$Pts.Won/sum(y.1$Pts.Won)
z.1$Pts.Won<-z.1$Pts.Won/sum(z.1$Pts.Won)
aa.1$Pts.Won<-aa.1$Pts.Won/sum(aa.1$Pts.Won)
ab.1$Pts.Won<-ab.1$Pts.Won/sum(ab.1$Pts.Won)
ac.1$Pts.Won<-ac.1$Pts.Won/sum(ac.1$Pts.Won)
ad.1$Pts.Won<-ad.1$Pts.Won/sum(ad.1$Pts.Won)





salary<-file.path("http://www.eskimo.com/~pbender/misc",c("salaries86.txt","salaries88.txt","salaries89.txt","salaries91.txt","salaries92.txt","salaries93.txt","salaries94.txt","salaries95.txt","salaries96.txt","salaries97.txt","salaries98.txt","salaries00.txt","salaries01.txt","salaries02.txt","salaries03.txt","salaries04.txt","salaries05.txt","salaries06.txt","salaries07.txt","salaries08.txt","salaries09.txt","salaries10.txt","salaries11.txt"))
salary.1<-lapply(salary,readHTMLTable)








grandtotalmvp<-rbind(g.1,i.1,j.1,l.1,m.1,n.1,o.1,p.1,q.1,r.1,s.1,t.1,u.1,v.1,w.1,x.1,y.1,z.1,aa.1,ab.1,ac.1,ad.1)
grandtotalmvp$totals.Rk<-NULL
grandtotalmvp$First<-NULL
write.csv(grandtotalmvp,file="grandtotalmvp_1.csv")


tenyear<-rbind(t.1,u.1,v.1,w.1,x.1,y.1,z.1,aa.1,ab.1,ac.1,ad.1)
tenyear$totals.Rk<-NULL
tenyear$First<-NULL
write.csv(tenyear,file="tenyearmvp_1.csv")


ridge regression and lasso


l.1<file_sep>/2013_data_code/2013_data.R
library(XML)
library(MASS)
thir<-readHTMLTable("http://www.basketball-reference.com/leagues/NBA_2014_totals.html")
thir.1<-as.data.frame(thir)
thir.adv<-readHTMLTable("http://www.basketball-reference.com/leagues/NBA_2014_advanced.html")
thir.adv.1<-as.data.frame(thir.adv)
change.num.totals<-function(list){
	team<-list;
	for( i in c(4,6:length(team))){
		team[,i]<-as.character(team[,i]);
		team[,i]<-as.numeric(team[,i]);	
	}
	return(team)
}

change.num.advanced<-function(list){
	team<-list;
	for( i in c(4,6:length(team))){
		team[,i]<-as.character(team[,i]);
		team[,i]<-as.numeric(team[,i]);	
	}
	return(team)
}
thir.1.totals<-change.num.totals(thir.1)
thir.1.adv<-change.num.advanced(thir.adv.1)
delete.row<-function(list){
	team<-list;
	team.1<-team[-grep("Player",team[,2]),]
	return(team.1)
}
thir.1.totals<-delete.row(thir.1.totals)
thir.1.adv<-delete.row(thir.1.adv)
has.star<-function(list){
	team<-list;
	team[,2]<-as.character(team[,2]);
	check.star<-grep("\\*$",team[,2]);
	team[check.star,2]<-gsub("\\*$","",team[check.star,2]);
	return(team);
}
has.multiple.entry<-function(list){
	team<-list;
	team<-team[!duplicated(team[,2]),];
	return(team);	
}
thir.1.totals<-has.star(thir.1.totals)
thir.1.totals<-has.multiple.entry(thir.1.totals)
thir.1.adv<-has.star(thir.1.adv)
thir.1.adv<-has.multiple.entry(thir.1.adv)
nba_2013<-merge(thir.1.totals,thir.1.adv,by.x="totals.Player",by.y="advanced.Player")
fix.columns.ndf<-function(list){
 	x<-list;
 	x<-data.frame(x,0);
 	colnames(x)[55]<-"Pts.Won";
 	colnames(x)[1]<-"Player";
 	x$totals.Rk<-NULL;
 	x$advanced.Rk<-NULL;
 	x$advanced.Pos<-NULL;
 	x$advanced.Age<-NULL;
 	x$advanced.Tm<-NULL;
 	x$advanced.G<-NULL;
 	x$advanced.MP<-NULL;
	return(x);
}
nba_2013<-fix.columns.ndf(nba_2013)
write.csv(nba_2013,file="nba_2013.csv")







salary<-file.path("http://hoopshype.com/salaries",c("brooklyn.htm","atlanta.htm","boston.htm","charlotte.htm","chicago.htm","cleveland.htm","dallas.htm","denver.htm","detroit.htm","golden_state.htm","houston.htm","indiana.htm","la_clippers.htm","la_lakers.htm","memphis.htm","miami.htm","milwaukee.htm","minnesota.htm","new_orleans.htm","new_york.htm","oklahoma_city.htm","orlando.htm","philadelphia.htm","phoenix.htm","portland.htm","sacramento.htm","san_antonio.htm","toronto.htm","utah.htm","washington.htm"))
sal<-lapply(salary,readHTMLTable)
names.extract<-function(list){
	newlist<-list(0)
	for(i in 1:30){
		names(list[[i]])<-c("a","b","c","d","e","f","sal")
	}
	for(i in 1:30){
		newlist[[i]]<-list[[i]]$sal
	}
	return(newlist)
}
sal.1<-names.extract(sal)
s<-lapply(sal.1,as.data.frame)
df<-ldply(s,data.frame)
df<-df[,1:2]
delete.row<-function(list){
	team<-list;
	team.1<-team[-grep("Player",team[,1]),]
	return(team.1)
}
df.1<-delete.row(df)
df.1[,1]<-as.character(df.1[,1])
df.1[570,1]<-"Nene"

empty.delete.row<-function(data){
	team<-data;
	team.1<-team[-grep("^$",team[,1]),]
	return(team.1)
}
df.2<-empty.delete.row(df.1)
empty<-function(data){
	team<-data;
	team.1<-team[-grep("Â",team[,2]),]
	return(team.1)
}
df.3<-empty(df.2)
delete.money<-function(data){
	team<-data;
	team[,2]<-as.character(team[,2]);
	check.money<-grep("[[:punct:]]",team[,2]);
	team[check.money,2]<-gsub("[[:punct:]]","",team[check.money,2]);
	return(team)
}
df.3<-delete.money(df.3)
df.3[,2]<-as.numeric(df.3[,2])
total<-df.3[df.3$V1=="TOTALS:",2]
sum.total<-sum(total)
empty.totals<-function(data){
	team<-data;
	team.1<-team[-grep("TOTALS:",team[,1]),]
	return(team.1)	
}
df.3<-empty.totals(df.3)
names(df.3)[2]<-"Salary"
df.3$Salary<-df.3$Salary/sum.total
nba_2013.1<-merge(nba_2013,df.3,by.x="Player",by.y="V1")
fitforward<-lm(Pts.Won ~ advanced.WS + Salary + advanced.USG. + 
    totals.FT + advanced.TOV. + advanced.TS. + totals.PF + advanced.AST. + 
    totals.FG + totals.MP + advanced.PER + totals.TOV + advanced.STL. + 
    totals.PTS,data=mvp)
    
 nba_2014<-nba_2013.1[nba_2013.1$totals.G>=76,]   
 nba_2014[is.na(nba_2014)]<-0
 pre<-predict(fitforward,newdata=nba_2014)
 m<-data.frame(nba_2014$Player,nba_2014$totals.G,pre)
 top.order<-order(m[,3],decreasing=T)
 m[top.order,]  
