Skip to content

Instantly share code, notes, and snippets.

@EvanZ
Created February 23, 2015 21:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EvanZ/f7d44b9906e4275e6f39 to your computer and use it in GitHub Desktop.
Save EvanZ/f7d44b9906e4275e6f39 to your computer and use it in GitHub Desktop.
RAPM tutorial
{
"metadata": {
"name": "",
"signature": "sha256:6cf5e55848c6c232fce1d5c6998ffc60f2100df93baac87ca4555267751148fa"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"Regularized +/- (RAPM) in Python using scikit-learn"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First thing we do is import matchup data. My nbawowy data is stored in a MongoDB collection which has a \"document\" (i.e. JSON object) for each \"stint\" in a game. A stint is defined as a series of possessions in between player substitutions. Every time a player (or more than one) is subbed into the game, a new stint is created. For this tutorial I'll be working with data from last season (2013-14)."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import json # a built-in Python module for dealing with JSON data\n",
"data = [] # create an empty array to hold all the stints\n",
"# open the file and read the data!\n",
"with open('/Users/evanzamir/PycharmProjects/sklearn_tutorial/matchups2014.json') as units_file:\n",
" for j in units_file:\n",
" data.append(json.loads(j)) "
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 365
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# \"pretty\" print the first stint, which in this case describes a matchup in a CHA-MIA game last season.\n",
"\n",
"from pprint import pprint\n",
"pprint(data[0]) "
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"{u'Bobcats': {u'entered': [u'Ben Gordon'],\n",
" u'exited': [u'Michael Kidd-Gilchrist'],\n",
" u'on': [u'Kemba Walker',\n",
" u'Ben Gordon',\n",
" u'Gerald Henderson',\n",
" u'Josh McRoberts',\n",
" u'Al Jefferson'],\n",
" u'stats': {u'dreb': 0,\n",
" u'drebx': 0,\n",
" u'fg2m': 1,\n",
" u'fg3m': 0,\n",
" u'fgm': 1,\n",
" u'fgx': 0,\n",
" u'foul': 1,\n",
" u'fta': 2,\n",
" u'ftm': 2,\n",
" u'non_steal_tov': 0,\n",
" u'oreb': 0,\n",
" u'orebx': 0,\n",
" u'poss': 1,\n",
" u'pts': 4,\n",
" u'team_tov': 0,\n",
" u'time': 0,\n",
" u'tov': 0}},\n",
" u'Heat': {u'entered': [],\n",
" u'exited': [],\n",
" u'on': [u'Norris Cole',\n",
" u'Mario Chalmers',\n",
" u'Dwyane Wade',\n",
" u'LeBron James',\n",
" u'Chris Bosh'],\n",
" u'stats': {u'dreb': 0,\n",
" u'drebx': 0,\n",
" u'fg2m': 0,\n",
" u'fg3m': 0,\n",
" u'fgm': 0,\n",
" u'fgx': 0,\n",
" u'foul': 1,\n",
" u'fta': 2,\n",
" u'ftm': 2,\n",
" u'non_steal_tov': 0,\n",
" u'oreb': 0,\n",
" u'orebx': 0,\n",
" u'poss': 1,\n",
" u'pts': 2,\n",
" u'team_tov': 0,\n",
" u'time': 0,\n",
" u'tov': 0}},\n",
" u'_id': {u'$oid': u'5353245a5bca6d5652001dd1'},\n",
" u'as': 97,\n",
" u'away': u'Bobcats',\n",
" u'date': u'2013-12-01',\n",
" u'end': u'0:01',\n",
" u'espn_id': u'400489125',\n",
" u'home': u'Heat',\n",
" u'hs': 99,\n",
" u'mid': 5,\n",
" u'plays': [{u'id': {u'$oid': u'5353189f5bca6d54dd01c27b'}},\n",
" {u'id': {u'$oid': u'5353189f5bca6d54dd01c27c'}},\n",
" {u'id': {u'$oid': u'5353189f5bca6d54dd01c27d'}},\n",
" {u'id': {u'$oid': u'5353189f5bca6d54dd01c27e'}},\n",
" {u'id': {u'$oid': u'5353189f5bca6d54dd01c27f'}},\n",
" {u'id': {u'$oid': u'5353189f5bca6d54dd01c280'}},\n",
" {u'id': {u'$oid': u'5353189f5bca6d54dd01c281'}},\n",
" {u'id': {u'$oid': u'5353189f5bca6d54dd01c282'}},\n",
" {u'id': {u'$oid': u'5353189f5bca6d54dd01c283'}}],\n",
" u'q': 4,\n",
" u'season': u'2014',\n",
" u'start': u'0:12',\n",
" u'time': 11,\n",
" u'url': u'http://scores.nbcsports.msnbc.com/nba/pbp.asp?gamecode=2013120114'}\n"
]
}
],
"prompt_number": 374
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can see there's a ton of data even for one stint. The main things we care about are the players in the 'on' and 'off' arrays under each team, the possessions (.stats.poss) and the points scored during the stint ('.stats.pts')."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To compute RAPM we'll be using a very popular machine learning toolkit in Python called scikit-learn (abbreviated sklearn). Within sklearn there are many different ML algorithms. RAPM uses a technique called Ridge Regression. But before we get to that, we will want to look at some \"helper\" functions that will be useful in transforming our stint data to a form that sklearn requires."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First we will import a class called DictVectorizer which transforms a list of arrays into a list of Python dictionaries (\"dicts\" in Python or \"hashes\" or \"maps\" in other languages). In our stint objects there is an array containing the 5 players on the court for each team. When we do the regression, we will actually want to create a much larger array containing as many columns as there are players in the league (around 480 or so). *DictVectorizer* will help us do that quite easily as shown below."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# To demonstrate how DictVectorizer works...\n",
"# Create a small list of lists with \"fake\" units\n",
"\n",
"units = [['Stephen Curry','Klay Thompson','Harrison Barnes','Draymond Green','Andrew Bogut'],\n",
" ['Stephen Curry','Klay Thompson','Harrison Barnes','Draymond Green','Andrew Bogut'],\n",
" ['Shaun Livingston','Klay Thompson','Harrison Barnes','Draymond Green','Andrew Bogut'],\n",
" ['Shaun Livingston','Klay Thompson','Andre Iguodala','Draymond Green','Andrew Bogut'],\n",
" ['Leandro Barbosa','Shaun Livingston','Andre Iguodala','Harrison Barnes','Draymond Green']]\n",
"\n",
"from sklearn.feature_extraction import DictVectorizer\n",
"v = DictVectorizer(sparse=False)\n",
"list_dicts = []\n",
"\n",
"# For each unit we want to create a dict containing the players' names as keys and the value 1 as the value.\n",
"# Later the value will be +1 if the player is playing at home and -1 if he is away.\n",
"\n",
"for unit in units:\n",
" list_dicts.append({name: 1 for name in unit})\n",
"print(list_dicts)\n"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[{'Andrew Bogut': 1, 'Klay Thompson': 1, 'Draymond Green': 1, 'Harrison Barnes': 1, 'Stephen Curry': 1}, {'Andrew Bogut': 1, 'Klay Thompson': 1, 'Draymond Green': 1, 'Harrison Barnes': 1, 'Stephen Curry': 1}, {'Klay Thompson': 1, 'Andrew Bogut': 1, 'Shaun Livingston': 1, 'Draymond Green': 1, 'Harrison Barnes': 1}, {'Klay Thompson': 1, 'Andrew Bogut': 1, 'Shaun Livingston': 1, 'Draymond Green': 1, 'Andre Iguodala': 1}, {'Shaun Livingston': 1, 'Leandro Barbosa': 1, 'Harrison Barnes': 1, 'Andre Iguodala': 1, 'Draymond Green': 1}]\n"
]
}
],
"prompt_number": 368
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# This is where magic happens.\n",
"# The function fit_transform has turned our list of dicts into a list of arrays containing enough columns\n",
"# for all the players in this fake data set.\n",
"# The variable v, an instance of DictVectorizer, is able to keep track of all this bookkeeping for us.\n",
"# Basically, it's a really useful thing to have for what we're about to do and eliminates\n",
"# writing a metric ton of our own code.\n",
"\n",
"X = v.fit_transform(list_dicts)\n",
"print(X)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[[ 0. 1. 1. 1. 1. 0. 0. 1.]\n",
" [ 0. 1. 1. 1. 1. 0. 0. 1.]\n",
" [ 0. 1. 1. 1. 1. 0. 1. 0.]\n",
" [ 1. 1. 1. 0. 1. 0. 1. 0.]\n",
" [ 1. 0. 1. 1. 0. 1. 1. 0.]]\n"
]
}
],
"prompt_number": 370
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# We can even take the inverse transform and get back the list of dicts!\n",
"\n",
"x = v.inverse_transform(X)\n",
"print(x)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[{'Klay Thompson': 1.0, 'Andrew Bogut': 1.0, 'Draymond Green': 1.0, 'Harrison Barnes': 1.0, 'Stephen Curry': 1.0}, {'Klay Thompson': 1.0, 'Andrew Bogut': 1.0, 'Draymond Green': 1.0, 'Harrison Barnes': 1.0, 'Stephen Curry': 1.0}, {'Klay Thompson': 1.0, 'Shaun Livingston': 1.0, 'Andrew Bogut': 1.0, 'Draymond Green': 1.0, 'Harrison Barnes': 1.0}, {'Klay Thompson': 1.0, 'Shaun Livingston': 1.0, 'Andrew Bogut': 1.0, 'Draymond Green': 1.0, 'Andre Iguodala': 1.0}, {'Shaun Livingston': 1.0, 'Harrison Barnes': 1.0, 'Leandro Barbosa': 1.0, 'Draymond Green': 1.0, 'Andre Iguodala': 1.0}]\n"
]
}
],
"prompt_number": 371
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# And we can easily get the names of all the players in the data set!\n",
"# W00t\n",
"\n",
"print(v.get_feature_names())"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"['Andre Iguodala', 'Andrew Bogut', 'Draymond Green', 'Harrison Barnes', 'Klay Thompson', 'Leandro Barbosa', 'Shaun Livingston', 'Stephen Curry']\n"
]
}
],
"prompt_number": 372
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we're going to iterate through our matchup **data** and create three variables: 1) **units** is a list of dicts of the home and away players for each stint with a +1/-1 indicating which side they are on; 2) **points** is a list containing the point differential (normalized to 100 possessions) for each stint; 3) **weights** is simply the number of possessions for each stint."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"units = []\n",
"points = []\n",
"weights = []\n",
"\n",
"for d in data:\n",
" home = d['home']\n",
" away = d['away']\n",
" home_poss = d[home]['stats']['poss']\n",
" away_poss = d[away]['stats']['poss']\n",
" point_diff = 100*(d[home]['stats']['pts']-d[away]['stats']['pts'])/((home_poss+away_poss+0.01)/2.)\n",
" home_unit = {name:1 for name in d[home]['on']}\n",
" away_unit = {name:-1 for name in d[away]['on']}\n",
" stint = home_unit.copy()\n",
" stint.update(away_unit)\n",
" if (home_poss+away_poss) >= 2: # to avoid some ill-conditioning we only use stints that have possessions >= 1\n",
" units.append(stint)\n",
" points.append(point_diff)\n",
" weights.append((home_poss+away_poss)/2.)\n",
"print(len(units),len(points),len(weights))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"(32927, 32927, 32927)\n"
]
}
],
"prompt_number": 375
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Now we employ DictVectorizer to do its magic\n",
"\n",
"u = DictVectorizer(sparse=False)\n",
"u_mat = u.fit_transform(units)\n",
"print(u_mat) # a giant list of lists where each array contains five +1's, five -1's, and a whole mess of 0's\n",
"print(points[:25]) # just showing the first 25 stints\n",
"print(weights[:100]) # just showing the first 100 stints"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[[ 0. 0. 0. ..., 0. 0. 0.]\n",
" [ 0. 0. 0. ..., 0. 0. 0.]\n",
" [ 0. 0. 0. ..., 0. 0. 0.]\n",
" ..., \n",
" [ 0. 0. 0. ..., 0. 0. 0.]\n",
" [ 0. 0. 0. ..., 0. 0. 0.]\n",
" [ 0. 0. 0. ..., 0. 0. 0.]]\n",
"[-199.00497512437812, -42.82655246252677, -92.23674096848578, -99.50248756218906, 44.39511653718091, 44.39511653718091, -76.86395080707149, 66.59267480577137, 239.52095808383234, 72.66121707538602, 66.55574043261231, -66.44518272425249, -24.984384759525295, 99.50248756218906, -16.65278934221482, -22.197558268590456, -132.89036544850498, -99.87515605493134, 66.44518272425249, 0.0, -99.87515605493134, 0.0, 99.75062344139651, 39.920159680638726, 99.50248756218906]\n",
"[1.0, 7.0, 6.5, 1.0, 4.5, 4.5, 6.5, 4.5, 2.5, 5.5, 3.0, 1.5, 8.0, 1.0, 6.0, 4.5, 1.5, 4.0, 1.5, 1.0, 4.0, 1.0, 2.0, 2.5, 1.0, 1.5, 5.5, 4.5, 1.0, 4.5, 8.0, 4.0, 2.0, 1.0, 1.5, 3.0, 6.0, 5.0, 2.5, 2.5, 6.0, 9.0, 1.0, 4.0, 4.0, 6.5, 5.0, 3.0, 5.5, 1.5, 2.0, 8.0, 1.5, 2.0, 1.5, 1.0, 1.0, 2.0, 1.0, 3.5, 4.0, 1.0, 6.0, 2.5, 2.0, 2.0, 1.5, 4.0, 3.0, 12.0, 6.0, 2.5, 2.0, 1.5, 8.0, 2.5, 11.0, 11.5, 2.0, 3.0, 4.0, 1.5, 2.5, 1.0, 1.0, 1.5, 2.5, 2.0, 4.0, 2.5, 1.0, 2.0, 1.5, 4.5, 1.5, 1.0, 2.0, 4.0, 5.5, 3.0]\n"
]
}
],
"prompt_number": 376
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# The first 25 players alphabetically in the data set\n",
"\n",
"pprint(u.get_feature_names()[:25])"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[u'A.J. Price',\n",
" u'Aaron Brooks',\n",
" u'Aaron Gray',\n",
" u'Adonis Thomas',\n",
" u'Al Harrington',\n",
" u'Al Horford',\n",
" u'Al Jefferson',\n",
" u'Al-Farouq Aminu',\n",
" u'Alan Anderson',\n",
" u'Alec Burks',\n",
" u'Alex Len',\n",
" u'Alexey Shved',\n",
" u'Alexis Ajinca',\n",
" u'Allen Crabbe',\n",
" u'Alonzo Gee',\n",
" u\"Amar'e Stoudemire\",\n",
" u'Amir Johnson',\n",
" u'Anderson Varejao',\n",
" u'Andray Blatche',\n",
" u'Andre Drummond',\n",
" u'Andre Iguodala',\n",
" u'Andre Miller',\n",
" u'Andre Roberson',\n",
" u'Andrea Bargnani',\n",
" u'Andrei Kirilenko']\n"
]
}
],
"prompt_number": 377
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# perform the inverse transform on one stint just to double check it makes sense\n",
"\n",
"pprint(u.inverse_transform(u_mat)[:1])"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"[{u'Al Jefferson': -1.0,\n",
" u'Ben Gordon': -1.0,\n",
" u'Chris Bosh': 1.0,\n",
" u'Dwyane Wade': 1.0,\n",
" u'Gerald Henderson': -1.0,\n",
" u'Josh McRoberts': -1.0,\n",
" u'Kemba Walker': -1.0,\n",
" u'LeBron James': 1.0,\n",
" u'Mario Chalmers': 1.0,\n",
" u'Norris Cole': 1.0}]\n"
]
}
],
"prompt_number": 378
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now the fun stuff begins! We import the **linear_model** class and use the function **RidgeCV** to perform ridge regression on our data set using five-fold cross validation. Briefly, the idea here is to pick the optimal value of *alpha* for regularizing the data (i.e. so it fits the data best)."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from sklearn import linear_model\n",
"clf = linear_model.RidgeCV(alphas=(numpy.array([0.01,0.1,1.0,10,100,500,1000,2000,5000])),cv=5)\n",
"clf.fit(u_mat,points,sample_weight=weights)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 333,
"text": [
"RidgeCV(alphas=array([ 1.00000e-02, 1.00000e-01, 1.00000e+00, 1.00000e+01,\n",
" 1.00000e+02, 5.00000e+02, 1.00000e+03, 2.00000e+03,\n",
" 5.00000e+03]),\n",
" cv=5, fit_intercept=True, gcv_mode=None, loss_func=None,\n",
" normalize=False, score_func=None, scoring=None, store_cv_values=False)"
]
}
],
"prompt_number": 333
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Here is the value of alpha that RidgeCV selected. We could probably add a few more values to test above too...\n",
"# but this is just a tutorial :)\n",
"\n",
"print(clf.alpha_)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1000.0\n"
]
}
],
"prompt_number": 379
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we want to get the coefficients that RidgeCV found for our \"optimal\" solution. The coefficients for each player are contained in an attribute of the class called **coef_**. "
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"ratings = []\n",
"for player in players:\n",
" ratings.append((player,clf.coef_[players.index(player)]))\n",
"ratings.sort(key=lambda tup: tup[1],reverse=True) # sort by rating in descending order"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 380
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And here are the ratings! Now, remember this is for one season of data. The ratings are obviously quite noisy. And that's why it is often not very useful to look at just one season of data. But this is enough to give you the basic idea of how it's done."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"for idx, rating in enumerate(ratings):\n",
" print(idx+1, \"{}\".format(rating[0]), \"{0:.2f}\".format(rating[1]))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"(1, 'Jae Crowder', '7.63')\n",
"(2, 'Nick Collison', '6.21')\n",
"(3, 'Chris Paul', '5.70')\n",
"(4, 'LeBron James', '5.53')\n",
"(5, 'Stephen Curry', '5.51')\n",
"(6, 'Kevin Durant', '5.44')\n",
"(7, 'Manu Ginobili', '5.25')\n",
"(8, 'Kawhi Leonard', '5.19')\n",
"(9, 'LaMarcus Aldridge', '4.90')\n",
"(10, 'Ricky Rubio', '4.84')\n",
"(11, 'Luol Deng', '4.73')\n",
"(12, 'Channing Frye', '4.67')\n",
"(13, 'Dwight Howard', '4.61')\n",
"(14, 'Kemba Walker', '4.50')\n",
"(15, 'Zach Randolph', '4.35')\n",
"(16, 'Deron Williams', '4.18')\n",
"(17, 'Dirk Nowitzki', '4.15')\n",
"(18, 'Marcin Gortat', '3.93')\n",
"(19, 'Goran Dragic', '3.90')\n",
"(20, 'Kevin Love', '3.88')\n",
"(21, 'Russell Westbrook', '3.86')\n",
"(22, 'DeAndre Jordan', '3.85')\n",
"(23, 'J.J. Redick', '3.70')\n",
"(24, 'James Harden', '3.59')\n",
"(25, 'Patrick Mills', '3.55')\n",
"(26, 'Andre Iguodala', '3.46')\n",
"(27, 'Reggie Jackson', '3.38')\n",
"(28, 'Klay Thompson', '3.34')\n",
"(29, 'David West', '3.29')\n",
"(30, 'James Johnson', '3.22')\n",
"(31, 'Danny Green', '3.19')\n",
"(32, 'Kirk Hinrich', '3.18')\n",
"(33, 'Kyle Lowry', '3.18')\n",
"(34, 'Andre Miller', '3.16')\n",
"(35, 'Roy Hibbert', '3.09')\n",
"(36, 'Carmelo Anthony', '3.06')\n",
"(37, 'Patrick Beverley', '3.06')\n",
"(38, 'Blake Griffin', '3.04')\n",
"(39, 'Paul George', '2.92')\n",
"(40, 'Damian Lillard', '2.91')\n",
"(41, 'Tiago Splitter', '2.88')\n",
"(42, 'Anthony Tolliver', '2.88')\n",
"(43, 'Jeremy Lin', '2.87')\n",
"(44, 'Corey Brewer', '2.83')\n",
"(45, 'Devin Harris', '2.80')\n",
"(46, 'Kenyon Martin', '2.79')\n",
"(47, 'Chris Bosh', '2.79')\n",
"(48, 'James Jones', '2.78')\n",
"(49, 'Nate Robinson', '2.66')\n",
"(50, 'Robbie Hummel', '2.60')\n",
"(51, 'Serge Ibaka', '2.60')\n",
"(52, 'Joakim Noah', '2.53')\n",
"(53, 'Rudy Gay', '2.52')\n",
"(54, 'Amir Johnson', '2.46')\n",
"(55, 'DeMarcus Cousins', '2.44')\n",
"(56, 'Ryan Kelly', '2.41')\n",
"(57, 'Jeff Ayres', '2.37')\n",
"(58, 'Kyle Korver', '2.36')\n",
"(59, 'David Lee', '2.34')\n",
"(60, 'Mario Chalmers', '2.32')\n",
"(61, 'Trevor Ariza', '2.30')\n",
"(62, 'Greivis Vasquez', '2.20')\n",
"(63, 'Josh McRoberts', '2.17')\n",
"(64, 'Draymond Green', '2.16')\n",
"(65, 'Isaiah Thomas', '2.14')\n",
"(66, 'Nikola Pekovic', '2.13')\n",
"(67, 'Tony Allen', '2.13')\n",
"(68, 'Jrue Holiday', '2.12')\n",
"(69, 'Danny Granger', '2.11')\n",
"(70, 'Austin Rivers', '2.10')\n",
"(71, 'Wesley Matthews', '2.10')\n",
"(72, 'Shane Battier', '1.94')\n",
"(73, 'DeMarre Carroll', '1.94')\n",
"(74, 'Avery Bradley', '1.89')\n",
"(75, 'Randy Foye', '1.88')\n",
"(76, 'Iman Shumpert', '1.82')\n",
"(77, 'Tony Parker', '1.82')\n",
"(78, 'Luke Babbitt', '1.81')\n",
"(79, 'Andray Blatche', '1.81')\n",
"(80, 'Taj Gibson', '1.78')\n",
"(81, 'Derek Fisher', '1.77')\n",
"(82, 'Ryan Anderson', '1.73')\n",
"(83, 'Chandler Parsons', '1.71')\n",
"(84, 'Darrell Arthur', '1.71')\n",
"(85, 'Darius Miller', '1.70')\n",
"(86, 'MarShon Brooks', '1.69')\n",
"(87, 'Vince Carter', '1.62')\n",
"(88, 'Mike Conley', '1.60')\n",
"(89, 'Josh Smith', '1.56')\n",
"(90, 'Matt Bonner', '1.53')\n",
"(91, 'Ty Lawson', '1.53')\n",
"(92, 'Al Jefferson', '1.51')\n",
"(93, 'Brandan Wright', '1.49')\n",
"(94, 'Jared Sullinger', '1.48')\n",
"(95, 'Nicolas Batum', '1.47')\n",
"(96, 'Chris Andersen', '1.47')\n",
"(97, 'Patrick Patterson', '1.47')\n",
"(98, 'Greg Monroe', '1.46')\n",
"(99, 'Ed Davis', '1.41')\n",
"(100, 'Anthony Davis', '1.39')\n",
"(101, 'Omri Casspi', '1.38')\n",
"(102, 'Jason Thompson', '1.38')\n",
"(103, 'Robin Lopez', '1.31')\n",
"(104, 'Pero Antic', '1.30')\n",
"(105, 'Andrew Bogut', '1.27')\n",
"(106, 'Michael Carter-Williams', '1.27')\n",
"(107, 'Anthony Morrow', '1.26')\n",
"(108, 'Courtney Lee', '1.23')\n",
"(109, 'P.J. Tucker', '1.22')\n",
"(110, 'Shavlik Randolph', '1.19')\n",
"(111, 'Antawn Jamison', '1.17')\n",
"(112, 'George Hill', '1.15')\n",
"(113, 'Shawne Williams', '1.11')\n",
"(114, 'Luigi Datome', '1.09')\n",
"(115, 'Kendall Marshall', '1.07')\n",
"(116, 'Joe Johnson', '1.04')\n",
"(117, 'Anderson Varejao', '1.03')\n",
"(118, 'C.J. Watson', '1.01')\n",
"(119, 'Nikola Vucevic', '0.99')\n",
"(120, 'Mike Harris', '0.99')\n",
"(121, 'Nate Wolters', '0.99')\n",
"(122, 'Nick Calathes', '0.96')\n",
"(123, 'Chauncey Billups', '0.96')\n",
"(124, 'Tony Mitchell', '0.95')\n",
"(125, 'DeMar DeRozan', '0.94')\n",
"(126, \"Kyle O'Quinn\", '0.93')\n",
"(127, 'Tyler Zeller', '0.93')\n",
"(128, 'Casper Ware', '0.92')\n",
"(129, 'J.R. Smith', '0.91')\n",
"(130, 'Shane Larkin', '0.90')\n",
"(131, 'Ben Gordon', '0.87')\n",
"(132, 'Marvin Williams', '0.85')\n",
"(133, 'Aron Baynes', '0.85')\n",
"(134, 'Kentavious Caldwell-Pope', '0.83')\n",
"(135, 'Al Harrington', '0.81')\n",
"(136, 'Boris Diaw', '0.78')\n",
"(137, 'Rashard Lewis', '0.78')\n",
"(138, 'DeJuan Blair', '0.76')\n",
"(139, 'Dante Cunningham', '0.76')\n",
"(140, 'Khris Middleton', '0.75')\n",
"(141, 'Austin Daye', '0.75')\n",
"(142, 'Troy Daniels', '0.74')\n",
"(143, 'Trey Burke', '0.73')\n",
"(144, 'Lance Stephenson', '0.72')\n",
"(145, 'Dwight Buycks', '0.72')\n",
"(146, 'Tyler Hansbrough', '0.72')\n",
"(147, 'Hedo Turkoglu', '0.72')\n",
"(148, 'Solomon Hill', '0.72')\n",
"(149, 'Kosta Koufos', '0.71')\n",
"(150, 'Lorenzo Brown', '0.70')\n",
"(151, 'Jeremy Lamb', '0.70')\n",
"(152, 'Tyson Chandler', '0.69')\n",
"(153, 'John Wall', '0.69')\n",
"(154, 'A.J. Price', '0.67')\n",
"(155, 'Jameer Nelson', '0.66')\n",
"(156, 'Chris Douglas-Roberts', '0.66')\n",
"(157, 'Josh Childress', '0.65')\n",
"(158, 'Jared Cunningham', '0.63')\n",
"(159, 'Brandon Davies', '0.60')\n",
"(160, 'Kenneth Faried', '0.59')\n",
"(161, 'Doron Lamb', '0.58')\n",
"(162, 'Jeff Adrien', '0.57')\n",
"(163, 'Xavier Henry', '0.56')\n",
"(164, 'Othyus Jeffers', '0.55')\n",
"(165, 'Damion James', '0.53')\n",
"(166, 'Jamaal Franklin', '0.52')\n",
"(167, 'Martell Webster', '0.50')\n",
"(168, \"Toure' Murry\", '0.50')\n",
"(169, 'Al Horford', '0.48')\n",
"(170, 'Vander Blue', '0.47')\n",
"(171, 'Spencer Hawes', '0.45')\n",
"(172, 'Adonis Thomas', '0.45')\n",
"(173, 'Jeff Withey', '0.44')\n",
"(174, 'Rudy Gobert', '0.43')\n",
"(175, 'Marcus Morris', '0.41')\n",
"(176, 'Steve Nash', '0.41')\n",
"(177, 'Steve Novak', '0.40')\n",
"(178, 'JaVale McGee', '0.40')\n",
"(179, 'C.J. Miles', '0.40')\n",
"(180, 'Robert Covington', '0.40')\n",
"(181, 'Nene Hilario', '0.39')\n",
"(182, 'Ryan Gomes', '0.38')\n",
"(183, 'D.J. Augustin', '0.36')\n",
"(184, 'Greg Smith', '0.33')\n",
"(185, 'Keith Bogans', '0.31')\n",
"(186, 'Diante Garrett', '0.30')\n",
"(187, 'Andris Biedrins', '0.29')\n",
"(188, 'Stephen Jackson', '0.27')\n",
"(189, 'Paul Pierce', '0.27')\n",
"(190, 'Jordan Farmar', '0.26')\n",
"(191, 'Kelly Olynyk', '0.21')\n",
"(192, 'Marcus Thornton', '0.21')\n",
"(193, 'Dion Waiters', '0.19')\n",
"(194, 'Pablo Prigioni', '0.19')\n",
"(195, 'Markieff Morris', '0.18')\n",
"(196, 'Eric Bledsoe', '0.18')\n",
"(197, 'Timofey Mozgov', '0.17')\n",
"(198, 'Jonas Valanciunas', '0.16')\n",
"(199, 'Tristan Thompson', '0.14')\n",
"(200, \"Jermaine O'Neal\", '0.12')\n",
"(201, 'Darius Johnson-Odom', '0.11')\n",
"(202, 'Leandro Barbosa', '0.10')\n",
"(203, 'D.J. Stephens', '0.09')\n",
"(204, 'Josh Harrellson', '0.09')\n",
"(205, 'DJ White', '0.09')\n",
"(206, 'Matt Barnes', '0.08')\n",
"(207, 'James Southerland', '0.07')\n",
"(208, 'Ray Allen', '0.07')\n",
"(209, 'DeAndre Liggins', '0.04')\n",
"(210, 'Chris Kaman', '0.03')\n",
"(211, 'Mike James', '0.03')\n",
"(212, 'Mike Dunleavy', '0.03')\n",
"(213, 'Elias Harris', '0.03')\n",
"(214, 'Jeff Teague', '0.02')\n",
"(215, 'Carrick Felix', '0.01')\n",
"(216, 'Marco Belinelli', '-0.00')\n",
"(217, 'Jorge Gutierrez', '-0.01')\n",
"(218, 'Alexis Ajinca', '-0.01')\n",
"(219, 'Chris Copeland', '-0.01')\n",
"(220, 'Scotty Hopson', '-0.01')\n",
"(221, 'Nick Young', '-0.02')\n",
"(222, 'Kobe Bryant', '-0.02')\n",
"(223, 'Brook Lopez', '-0.03')\n",
"(224, 'Bismack Biyombo', '-0.04')\n",
"(225, 'Dexter Pittman', '-0.04')\n",
"(226, 'Arinze Onuaku', '-0.09')\n",
"(227, 'Melvin Ely', '-0.09')\n",
"(228, 'Jeremy Evans', '-0.09')\n",
"(229, 'Jason Terry', '-0.10')\n",
"(230, 'Maalik Wayns', '-0.10')\n",
"(231, 'Chuck Hayes', '-0.12')\n",
"(232, 'Tayshaun Prince', '-0.12')\n",
"(233, 'Josh Powell', '-0.14')\n",
"(234, 'Jason Collins', '-0.14')\n",
"(235, 'Glen Rice Jr.', '-0.14')\n",
"(236, 'Hilton Armstrong', '-0.15')\n",
"(237, 'Tim Duncan', '-0.16')\n",
"(238, 'Monta Ellis', '-0.16')\n",
"(239, 'Royce White', '-0.17')\n",
"(240, 'Kendrick Perkins', '-0.19')\n",
"(241, 'Francisco Garcia', '-0.19')\n",
"(242, 'Al-Farouq Aminu', '-0.19')\n",
"(243, 'Jimmy Butler', '-0.21')\n",
"(244, 'Raymond Felton', '-0.22')\n",
"(245, 'Giannis Antetokounmpo', '-0.22')\n",
"(246, 'Ryan Hollins', '-0.22')\n",
"(247, 'Chris Babb', '-0.22')\n",
"(248, 'Mustafa Shakur', '-0.23')\n",
"(249, 'Thabo Sefolosha', '-0.24')\n",
"(250, 'John Salmons', '-0.25')\n",
"(251, 'Solomon Jones', '-0.26')\n",
"(252, 'Omer Asik', '-0.27')\n",
"(253, 'Chris Smith', '-0.27')\n",
"(254, 'Shaun Livingston', '-0.27')\n",
"(255, 'Aaron Brooks', '-0.28')\n",
"(256, 'Ray McCallum', '-0.28')\n",
"(257, 'Royal Ivey', '-0.29')\n",
"(258, 'James Nunnally', '-0.30')\n",
"(259, 'Gerald Green', '-0.30')\n",
"(260, 'Victor Oladipo', '-0.31')\n",
"(261, 'Kyle Singler', '-0.33')\n",
"(262, 'Shane Edwards', '-0.35')\n",
"(263, 'Reggie Williams', '-0.36')\n",
"(264, 'Ricky Ledo', '-0.36')\n",
"(265, 'Zaza Pachulia', '-0.37')\n",
"(266, 'Brandon Jennings', '-0.38')\n",
"(267, 'Allen Crabbe', '-0.38')\n",
"(268, 'Evan Fournier', '-0.39')\n",
"(269, 'Donatas Motiejunas', '-0.39')\n",
"(270, 'Caron Butler', '-0.40')\n",
"(271, 'Malcolm Thomas', '-0.40')\n",
"(272, 'Hamady Ndiaye', '-0.43')\n",
"(273, 'Sasha Vujacic', '-0.44')\n",
"(274, 'Gorgui Dieng', '-0.46')\n",
"(275, 'Marc Gasol', '-0.46')\n",
"(276, 'Shelvin Mack', '-0.47')\n",
"(277, 'Landry Fields', '-0.49')\n",
"(278, 'Miroslav Raduljica', '-0.50')\n",
"(279, 'Norris Cole', '-0.50')\n",
"(280, 'Bradley Beal', '-0.51')\n",
"(281, 'Brandon Knight', '-0.52')\n",
"(282, 'Paul Millsap', '-0.52')\n",
"(283, 'Matthew Dellavedova', '-0.52')\n",
"(284, 'Carl Landry', '-0.53')\n",
"(285, 'Jeremy Tyler', '-0.53')\n",
"(286, 'Ronnie Price', '-0.54')\n",
"(287, \"E'Twaun Moore\", '-0.54')\n",
"(288, 'Seth Curry', '-0.55')\n",
"(289, 'Kris Humphries', '-0.55')\n",
"(290, 'Manny Harris', '-0.55')\n",
"(291, 'Dionte Christmas', '-0.55')\n",
"(292, 'Pau Gasol', '-0.57')\n",
"(293, 'Jose Calderon', '-0.58')\n",
"(294, 'Shabazz Muhammad', '-0.58')\n",
"(295, 'Kevin Martin', '-0.58')\n",
"(296, 'Ian Clark', '-0.60')\n",
"(297, 'Cole Aldrich', '-0.61')\n",
"(298, 'Gordon Hayward', '-0.61')\n",
"(299, 'Jerryd Bayless', '-0.61')\n",
"(300, 'Jared Dudley', '-0.62')\n",
"(301, 'Ish Smith', '-0.62')\n",
"(302, 'Lance Thomas', '-0.63')\n",
"(303, 'Samuel Dalembert', '-0.63')\n",
"(304, 'Dorell Wright', '-0.64')\n",
"(305, 'Andre Drummond', '-0.64')\n",
"(306, 'Ognjen Kuzmic', '-0.66')\n",
"(307, 'Elton Brand', '-0.66')\n",
"(308, 'Glen Davis', '-0.67')\n",
"(309, 'Chris Johnson', '-0.67')\n",
"(310, 'Jordan Crawford', '-0.68')\n",
"(311, 'Daniel Orton', '-0.69')\n",
"(312, 'Thaddeus Young', '-0.69')\n",
"(313, 'Gerald Henderson', '-0.70')\n",
"(314, 'Willie Green', '-0.70')\n",
"(315, 'Justin Hamilton', '-0.71')\n",
"(316, 'Sergey Karasev', '-0.71')\n",
"(317, 'Drew Gooden', '-0.71')\n",
"(318, 'Andrei Kirilenko', '-0.72')\n",
"(319, 'Arron Afflalo', '-0.73')\n",
"(320, 'Chris Wright', '-0.73')\n",
"(321, 'Reggie Bullock', '-0.74')\n",
"(322, 'John Jenkins', '-0.77')\n",
"(323, 'Ekpe Udoh', '-0.78')\n",
"(324, 'Phil Pressey', '-0.79')\n",
"(325, 'Dwyane Wade', '-0.80')\n",
"(326, 'Terrence Ross', '-0.82')\n",
"(327, 'Jarvis Varnado', '-0.82')\n",
"(328, 'Quincy Miller', '-0.82')\n",
"(329, 'Metta World Peace', '-0.82')\n",
"(330, 'Otto Porter Jr.', '-0.84')\n",
"(331, 'Victor Claver', '-0.85')\n",
"(332, 'Jamaal Tinsley', '-0.85')\n",
"(333, 'Roger Mason Jr.', '-0.86')\n",
"(334, 'Mirza Teletovic', '-0.87')\n",
"(335, 'Wilson Chandler', '-0.88')\n",
"(336, 'Alexey Shved', '-0.91')\n",
"(337, 'Darren Collison', '-0.93')\n",
"(338, 'Arnett Moultrie', '-0.96')\n",
"(339, 'Bernard James', '-0.96')\n",
"(340, 'Joel Freeland', '-0.97')\n",
"(341, 'Jamal Crawford', '-0.98')\n",
"(342, 'Greg Stiemsma', '-0.98')\n",
"(343, 'Hasheem Thabeet', '-1.00')\n",
"(344, 'Alan Anderson', '-1.04')\n",
"(345, 'Terrence Jones', '-1.06')\n",
"(346, 'Nazr Mohammed', '-1.06')\n",
"(347, 'Jimmer Fredette', '-1.07')\n",
"(348, 'Peyton Siva', '-1.08')\n",
"(349, 'Ronny Turiaf', '-1.08')\n",
"(350, 'Louis Amundson', '-1.10')\n",
"(351, 'Tornike Shengelia', '-1.15')\n",
"(352, 'Gal Mekel', '-1.15')\n",
"(353, 'Rodney Stuckey', '-1.17')\n",
"(354, 'Dewayne Dedmon', '-1.18')\n",
"(355, 'Tobias Harris', '-1.19')\n",
"(356, 'Michael Kidd-Gilchrist', '-1.24')\n",
"(357, 'Alex Len', '-1.25')\n",
"(358, 'Ersan Ilyasova', '-1.26')\n",
"(359, 'Miles Plumlee', '-1.26')\n",
"(360, 'Harrison Barnes', '-1.27')\n",
"(361, 'Nando De Colo', '-1.28')\n",
"(362, 'Earl Watson', '-1.28')\n",
"(363, 'J.J. Hickson', '-1.29')\n",
"(364, 'Larry Sanders', '-1.29')\n",
"(365, 'Andrew Nicholson', '-1.34')\n",
"(366, 'James Anderson', '-1.34')\n",
"(367, 'Marquis Teague', '-1.34')\n",
"(368, 'Jason Maxiell', '-1.35')\n",
"(369, 'Andre Roberson', '-1.36')\n",
"(370, 'Nemanja Nedovic', '-1.36')\n",
"(371, 'Derrick Rose', '-1.37')\n",
"(372, 'Gustavo Ayon', '-1.37')\n",
"(373, 'Jason Smith', '-1.39')\n",
"(374, 'Julyan Stone', '-1.42')\n",
"(375, 'Jan Vesely', '-1.44')\n",
"(376, 'Viacheslav Kravtsov', '-1.48')\n",
"(377, 'Chase Budinger', '-1.48')\n",
"(378, 'Jon Leuer', '-1.50')\n",
"(379, 'Orlando Johnson', '-1.50')\n",
"(380, 'Eric Gordon', '-1.51')\n",
"(381, 'Brian Roberts', '-1.51')\n",
"(382, 'Reggie Evans', '-1.51')\n",
"(383, 'Henry Sims', '-1.53')\n",
"(384, 'Isaiah Canaan', '-1.54')\n",
"(385, 'Ronnie Brewer', '-1.56')\n",
"(386, 'Alec Burks', '-1.57')\n",
"(387, 'Erik Murphy', '-1.57')\n",
"(388, 'Travis Outlaw', '-1.58')\n",
"(389, 'Ben McLemore', '-1.62')\n",
"(390, 'Derrick Williams', '-1.62')\n",
"(391, 'Evan Turner', '-1.62')\n",
"(392, 'Cody Zeller', '-1.64')\n",
"(393, 'Kevin Seraphin', '-1.66')\n",
"(394, 'Chris Singleton', '-1.67')\n",
"(395, 'Hollis Thompson', '-1.68')\n",
"(396, 'Ramon Sessions', '-1.68')\n",
"(397, 'Robert Sacre', '-1.71')\n",
"(398, 'Garrett Temple', '-1.72')\n",
"(399, 'Jodie Meeks', '-1.77')\n",
"(400, 'Mike Muscala', '-1.78')\n",
"(401, 'Will Bynum', '-1.78')\n",
"(402, 'Cory Joseph', '-1.79')\n",
"(403, 'Jannero Pargo', '-1.79')\n",
"(404, 'Joel Anthony', '-1.81')\n",
"(405, 'Thomas Robinson', '-1.81')\n",
"(406, 'Udonis Haslem', '-1.83')\n",
"(407, 'Beno Udrih', '-1.83')\n",
"(408, 'Steve Blake', '-1.86')\n",
"(409, 'Steven Adams', '-1.86')\n",
"(410, 'Kyrie Irving', '-1.86')\n",
"(411, 'Jonas Jerebko', '-1.87')\n",
"(412, 'C.J. McCollum', '-1.88')\n",
"(413, 'Maurice Harkless', '-1.89')\n",
"(414, 'Kevin Garnett', '-1.93')\n",
"(415, 'Rajon Rondo', '-1.94')\n",
"(416, 'Darius Morris', '-1.97')\n",
"(417, 'Rasual Butler', '-1.98')\n",
"(418, 'Mike Scott', '-2.01')\n",
"(419, 'Gerald Wallace', '-2.03')\n",
"(420, 'Wesley Johnson', '-2.08')\n",
"(421, 'Mike Miller', '-2.08')\n",
"(422, 'Toney Douglas', '-2.10')\n",
"(423, 'Brandon Rush', '-2.15')\n",
"(424, 'Brandon Bass', '-2.16')\n",
"(425, 'Anthony Bennett', '-2.16')\n",
"(426, 'Andrea Bargnani', '-2.17')\n",
"(427, 'Mo Williams', '-2.17')\n",
"(428, 'Lou Williams', '-2.18')\n",
"(429, 'Jordan Hill', '-2.30')\n",
"(430, 'Alonzo Gee', '-2.33')\n",
"(431, 'Luis Scola', '-2.33')\n",
"(432, 'John Lucas III', '-2.34')\n",
"(433, 'Greg Oden', '-2.35')\n",
"(434, 'Cartier Martin', '-2.35')\n",
"(435, 'Mason Plumlee', '-2.38')\n",
"(436, 'Michael Beasley', '-2.38')\n",
"(437, 'Shannon Brown', '-2.39')\n",
"(438, 'Tony Wroten', '-2.40')\n",
"(439, 'Derrick Favors', '-2.44')\n",
"(440, 'Quincy Acy', '-2.47')\n",
"(441, 'Perry Jones', '-2.52')\n",
"(442, 'Lavoy Allen', '-2.53')\n",
"(443, 'Donald Sloan', '-2.54')\n",
"(444, 'Ian Mahinmi', '-2.54')\n",
"(445, 'Luc Richard Mbah a Moute', '-2.56')\n",
"(446, 'Luke Ridnour', '-2.60')\n",
"(447, 'J.J. Barea', '-2.64')\n",
"(448, 'Trevor Booker', '-2.66')\n",
"(449, 'Jeff Green', '-2.74')\n",
"(450, 'Archie Goodwin', '-2.74')\n",
"(451, 'Anthony Randolph', '-2.79')\n",
"(452, 'Tim Hardaway Jr.', '-2.80')\n",
"(453, 'Richard Jefferson', '-2.84')\n",
"(454, 'Earl Clark', '-2.88')\n",
"(455, 'Tyreke Evans', '-2.88')\n",
"(456, 'Will Barton', '-2.89')\n",
"(457, 'Carlos Boozer', '-2.90')\n",
"(458, 'Meyers Leonard', '-2.91')\n",
"(459, 'Aaron Gray', '-2.93')\n",
"(460, 'Kent Bazemore', '-3.10')\n",
"(461, 'Vitor Faverani', '-3.12')\n",
"(462, 'Charlie Villanueva', '-3.19')\n",
"(463, 'Gary Neal', '-3.25')\n",
"(464, 'Quincy Pondexter', '-3.27')\n",
"(465, 'Tony Snell', '-3.28')\n",
"(466, 'Marreese Speights', '-3.32')\n",
"(467, 'Jordan Hamilton', '-3.35')\n",
"(468, 'Andrew Bynum', '-3.39')\n",
"(469, 'Shawn Marion', '-3.42')\n",
"(470, 'Eric Maynor', '-3.45')\n",
"(471, 'Tyshawn Taylor', '-3.67')\n",
"(472, 'Enes Kanter', '-3.76')\n",
"(473, 'Byron Mullens', '-3.77')\n",
"(474, 'O.J. Mayo', '-3.97')\n",
"(475, 'Wayne Ellington', '-4.00')\n",
"(476, 'Jarrett Jack', '-4.02')\n",
"(477, 'Jeffery Taylor', '-4.26')\n",
"(478, \"Amar'e Stoudemire\", '-4.71')\n",
"(479, 'Elliot Williams', '-5.07')\n",
"(480, 'Dennis Schroder', '-5.09')\n",
"(481, 'John Henson', '-6.01')\n"
]
}
],
"prompt_number": 361
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment