Contenido


Poder social, influencia y rendimiento en la NBA, Parte 2

Explorar individualmente a los jugadores de la NBA

Python, Pandas y un poco de R

Comments

Contenido de la serie:

Este contenido es la parte # de # de la serie: Poder social, influencia y rendimiento en la NBA, Parte 2

Manténgase en contacto por contenidos adicionales de esta serie.

Este contenido es parte de la serie:Poder social, influencia y rendimiento en la NBA, Parte 2

Manténgase en contacto por contenidos adicionales de esta serie.

Iniciando

En la Parte 1 de esta serie, usted aprendió los aspectos básicos de la ciencia de datos y del aprendizaje automático. Utilizó Jupyter Notebook, Pandas y scikit-learn para explorar las relaciones entre los equipos de la NBA y sus valoraciones. Aquí, explorará la relación entre redes sociales, salario y rendimiento en la cancha de los jugadores de la NBA.

Cree un marco de datos unificado (Aviso: ¡va a ser un trabajo duro!)

Para empezar, cree un nuevo Jupyter Notebook y llámelo nba_player_power_influence_performance.

Después, cargue todos los datos de los jugadores y fusiónelos en un único marco de datos unificado.

La manipulación de varios marcos de datos cae en la categoría del 80 por ciento del trabajo duro de la ciencia de datos. En los listados 1 y 2, el marco de datos se copia basketball-reference y después se renombran varias columnas.

Listado 1. Configurar Jupyter Notebook y cargar marcos de datos

import pandas as pd
import numpy as np
import statsmodels.api as sm
import statsmodels.formula.api as smf
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.cluster import KMeans
color = sns.color_palette()
from IPython.core.display import display, HTML
display(HTML("<style>.container { width:100% !important; }</style>"))
%matplotlib inline
attendance_valuation_elo_df = pd.read_csv("../data/nba_2017_att_val_elo.csv")
salary_df = pd.read_csv("../data/nba_2017_salary.csv")
pie_df = pd.read_csv("../data/nba_2017_pie.csv")
plus_minus_df = pd.read_csv("../data/nba_2017_real_plus_minus.csv")
br_stats_df = pd.read_csv("../data/nba_2017_br.csv")

Listado 2. Corregir datos incorrectos en la columna en el marco de datos "plus minus"

plus_minus_df.rename(columns={"NAME":"PLAYER"}, inplace=True)
players = []
for player in plus_minus_df["PLAYER"]:
    plyr, _ = player.split(",")
    players.append(plyr)
plus_minus_df.drop(["PLAYER"], inplace=True, axis=1)
plus_minus_df["PLAYER"] = players
plus_minus_df.head()

A continuación, se muestra el resultado de los comandos para nombrar la columna NAME a la columna PLAYER. También se abandona la columna extra. Observe inplace=TRUE y los "drops" para aplicar en el marco de datos existente.

Figura 1. Carga y descripción de conjunto de datos de la NBA
Image shows output of commands
Image shows output of commands

El siguiente paso es renombrar y fusionar el marco de datos principal que contiene la mayor parte de las estadísticas de Basketball Reference. Para hacerlo, utilice el código que se brinda en los listados 3 y 4.

Listado 3. Renombrar y fusionar el marco de datos de basketball reference

nba_players_df = br_stats_df.copy()
nba_players_df.rename(columns={'Player': 'PLAYER','Pos':'POSITION', 'Tm': "TEAM", 'Age': 'AGE'}, inplace=True)
nba_players_df.drop(["G", "GS", "TEAM"], inplace=True, axis=1)
nba_players_df = nba_players_df.merge(plus_minus_df, how="inner", on="PLAYER")
nba_players_df.head()

Listado 4. Limpie y fusione los campos PIE

pie_df_subset = pie_df[["PLAYER", "PIE", "PACE"]].copy()
nba_players_df = nba_players_df.merge(pie_df_subset, how="inner", on="PLAYER")
nba_players_df.head()

La imagen 2 muestra el resultado de dividir las columnas en dos partes y de volver a crear la columna. Dividir y volver a crear columnas son operaciones típicas y ocupan la mayor parte del tiempo de la manipulación de datos para solucionar problemas de ciencia de datos.

Figura 2. Fusione marcos de datos de PIE
Image shows 5 rows x 37 columns  of data
Image shows 5 rows x 37 columns of data

Hasta ahora, la mayoría de las tareas de manipulación de datos han sido relativamente fáciles. Las cosas se van a poner un poco más difíciles porque faltan registros. En el Listado 5, faltan 111 registros de salario. Una forma de tratar esto es hacer una fusión que descarte las filas que faltan. Hay muchas técnicas para tratar con datos que faltan; sólo descartar las filas que faltan, como se muestra en el ejemplo, no siempre es la mejor opción. En Titanic: Aprendizaje Automático a partir del Desastre hay muchos ejemplos de cómo tratar con datos que faltan. Merece la pena pasar algo de tiempo explorando algunos cuadernos de ejemplo de ahí.

Listado 5. Limpiar el salario

salary_df.rename(columns={'NAME': 'PLAYER'}, inplace=True)
salary_df.drop(["POSITION","TEAM"], inplace=True, axis=1)
salary_df.head()

En el Listado 6, puede ver cómo se crea un conjunto para calcular el número de filas en las que faltan datos. Este es un truco útil muy valioso para determinar las diferencias que hay entre dos marcos de datos. Se logra utilizando la función len() incorporada en Python, que también se utiliza habitualmente en la programación normal de Python para obtener la longitud de una lista.

Listado 6. Encontrar registros que faltan y fusionar

diff = list(set(nba_players_df["PLAYER"].values.tolist()) - set(salary_df["PLAYER"].values.tolist()))
len(diff)

Out[45]:  111
nba_players_with_salary_df = nba_players_df.merge(salary_df)

El resultado se muestra a continuación.

Figura 3. Diferencia entre marcos de datos
Image shows difference between data frames
Image shows difference between data frames

Una vez completada la fusión de marcos de datos, es el momento de crear un mapa de calor de la correlación para descubrir qué funciones están correlacionadas. El mapa de calor siguiente muestra el resultado combinado de la correlación de 35 columnas y 342 filas. Un par de cosas que se resaltan inmediatamente son que el salario está altamente correlacionado con ambos puntos y WINS_RPM, que es una estadística avanzada que calcula la estimación de las victorias que un jugador aporta a su equipo por estar en la cancha.

Otra correlación interesante es que las vistas de las páginas de Wikipedia están fuertemente correlacionadas con el número de Favoritos de Twitter. Esta correlación intuitivamente tiene sentido porque ambas son medidas de participación y de popularidad de los jugadores de la NBA con sus seguidores. Este es un ejemplo de cómo una visualización puede ayudar a concretar qué funciones se incluirán en un modelo de aprendizaje automático.

Figura 4. Mapa de calor de correlación de jugadores de la NBA: sesión 2016-2017 (estadísticas y salario)
heatmap
heatmap

Una vez que se ha hecho el descubrimiento inicial de cuáles son las funciones que están correlacionadas, el siguiente paso es descubrir aún más las relaciones que existen en los datos mediante la creación de diagramas en Seaborn. A continuación, se muestran los comandos que se han ejecutado para crear el diagrama.

Listado 7. lmplot de Seaborn de salario comparado con WINS_RPM

sns.lmplot(x="SALARY_MILLIONS", y="WINS_RPM", data=nba_players_with_salary_df)

En el resultado del diagrama que se muestra a continuación, parece que hay una fuerte relación lineal entre salario y WINS_RPM. Para investigar más esto, ejecute una regresión lineal.

Figura 5. lmplot de Seaborn de salario y victorias reales de "plus minus"
Image shows salary millions x  axis, wins y axis
Image shows salary millions x axis, wins y axis

A continuación, se muestra el resultado de dos regresiones lineales sobre las victorias. Uno de los descubrimientos más interesantes es que WINS_RPM explica mejor las victorias que los puntos. El R-cuadrado (Bondad de ajuste) es 0,324 en el caso de WINS_RPM y 0,200 en los puntos. WINS_RPM es la estadística que muestra las victorias individuales que se atribuyen a un jugador. Tiene sentido que una estadística más avanzada que tiene en cuenta estadísticas defensivas y ofensivas y el tiempo en la cancha sea más predictiva que sólo una estadística ofensiva.

Un ejemplo de cómo poner esto en práctica es imaginar a un jugador que tuvo un porcentaje muy bajo de tiro, pero muchos puntos. Si hubiese tratando de encestar a menudo, en vez de un compañero que tenga un porcentaje de tiro mayor, le podría haber costado victorias. Este caso se reprodujo en la vida real durante la temporada 2015-16, en la que Kobe Bryant en su último año en Los Angeles Lakers, tenía 17,6 puntos por temporada, pero su porcentaje de tiro era del 41 por ciento en las canastas de dos puntos. El equipo acabó ganando sólo 17 partidos, y la estadística WINS_RPM fue de 0,66 (durante esa temporada sólo se atribuyó media victoria a su juego ).

Figura 6. Regresión lineal de victorias
Image shows  linear  wins data
Image shows linear wins data

Listado 8. Regresión de victorias y de puntos

results = smf.ols('W ~POINTS', data=nba_players_with_salary_df).fit()
print(results.summary())

Otra forma de representar esta relación gráficamente es con "ggplot" en Python. El listado 9 es un ejemplo de cómo configurar el diagrama. La biblioteca de Python es un puerto directo de ggplot en R y está en desarrollo activo. Al momento de escribir esto, su uso no era tan uniforme como el R ggplot normal, pero tiene muchas funciones buenas. El gráfico se muestra a continuación.
Nota: Una función útil es la capacidad de representar otra columna de variables continuas con un color.

Listado 9. ggplot de Python

from ggplot import *
p = ggplot(nba_players_with_salary_df,aes(x="POINTS", y="WINS_RPM", color="SALARY_MILLIONS")) + geom_point(size=200)
p + xlab("POINTS/GAME") + ylab("WINS/RPM") + ggtitle("NBA Players 2016-2017:  POINTS/GAME, WINS REAL PLUS MINUS and SALARY")
Figura 7. ggplot de Python punto de salario "plus minus"
Image shows wins/rpm x axis, points/game y axis
Image shows wins/rpm x axis, points/game y axis

Obtención de las vistas de página de Wikipedia para los jugadores de la NBA

La siguiente tarea es descubrir cómo recopilar las vistas de página de Wikipedia, lo que normalmente es una recopilación de datos confusa. Entre sus problemas están:

  1. Descubrir cómo extraer datos de Wikipedia (o de algún sitio web)
  2. Descubrir cómo generar identificadores de Wikipedia de forma programática
  3. Escribir los datos en un marco de datos y unirlos junto con el resto de los datos

El siguiente código está en el repositorio de GitHub para este tutorial. Los comentarios sobre este código se encuentran a lo largo de las siguientes secciones.

El listado 10 brinda el código para construir un URL de Wikipedia URL que devuelva una respuesta en JSON. En la Parte 1, en el "docstrings" se muestra la ruta para construirlo. Este es el URL al que llama el código para obtener datos de las vistas de la página.

Listado 10. Wikipedia, parte 1

"""
Ejemplo de la Ruta a Construir:

https://wikimedia.org/api/rest_v1/ +
metrics/pageviews/per-article/ +
en.wikipedia/all-access/user/ +
LeBron_James/daily/2015070100/2017070500 +

"""
import requests
import pandas as pd
import time
import wikipedia

BASE_URL =\
 "https://wikimedia.org/api/rest_v1/metrics/pageviews/per-article/en.wikipedia/all-access/user"

def construct_url(handle, period, start, end):
    """Construye un URL basándose en los argumentos

    Debería construir el siguiente URL:
    /LeBron_James/daily/2015070100/2017070500
    """

    
    urls  = [BASE_URL, handle, period, start, end]
    constructed = str.join('/', urls)
    return constructed

def query_wikipedia_pageviews(url):

    res = requests.get(url)
    return res.json()

def wikipedia_pageviews(handle, period, start, end):
    """Returns JSON"""

    constructed_url = construct_url(handle, period, start,end)
    pageviews = query_wikipedia_pageviews(url=constructed_url)
    return pageviews

En el Listado 10, parte 2, se crean identificadores de Wikipedia adivinando cuál es el nombre y el apellido del jugador y después intentando añadir "(basketball)" al URL si hay un error. Esto soluciona la mayor parte de los casos, y sólo se pierden algunos nombres/identificadores. Un ejemplo de suposición sería "LeBron" como el nombre y "James" como el apellido. La razón para suponer inicialmente de esta forma es que así coincide con casi el 80 por ciento de las páginas de Wikipedia y ahorra el tiempo de encontrar las URLs una por una. Para el 20 por ciento de los nombres que no encajan con este patrón, hay otro método (que se muestra a continuación) y que coincide con el 80 por ciento de los que fallan inicialmente.

Al añadir "(basketball)," Wikipedia puede diferenciar entre un nombre famoso y otro. Esta convención agarra la mayoría de los nombres que no coincidían. El listado 10, parte 2 muestra el último método para encontrar los nombres de los otros.

Listado 10. Wikipedia, parte 2

def wikipedia_2016(handle,sleep=0):
    """Extrae las vistas de página del 2016"""

    print("SLEEP: {sleep}".format(sleep=sleep))
    time.sleep(sleep)
    pageviews = wikipedia_pageviews(handle=handle, 
            period="daily", start="2016010100", end="2016123100")
    if not 'items' in pageviews:
        print("NO PAGEVIEWS: {handle}".format(handle=handle))
        return None
    return pageviews

def create_wikipedia_df(handles):
    """Crea un marco de datos de las vistas de página"""

    pageviews = []
    timestamps = []    
    names = []
    wikipedia_handles = []
    for name, handle in handles.items():
        pageviews_record = wikipedia_2016(handle)
        if pageviews_record is None:
            continue
        for record in pageviews_record['items']:
            pageviews.append(record['views'])
            timestamps.append(record['timestamp'])
            names.append(name)
            wikipedia_handles.append(handle)
    data = {
        "names": names,
        "wikipedia_handles": wikipedia_handles,
        "pageviews": pageviews,
        "timestamps": timestamps 
    }
    df = pd.DataFrame(data)
    return df    


def create_wikipedia_handle(raw_handle):
    """Toma un identificador en bruto y lo convierte en un identificador de wikipedia"""

    wikipedia_handle = raw_handle.replace(" ", "_")
    return wikipedia_handle

def create_wikipedia_nba_handle(name):
    """Añade basketball al el enlace"""

    url = " ".join([name, "(basketball)"])
    return url

En el listado 10, parte 3, se facilita la suposición de un identificador al tener acceso a una lista de jugadores. Esta parte del código ejecuta el código para encontrar coincidencias que se mostraron antes, contra toda la lista de la NBA que se recopiló con anterioridad en el artículo.

Listado 10. Wikipedia, parte 3

def wikipedia_current_nba_roster():
    """Obtiene todos los enlaces de la página de la lista actual de wikipedia"""

    links = {}
    nba = wikipedia.page("List_of_current_NBA_team_rosters")
    for link in nba.links:
        links[link] = create_wikipedia_handle(link)
    return links

def guess_wikipedia_nba_handle(data="data/nba_2017_br.csv"):
    """Intenta obtener el identificador correcto de wikipedia"""

    links = wikipedia_current_nba_roster() 
    nba = pd.read_csv(data)
    count = 0
    verified = {}
    guesses = {}
    for player in nba["Player"].values:
        if player in links:
            print("Player: {player}, Link: {link} ".format(player=player,
                 link=links[player]))
            print(count)
            count += 1
            verified[player] = links[player] #add wikipedia link
        else:
            print("NO MATCH: {player}".format(player=player))
            guesses[player] = create_wikipedia_handle(player)
    return verified, guesses

En el listado 10, parte 4, se ejecuta todo el script utilizando el archivo CSV como entrada y haciendo que otro archivo CSV funcione como el resultado. Observe que la biblioteca Wikipedia Python se utiliza para inspeccionar la página para encontrar la palabra "NBA" en las coincidencias finales. Esta es la última verificación para las páginas que han fallado con varias técnicas de suposición. El resultado de todos estos procedimientos heurísticos es una forma relativamente confiable de obtener los identificadores de Wikipedia para los atletas de la NBA. Se podría imaginar el uso de una técnica similar para otros deportes.

Listado 10. Wikipedia, parte 4

def validate_wikipedia_guesses(guesses):
    """Valida las cuentas adivinadas de la Wikipedia"""

    verified = {}
    wrong = {}
    for name, link in guesses.items():
        try:
            page = wikipedia.page(link)
        except (wikipedia.DisambiguationError, wikipedia.PageError) as error:
            #try basketball suffix
            nba_handle = create_wikipedia_nba_handle(name)
            try:
                page = wikipedia.page(nba_handle)
                print("Initial wikipedia URL Failed: {error}".format(error=error))
            except (wikipedia.DisambiguationError, wikipedia.PageError) as error:
                print("Second Match Failure: {error}".format(error=error))
                wrong[name] = link
                continue
        if "NBA" in page.summary:
            verified[name] = link
        else:
            print("NO GUESS MATCH: {name}".format(name=name))
            wrong[name] = link
    return verified, wrong

def clean_wikipedia_handles(data="data/nba_2017_br.csv"):
    """Limpiar Identificadores"""

    verified, guesses = guess_wikipedia_nba_handle(data=data)
    verified_cleaned, wrong = validate_wikipedia_guesses(guesses)
    print("WRONG Matches: {wrong}".format(wrong=wrong))
    handles = {**verified, **verified_cleaned}
    return handles

def nba_wikipedia_dataframe(data="data/nba_2017_br.csv"):
    handles = clean_wikipedia_handles(data=data)
    df = create_wikipedia_df(handles)    
    return df

def create_wikipedia_csv(data="data/nba_2017_br.csv"):
    df = nba_wikipedia_dataframe(data=data)
    df.to_csv("data/wikipedia_nba.csv")


if __name__ == "__main__":
    create_wikipedia_csv()

Obtención de la participación en Twitter de los jugadores de la NBA

Ahora necesita la biblioteca de Twitter para poder descargar los tuits de los jugadores de la NBA. El listado 11, parte 1, muestra la API para utilizar este código. La API de Twitter es más avanzada que el simple script que se muestra a continuación. Esta es una de las ventajas de utilizar una biblioteca de terceros que ha sido desarrollada durante años.

Listado 11. Extracción de metadatos de Twitter, parte 1

"""
Obtener el estado en Twitter

df = stats_df(user="KingJames")
In [34]: df.describe()
Out[34]:
       favorite_count  retweet_count
count      200.000000     200.000000
mean     11680.670000    4970.585000
std      20694.982228    9230.301069
min          0.000000      39.000000
25%       1589.500000     419.750000
50%       4659.500000    1157.500000
75%      13217.750000    4881.000000
max     128614.000000   70601.000000

In [35]: df.corr()
Out[35]:
                favorite_count  retweet_count
favorite_count        1.000000       0.904623
retweet_count         0.904623       1.000000

"""

import time

import twitter
from . import config
import pandas as pd
import numpy as np
from twitter.error import TwitterError

def api_handler():
    """Crea la conexión con la API de Twitter"""

    api = twitter.Api(consumer_key=config.CONSUMER_KEY,
    consumer_secret=config.CONSUMER_SECRET,
    access_token_key=config.ACCESS_TOKEN_KEY,
    access_token_secret=config.ACCESS_TOKEN_SECRET)
    return api

def tweets_by_user(api, user, count=200):
    """Extrae el número "n" de tuits.  El número predeterminado es 200"""

    tweets = api.GetUserTimeline(screen_name=user, count=count)
    return tweets

En la siguiente sección, los tuits se extraen y se convierte en un marco de datos de Pandas que almacena los valores como una mediana. Esta es una excelente técnica para comprimir los datos almacenando sólo los valores en los que estamos interesados (es decir, la mediana de un conjunto de datos). La mediana es una métrica útil porque es sólida contra los valores artísticos.

Listado 11. Extracción de metadatos de Twitter, parte 2

def stats_to_df(tweets):
    """Toma las estadísticas de Twitter y las convierte en un marco de datos"""

    records = []
    for tweet in tweets:
        records.append({"created_at":tweet.created_at,
            "screen_name":tweet.user.screen_name,
            "retweet_count":tweet.retweet_count,
            "favorite_count":tweet.favorite_count})
    df = pd.DataFrame(data=records)
    return df

def stats_df(user):
    """Devuelve un marco de datos de estadísticas"""

    api = api_handler()
    tweets = tweets_by_user(api, user)
    df = stats_to_df(tweets)
    return df

def twitter_handles(sleep=.5,data="data/twitter_nba_combined.csv"):
    """produce los identificadores"""

    nba = pd.read_csv(data)
    for handle in nba["twitter_handle"]:
        time.sleep(sleep) #Avoid throttling in twitter api
        try:
            df = stats_df(handle)
        except TwitterError as error:
            print("Error {handle} and error msg {error}".format(
                handle=handle,error=error))
            df = None
        yield df

def median_engagement(data="data/twitter_nba_combined.csv"):
    """Participación mediana en twitter"""

    favorite_count = []
    retweet_count = []
    nba = pd.read_csv(data)
    for record in twitter_handles(data=data):
        print(record)
        #None records stored as Nan value
        if record is None:
            print("NO RECORD: {record}".format(record=record))
            favorite_count.append(np.nan)
            retweet_count.append(np.nan)
            continue
        try:
            favorite_count.append(record['favorite_count'].median())
            retweet_count.append(record["retweet_count"].median())
        except KeyError as error:
            print("No values found to append {error}".format(error=error))
            favorite_count.append(np.nan)
            retweet_count.append(np.nan)

    print("Creando DF")
    nba['twitter_favorite_count'] = favorite_count
    nba['twitter_retweet_count'] = retweet_count
    return nba

def create_twitter_csv(data="data/nba_2016_2017_wikipedia.csv"):
    nba = median_engagement(data)
    nba.to_csv("data/nba_2016_2017_wikipedia_twitter.csv")

Crear visualizaciones avanzadas

Si añade los datos de las redes sociales puede crear diagramas más avanzados con conocimientos adicionales. La imagen 8 es un diagrama avanzado, llamado mapa de calor. Muestra la correlación de un conjunto comprimido de funciones claves. Estas funciones son un elemento básico para realizar un más aprendizaje automático, como la agrupación (vea laParte 1 de esta serie). Podría merecer la pena utilizar estos datos en su propio experimento con diferentes configuraciones de agrupación.

Figura 8. Mapa de calor de correlación de apoyo, poder social, rendimiento en la cancha y valor del equipo de los jugadores de la NBA: temporada 2016-17
heatmap
heatmap

El listado 12 brinda el código para crear el mapa de calor de la correlación.

Listado 12. Mapa de calor de la correlación

endorsements = pd.read_csv("../data/nba_2017_endorsement_full_stats.csv")
plt.subplots(figsize=(20,15))
ax = plt.axes()
ax.set_title("Mapa de calor de correlación de ingresos publicitarios, poder social, rendimiento en la cancha
                    y valor del equipo de los jugadores de la NBA: temporada 2016-17")
corr = endorsements.corr()
sns.heatmap(corr,
            xticklabels=corr.columns.values,
            yticklabels=corr.columns.values, cmap="copper")

El listado 13 muestra un mapa de calor con los colores que se han creado utilizando una escala logarítmica con un mapa con colores especiales. Este es un gran grupo para brindar un contraste diferente entre cada celda. La escala logarítmica es una transformación que muestra el cambio relativo comparándolo con el cambio real. Es una técnica habitual para utilizar en los gráficos cuando los valores tienen grandes magnitudes de diferenciación — por ejemplo, 10 y 10 millones. Mostrar el cambio relativo, en vez del cambio real, añade claridad a un diagrama. Normalmente, los diagramas se muestran en escala lineal (una línea recta). La escala logarítmica (línea logarítmica) disminuye su potencia a medida que se dibuja (lo que significa que se aplana).

Listado 13. Mapa de calor avanzado de la correlación

from matplotlib.colors import LogNorm
plt.subplots(figsize=(20,15))
pd.set_option('display.float_format', lambda x: '%.3f' % x)
norm = LogNorm()
ax = plt.axes()
grid = endorsements.select_dtypes([np.number])
ax.set_title("Mapa de calor de ingresos publicitarios, poder social, rendimiento en la cancha
                    y valor del equipo de los jugadores de la NBA: temporada 2016-17")
sns.heatmap(grid,annot=True, yticklabels=endorsements["PLAYER"],fmt='g', cmap="Accent", cbar=False, norm=norm)
Figura 9. Mapa de calor de ingresos publicitarios, poder social, rendimiento en la cancha y valor del equipo de los jugadores de la NBA: temporada 2016-17
Image shows heatmap
Image shows heatmap

El último diagrama utiliza el lenguaje R para crear un diagrama multidimensional en ggplot. Esto se muestra en el Listado 14 y en la Imagen 10. La biblioteca ggplot nativa de R es una biblioteca de representación gráfica potente y única que puede crear múltiples dimensiones con colores, tamaños, facetas y formas. Merece la pena que pase algo de tiempo explorando por sí mismo la biblioteca ggplot de R.

Listado 14. ggplot avanzado basado en R

ggplot(nba_players_stats, aes(x=WINS_RPM, y=PAGEVIEWS,
                color=SALARY_MILLIONS, size=TWITTER_FAVORITE_COUNT)) + geom_point() +
                geom_smooth() + scale_color_gradient2(low = "blue", mid = "grey", high =
                "red", midpoint = 15) + labs(y="Mediana de vistas diarias de la página de Wikipedia", x="WINS
                Attributed to Player( WINS_RPM)", title = "Poder Social de la NBA temporada 2016-2017:
                Mediana de vistas diarias de la página de Wikipedia y victorias atribuidas a un jugador
                (Ajustadas más o menos)") +
                geom_text(vjust="inward",hjust="inward",color="black",size=4,check_overlap
                = TRUE, data=subset(nba_players_stats, SALARY_MILLIONS > 25 | PAGEVIEWS
                > 4500 | WINS_RPM > 15), aes(WINS_RPM,label=PLAYER )) +
                annotate("text", x=8, y=13000, label= "¿Los seguidores de la NBA valoran la habilidad de un jugador más que su
                salario, sus puntos, las victorias de su equipo o que cualquier otro factor?", size=5) +
                annotate("text", x=8, y=11000, label=paste("correlación VISTAS DE PÁGINA/VICTORIAS:
                28%"),size=4) + annotate("text", x=8, y=10000,
                label=paste("correlación VISTAS DE PÁGINA/Puntos 44%"),size=4) + annotate("text",
                x=8, y=9000, label=paste("correlación VISTAS DE PÁGINA/VICTORIAS_RPM: 49%"),size=4,
                color="red") + annotate("text", x=8, y=8000,
                label=paste("correlación SALARIO EN MILLONES/NÚMERO_DE_FAVORITOS_EN_TWITTER: 24%"),size=4)
Figura 10. Poder social de jugador de la NBA: temporada 2016-17
Image shows chart with end result NBA fans value player skill more than salary, points, or other factors
Image shows chart with end result NBA fans value player skill more than salary, points, or other factors

Conclusión

En la Parte 1 de esta serie, usted aprendió los aspectos básicos del aprendizaje automático y utilizó técnicas de agrupación no supervisadas para explorar la valoración del equipo. Las herramientas que se utilizaron para esta ciencia de datos fueron Python y los gráficos avanzados de Jupyter Notebook.

Aquí, en la Parte 2, usted ha explorado a los jugadores y su relación con las redes sociales, influencia, salario y rendimiento en la cancha. En un Jupyter Notebook se crearon muchos gráficos avanzados, aunque también se utilizó un poco R.

Algunas preguntas expuestas o que tienen que ser investigadas más (pueden ser suposiciones erróneas):

  • El salario que se paga a los jugadores no es un gran indicador de las victorias.
  • Los seguidores apoyan más a los atletas más habilidosos (en vez de a los mejor pagados, por ejemplo).
  • Los ingresos publicitarios están correlacionados con cuántas victorias tienen un equipo gracias a un jugador, porque tienen que tener cuidado sobre a qué equipo se cambian.
  • Parece que la audiencia que asiste a los partidos físicamente es diferente de la audiencia que participa en las redes sociales. La audiencia que asiste físicamente parece que se preocupa de si su equipo no tiene habilidades.

Es posible hacer más cosas. Intente aplicar el aprendizaje automático supervisado y no supervisado al conjunto de datos que se brinda en GitHub. He subido a Kaggle el conjunto de datos para que usted experimente con este proyecto.


Recursos para Descargar


Temas relacionados


Comentarios

Inicie Sesión o Regístrese para agregar comentarios.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=90
Zone=Big data y analytics
ArticleID=1056817
ArticleTitle=Poder social, influencia y rendimiento en la NBA, Parte 2: Explorar individualmente a los jugadores de la NBA
publish-date=01192018