Conteúdo


Poder social, influência e desempenho na NBA, Parte 1

Explore a avaliação e a presença do público usando ciência de dados e aprendizado de máquina

Python, pandas e um toque de R

Comments

Conteúdos da série:

Esse conteúdo é a parte # de # na série: Poder social, influência e desempenho na NBA, Parte 1

Fique ligado em conteúdos adicionais dessa série.

Esse conteúdo é parte da série:Poder social, influência e desempenho na NBA, Parte 1

Fique ligado em conteúdos adicionais dessa série.

Nesta série de tutoriais, aprenda a analisar como a mídia social afeta a NBA usando Python, pandas, Jupyter Notebooks e um toque de R. Aqui, na Parte 1, aprenda os fundamentos básicos da ciência de dados e do aprendizado de máquina relacionados aos times da NBA. Os jogadores da NBA são o assunto da Parte 2.

O que é ciência de dados, aprendizado de máquina e IA?

Há muita confusão em relação aos termos ciência de dados, aprendizado de máquina e inteligência artificial. Esses termos geralmente são usados indistintamente, mas em linhas gerais:

  • Ciência de dados é a filosofia de pensar cientificamente sobre os dados.
  • Aprendizado de máquina é uma técnica na qual os computadores aprendem sem serem instruídos explicitamente para aprenderem.
  • Inteligência artificial é a inteligência demonstrada por máquinas. (Aprendizado de máquina é um exemplo de técnica de IA, outro exemplo é a otimização).

Regra 80/20 do aprendizado de máquina na prática

Uma parte subestimada do aprendizado de máquina é a regra 80/20, na qual aproximadamente 80 por cento do tempo é gasto obtendo e manipulando dados e 20 por cento é dedicado à parte interessante como analisar dados, modelar dados e fazer previsões.

Figura 1. Regra 80/20 do aprendizado de máquina na prática
Image shows machine learning in practice
Image shows machine learning in practice

Um problema da manipulação de dados que não é óbvio é, em primeiro lugar, obter os dados. Uma coisa é tentar com um conjunto de dados disponível publicamente, outra coisa é vasculhar a Internet, chamar APIs e obter os dados em formato utilizável. Além dessas questões, um problema que pode ser ainda mais complicado é colocar os dados em produção.

Figura 2. Ciência de dados full-stack
Image shows full-stack data science
Image shows full-stack data science

Com razão, há muita atenção voltada para o aprendizado de máquina e para as aptidões necessárias para modelar: matemática aplicada, conhecimento da área e conhecimento do conjunto de ferramentas. Implementar um sistema de aprendizado de máquina de produção já é uma outra questão. Essa questão será abordada em linhas gerais nesta série de tutoriais buscando inspirá-lo a criar modelos de aprendizado de máquina e a implementá-los em produção.

O que é aprendizado de máquina?

Além de uma descrição em linhas gerais, existe uma hierarquia para o aprendizado de máquina. No topo está o aprendizado supervisionado e o aprendizado não supervisionado. Há dois tipos de técnicas de aprendizado supervisionado: problemas de classificação e problemas de regressão que têm um conjunto de treinamento com dados rotulados.

Um exemplo de problema de aprendizado de máquina de regressão supervisionado é prever os preços futuros de imóveis residenciais usando dados de vendas históricos. Um exemplo de problema de classificação supervisionado é usar um repositório histórico de imagens para classificar objetos em imagens: carros, casas, formas, etc.

O aprendizado não supervisionado envolve uma modelagem onde os dados não são rotulados. A resposta correta pode não ser conhecida e precisa ser descoberta. Um exemplo comum é o armazenamento em cluster. Um exemplo de armazenamento em cluster é encontrar grupos de jogadores da NBA com coisas em comum e rotular esses clusters manualmente — por exemplo, principais artilheiros, principais arremessadores, etc.

Colocando o problema: qual é o relacionamento entre a influência social e a NBA?

Agora que o básico já foi feito, é hora de analisar mais a fundo:

  • O desempenho individual de um jogador afeta as vitórias do time?
  • O desempenho na quadra está correlacionado com a influência da mídia social?
  • O engajamento em mídias sociais está correlacionado à popularidade na Wikipédia?
  • A contagem de seguidores ou o engajamento apresenta a melhor previsão de popularidade na Wikipédia?
  • O salário está correlacionado ao desempenho na quadra?
  • O salário está correlacionado ao desempenho nas mídias sociais?
  • Ganhar traz mais fãs para os jogos?
  • O que direciona a avaliação dos times: presença do público, mercado imobiliário local?

Para responder a essas e outras perguntas, é necessário recuperar diversas categorias de dados:

  • Popularidade na Wikipédia
  • Engajamento no Twitter
  • Presença do público no estádio
  • Dados de desempenho da NBA
  • Dados de salário da NBA
Figura 3. Origens de dados da NBA
Image shows NBA                     data sources
Image shows NBA data sources

Analisando a fundo o problema dos 80 por cento: reunindo dados

Reunir esses dados é um problema significativo de engenharia de software. A primeira etapa para coletar todos os dados é descobrir por onde começar. Para este tutorial, uma boa opção para começar é coletar todos os jogadores da NBA da temporada de 2016/17.

Isso sugere algo muito útil sobre o modo de coletar dados: se é fácil coletar dados manualmente — por exemplo, fazer o download de um website e limpar os dados manualmente no Excel — então existe uma maneira plausível de começar com um problema de ciência de dados. Se o processo de coletar uma origem de dados e de limpar os dados manualmente durar horas, é melhor escrever um código para resolver o problema.

Felizmente, coletar a primeira origem de dados é simples, basta fazer o download de um CSV da Referência de Basquete. Agora que a primeira coleta já foi feita, é hora de explorar rapidamente o uso de pandas e do Jupyter Notebook. Antes de executar um código, será necessário:

  1. Criar um ambiente virtual (baseado no Python 3.6)
  2. Instalar os pacotes usados neste tutorial: pandas e Jupyter Notebook.

Como o padrão de instalação e atualização de pacotes é muito comum, eu coloquei o processo em um Makefile, conforme mostrado abaixo:

Listagem 1. Conteúdo do makefile

setup:
	mkdir -p ~/.socialpowernba && python3 -m venv ~/.socialpowernba

install:
	pip install -r requirements.txt

Para começar a trabalhar em um projeto, execute make setup && make install.

Outro truque é criar um alias para que quando você desejar trabalhar em um projeto específico, o virtualenv seja criado automaticamente ao emitir cd no projeto. O conteúdo do arquivo .zshrc com esse alias dentro é semelhante a este:

alias nbatop="cd ~/src/socialpowernba && source ~/.socialpowernba/bin/activate"

Para iniciar o ambiente virtual, digite nbatop. Você emitirá cd no check-out e iniciará o virtualenv.

Para inspecionar o conjunto de dados transferido por download ou usado do repositório do GitHub:

Inicie o Jupyter Notebook: Jupyter notebook. Executar esse comando ativa um navegador da web no qual é possível explorar os notebooks existentes ou criar novos notebooks.

Se você estiver usando os arquivos no repositório do GitHub, procure basketball_reference.ipynb, que é um notebook simples que consulta os dados internos.

É possível criar um notebook usando o menu na web ou carregar o notebook que está no repositório do GitHub, chamado basketball_reference. Para fazer uma validação e uma exploração iniciais, carregue um arquivo CSV em um quadro de dados do pandas. Carregar um arquivo CSV no pandas é fácil, mas há duas considerações:

  • As colunas no arquivo CSV precisam ter nomes.
  • As linhas de cada coluna precisam ter tamanhos iguais

A Listagem 2 mostra como carregar o arquivo no pandas.

Listagem 2. Exploração da referência de basquete do Jupyter Notebook

import pandas as pd
nba = pd.read_csv("../data/nba_2017_br.csv")
nba.describe()

A imagem a seguir mostra o resultado dos dados carregados. A função describe em um quadro de dados do pandas fornece estatísticas descritivas, incluindo o número de colunas. Em seus dados, e como é mostrado abaixo, o número de colunas é 27 e a média (que é a linha 50 por cento) para cada coluna. Neste ponto, é interessante brincar um pouco com o Jupyter Notebook que você criou e ver quais insights podem ser observados. Para saber mais sobre o que o pandas pode fazer, consulte a página do tutorial do pandas.

Figura 4. Carregar e descrever o conjunto de dados da NBA
Image shows NBA dataset load and describe
Image shows NBA dataset load and describe

Uma coisa que este conjunto de dados não tem é uma maneira clara de classificar o desempenho ofensivo e defensivo de um jogador em uma estatística. Existem algumas maneiras de classificar os jogadores da NBA usando apenas uma única estatística. O website FiveThirtyEight tem um sistema de classificação CARMELO. A ESPN tem o Real Plus-Minus, que inclui o resultado de partidas vencidas atribuídas a cada jogador, o que é muito útil. A estatística de número único da NBA é chamada de PIE (Player Impact Estimate, ou seja, Estimativa de Impacto do Jogador).

O nível de dificuldade aumenta um pouco ao obter os dados dos dois websites, ESPN e NBA. Uma abordagem é vasculhar o website usando uma ferramenta como o Scrapy. No entanto, a abordagem usada neste tutorial é um pouco mais simples que essa. Nesse caso, recortar e colar do website no Excel, limpar os dados manualmente e, em seguida, salvar os dados como um CSV é mais rápido do que escrever o código para fazer isso. Mais tarde, se o projeto ganhar uma proporção maior, essa abordagem poderá não funcionar mais tão bem. Mas, para este tutorial, essa é uma boa solução. Uma boa lição para problemas de ciência de dados complicados é continuar a progredir rapidamente sem parar para se aprofundar muito.

É possível gastar um bom tempo aperfeiçoando uma maneira de obter uma origem de dados e limpá-la e, em seguida, perceber que esses dados não são úteis para o modelo que você está criando.

A imagem abaixo mostra o conjunto de dados PIE da NBA. Os dados também contêm uma contagem igual a 486 ou 486 linhas. Obter os dados da ESPN é um processo semelhante ao processo mencionado acima. Outras origens de dados a serem consideradas são salários e patrocínios. A ESPN tem as informações sobre salário e a Forbes tem um pequeno subconjunto de dados de patrocínio. Essas duas origens de dados estão no projeto do GitHub.

Figura 5. Conjunto de dados PIE da NBA
Image shows NBA                     PIE dataset
Image shows NBA PIE dataset

Na Tabela 1, há uma listagem de origens de dados por nome e local. Em pouco tempo, temos muitos itens de diversas origens de dados.

Tabela 1. Origens de dados da NBA
Origem de dadosNome do arquivoLinhasResumo
Basketball-Reference nba_2017_attendance.csv 30 Presença do público no estádio
Forbes nba_2017_endorsements.csv 8 Principais jogadores
Forbes nba_2017_team_valuations.csv 30 Todos os times
ESPN nba_2017_salary.csv 450 A maioria dos jogadores
NBA nba_2017_pie.csv 468 Todos os jogadores
ESPN nba_2017_real_plus_minus.csv 468 Todos os jogadores
Basketball-Reference nba_2017_br.csv 468 Todos os jogadores
FiveThirtyEight nba_2017_elo.csv 30 Classificação do time

Ainda há muito trabalho a ser feito para obter todos os dados transferidos por download e transformados em um conjunto de dados unificado. Para piorar ainda mais, coletar os dados até agora foi fácil, mas ainda temos uma longa jornada a seguir. Ao observar o formato dos dados, uma boa maneira de começar é obter os oito principais patrocínios de jogadores e verificar se existe algum padrão a ser analisado. No entanto, antes de fazer isso, explore a avaliação dos times na NBA. Com essas informações, é possível determinar o impacto que um jogador causa no valor total de uma franquia da NBA.

Explorando a avaliação do time da NBA

O primeiro passo é criar um novo Jupyter Notebook. Para sua sorte, o Jupyter Notebook já foi criado. Encontre-o no repositório do GitHub: exploring_team_valuation_nba.

Em seguida, importe um conjunto comum de bibliotecas que geralmente são usadas para explorar dados em um Jupyter Notebook.

Listagem 3. Importações iniciais comuns do Jupyter Notebook

import pandas as pd
import statsmodels.api as sm
import statsmodels.formula.api as smf
import matplotlib.pyplot as plt
import seaborn as sns
color = sns.color_palette()
%matplotlib inline

Agora, é necessário criar um quadro de dados do pandas para cada origem.

Listagem 4. Criar quadro de dados para origens

attendance_df = pd.read_csv("../data/nba_2017_attendance.csv")
endorsement_df = pd.read_csv("../data/nba_2017_endorsements.csv")
valuations_df = pd.read_csv("../data/nba_2017_team_valuations.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")
elo_df = pd.read_csv("../data/nba_2017_elo.csv")

Um ótimo truque ao trabalhar com uma grande quantidade de origens de dados é mostrar as primeiras linhas de cada quadro de dados. Veja como seria isso nas imagens abaixo.

Figura 6. Seção A dos quadros de dados de patrocínio
Image shows endorsement data frames section A
Image shows endorsement data frames section A
Figura 7. Seção B dos quadros de dados de patrocínio
Image shows endorsement data frames section B
Image shows endorsement data frames section B

Agora, junte os dados de avaliação de time com os dados de presença de público e crie um plot. A Listagem 5 fornece o código para mesclar os quadros de dados do pandas.

Listagem 5. Mesclando os quadros de dados do pandas

attendance_valuation_df = attendance_df.merge(valuations_df, how="inner", on="TEAM")
attendance_valuation_df.head()

A imagem abaixo mostra o resultado da mesclagem.

Figura 8. Cabeçalho da mesclagem do quadro de dados de avaliação de presença do público
Image shows attendance valuation data frame merge head
Image shows attendance valuation data frame merge head

Para melhorar a aparência dos dados que você acabou de mesclar, faça algumas visualizações rápidas. A primeira etapa é solicitar que o notebook exiba gráficos maiores e, em seguida, executar um pairplot do Seaborne, como é mostrado abaixo.

Listagem 6. Pairplot do Seaborn

from IPython.core.display import display, HTML
display(HTML("<style>.container { width:100% !important; }</style>"))
sns.pairplot(attendance_valuation_df, hue="TEAM")

Olhando os plots, observe o relacionamento entre a média de presença do público e a avaliação do jogador. Existe um forte relacionamento linear entre os dois aspectos, representado pela linha quase reta formada pelos pontos.

Figura 9. Pairplot do Seaborn da NBA sobre presença do público versus avaliação
Image shows Seaborn pairplot NBA attendance versus valuation
Image shows Seaborn pairplot NBA attendance versus valuation

Outra maneira de analisar esses dados é usar um plot de correlação. Para criar um plot de correlação, use o código fornecido abaixo. A imagem a seguir mostra o resultado.

Listagem 7. Plot de correlação do Seaborn

corr = attendance_valuation_df.corr()
sns.heatmap(corr, 
            xticklabels=corr.columns.values,
            yticklabels=corr.columns.values)
Figura 10. Plot de correlação do Seaborn da NBA sobre presença do público versus avaliação
Image shows Seaborn correlation plot NBA attendance versus                     valuation
Image shows Seaborn correlation plot NBA attendance versus valuation

O plot de correlação mostra um relacionamento com o valor em milhões de dólares (de um time da NBA), a porcentagem da capacidade média do estádio que está preenchida (PCT) e a média de presença do público. Um mapa de calor mostrando os números médios de presença do público versus avaliação para cada time da NBA ajudará a fazer uma análise mais profunda. Para gerar um mapa de calor no Seaborn, é necessário mudar o formato dos dados para uma tabela pivô (semelhante às que estão disponíveis no Excel). Uma tabela pivô permite que o gráfico do Seaborn alterne entre três valores e mostra como cada uma das três colunas se relaciona com as outras duas. O código abaixo mostra como mudar os dados para um formato de pivô.

Listagem 8. Plot de mapa de calor do Seaborn

valuations = attendance_valuation_df.pivot("TEAM", "AVG", "VALUE_MILLIONS")
plt.subplots(figsize=(20,15))
ax = plt.axes()
ax.set_title("NBA Team AVG Attendance vs Valuation in Millions:  2016-2017 Season")
sns.heatmap(valuations,linewidths=.5, annot=True, fmt='g')

A Figura 11 mostra alguns valores discrepantes interessantes, por exemplo, o Brooklyn Nets está avaliado em $1,8 bilhão, embora apresente a média de presença do público mais baixa na NBA. Esse é um dado que vale a pena analisar.

Figura 11. Plot de correlação do Seaborn da NBA sobre presença do público versus avaliação
Image shows Seaborn correlation plot NBA attendance versus                     valuation
Image shows Seaborn correlation plot NBA attendance versus valuation

Uma maneira de investigar ainda mais é executar uma regressão linear usando o pacote Statsmodels. De acordo com Statsmodels.org, o pacote Statsmodels "é um módulo Python que oferece classes e funções para a estimativa de vários modelos estatísticos diferentes, e também para realizar testes e a exploração de dados estatísticos. Há uma lista extensa de estatísticas de resultados disponível para cada estimador."

É possível instalar o pacote Statsmodels usando pip install Statsmodel. A seguir estão as três linhas necessárias para executar a regressão.

Listagem 9. Regressão linear VALUE ~ AVG

results = smf.ols('VALUE_MILLIONS ~AVG', data=attendance_valuation_df).fit()
print(results.summary())

A imagem abaixo mostra o resultado da regressão. O R quadrado mostra que aproximadamente 28 por cento da avaliação pode ser explicado pela presença do público e o valor de P igual a 0,044 cai no intervalo que é estatisticamente significativo. Um possível problema com os dados é que o plot dos valores residuais não parece totalmente aleatório. Esse é um bom começo para tentar desenvolver um modelo para explicar como começa a avaliação de uma franquia da NBA.

Figura 12. Regressão com plot residual
Image shows regression with residual plot
Image shows regression with residual plot

Uma possível maneira de agregar mais ao modelo é incluir os números do ELO de cada time. De acordo com o Wikipédia, "O sistema de classificação ELO é um método de calcular os níveis de aptidão relativos em jogos entre competidores, como o  xadrez". O sistema de classificação ELO também é usado em esportes.

Os números do ELO apresentam mais informações do que o registro de ganho/perda porque eles classificam de acordo com a força do oponente contra o qual se joga. Parece interessante investigar se o grau de habilidade de um time afeta a avaliação.

Para fazer isso, mescle os dados do ELO com esses dados, como é mostrado abaixo.

Listagem 10. Plotando o ELO

attendance_valuation_elo_df = attendance_df.merge(elo_df, how="inner", on="TEAM")
attendance_valuation_elo_df.head()
attendance_valuation_elo_df.to_csv("../data/nba_2017_att_val_elo.csv")
corr_elo = attendance_valuation_elo_df.corr()
plt.subplots(figsize=(20,15))
ax = plt.axes()
ax.set_title("NBA Team Correlation Heatmap:  2016-2017 Season (ELO, AVG Attendance, VALUATION IN MILLIONS)")
sns.heatmap(corr_elo, 
            xticklabels=corr_elo.columns.values,
            yticklabels=corr_elo.columns.values)
corr_elo
ax = sns.lmplot(x="ELO", y="AVG", data=attendance_valuation_elo_df, hue="CONF", size=12)
ax.set(xlabel='ELO Score', ylabel='Average Attendance Per Game', title="NBA Team AVG Attendance vs ELO Ranking:  2016-2017 Season")
attendance_valuation_elo_df.groupby("CONF")["ELO"].median()
attendance_valuation_elo_df.groupby("CONF")["AVG"].median()

Após a mesclagem, dois gráficos deverão ser criados. O primeiro, mostrado na Figura 13, é um novo mapa de calor de correlação. Existem algumas correlações positivas para serem examinadas mais a fundo. Especificamente, a presença do público e o ELO são dados que valem a pena plotar. No mapa de calor abaixo, quanto mais clara for a cor, mais correlacionadas as duas colunas estão. Se a matriz mostrar o mesmo valor em comparação consigo mesma, a correlação será 1 e o quadrado será bege. No caso de TOTAL e ELO, parece haver uma correlação de 0,5.

Figura 13. Mapa de calor de correlação de ELO
Image shows ELO correlation heatmap
Image shows ELO correlation heatmap

A Figura 14 mostra um plot do ELO versus a presença do público. Parece haver um relacionamento linear fraco entre o grau de habilidade de um time (CLASSIFICAÇÃO DO ELO) e a presença do público. O plot abaixo colore os plots de difusão das regiões leste e oeste separadamente, juntamente com um intervalo de confiança. O relacionamento linear fraco é representado pela linha reta passando pelos pontos no espaço X,Y.

Figura 14. ELO versus presença do público
Image shows ELO versus attendance
Image shows ELO versus attendance

Uma regressão linear ajudará a examinar mais a fundo esse relacionamento mostrado no plot.

Listagem 11. Regressão linear AVG ~ ELO

results = smf.ols('AVG ~ELO', data=attendance_valuation_elo_df).fit()
print(results.summary())

O resultado da regressão (veja a Figura 15) mostra um R quadrado de 8 por cento e um valor de P igual a 0,027, portanto, aqui também existe um sinal significativo do ponto de vista estatístico, mas ele é muito fraco.

Figura 15. Regressão do ELO versus presença do público
Image shows ELO versus attendance regression
Image shows ELO versus attendance regression

Aprendizado de máquina não supervisionado: cluster K-means

Um item final a ser considerado é usar o armazenamento em cluster k-means para criar três clusters baseados em AVG, ELO e VALUE_MILLIONS.

Listagem 12. Cluster k-means

from sklearn.cluster import
KMeans from sklearn.preprocessing import MinMaxScaler
#Only cluster on these values
numerical_df = val_housing_win_df.loc[:,["TOTAL_ATTENDANCE_MILLIONS", "ELO", "VALUE_MILLIONS", "MEDIAN_HOME_PRICE_COUNTY_MILLONS"]]

#Scale to between 0 and 1
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
print(scaler.fit(numerical_df))
print(scaler.transform(numerical_df))

#Add back to DataFrame
from sklearn.cluster import KMeans
k_means = KMeans(n_clusters=3)
kmeans = k_means.fit(scaler.transform(numerical_df))
val_housing_win_df['cluster'] = kmeans.labels_
val_housing_win_df.head()

É possível observar no plot mostrado abaixo que há três grupos distintos e que os centros dos clusters representam rótulos diferentes. Note que o sklearn MinMaxScaler é usado para dimensionar todas as colunas para um valor entre 0 e 1, para normalizar a diferença entre as escalas.

Figura 16. Clusters de times
Image shows team                     clusters
Image shows team clusters

A imagem abaixo mostra a associação ao cluster 1. A principal lição desse cluster é que nele estão contidos os melhores times da NBA e os times que têm a maior média de presença do público. É na avaliação total que ocorre uma divisão. Por exemplo, o Utah Jazz é um time muito bom de acordo com o ELO e tem uma presença do público muito boa, mas não está avaliado tão bem quanto os outros membros do cluster. Isso pode significar que há uma oportunidade para que o Utah Jazz faça pequenas mudanças que possam elevar significativamente a avaliação do time.

Figura 15. Associação ao cluster
Image shows cluster membership
Image shows cluster membership

Conclusão

Na Parte 1 desta série de duas partes, você aprendeu o básico da ciência de dados e do aprendizado de máquina e começou a explorar o relacionamento entre a avaliação, a presença do público e os times vitoriosos da NBA. O código do tutorial foi mantido em um Jupyter Notebook que pode ser consultado aqui. A Parte 2 deixa os times de lado e explora cada um dos atletas na NBA. São explorados os dados de patrocínio, o desempenho real na quadra e o poder social com o Twitter e a Wikipédia.

As lições aprendidas até agora com a exploração de dados são:

  • A avaliação de um time da NBA é afetada pela média de presença do público.
  • A classificação do ELO (registro de força do time) está relacionada à presença do público. Em linhas gerais, quanto melhor um time for, mais os fãs comparecerão nos jogos.
  • O Eastern Conference tem uma média de presença do público e uma classificação do ELO inferiores.

Recursos para download


Temas relacionados


Comentários

Acesse ou registre-se para adicionar e acompanhar os comentários.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Big data e análise de dados
ArticleID=1056795
ArticleTitle=Poder social, influência e desempenho na NBA, Parte 1: Explore a avaliação e a presença do público usando ciência de dados e aprendizado de máquina
publish-date=01192018