Sua primeira árvore de decisão em Python (NFL Combine)
O desempenho de um jogador no NFL Combine pode prever se ele será selecionado ou não? Vamos construir um modelo para descobrir!
O que é uma Árvore de Decisão?
Uma árvore de decisão é um algoritmo de aprendizado de máquina usado para tarefas de classificação e regressão. É um tipo de algoritmo de aprendizado supervisionado, o que significa que é treinado em dados rotulados. A ideia básica por trás de uma árvore de decisão é criar um modelo que preveja o valor de uma variável de destino com base em várias variáveis de entrada.
Como podemos usá-lo aqui?
Conforme declarado acima, as árvores de decisão podem ser usadas para classificação (se um jogador será selecionado ou não) com dados rotulados (os resultados do NFL Combine do passado).
Vamos implementar isso em Python (caderno completo encontrado aqui:https://github.com/ant-vessicchio/learn_data_science_through_sports/blob/main/NFL_Combine/NFL_Combine_1st_Decision_Tree.ipynb)
Primeiro, as importações que precisaremos:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
from sklearn import tree
master_table = master_table = pd.read_csv("NFL.csv")
master_table.head()
X = master_table.iloc[:,3:9]
Y = master_table.iloc[:,-1]
#Drop Records Containing Null Values
X.dropna(inplace=True)
X.isnull().sum() #Check
O que isto significa?
Essa é uma técnica utilizada em algoritmos de aprendizado de máquina com o objetivo de avaliar o desempenho de um modelo sem viés.
O conjunto de treinamento é a parte dos dados usada para treinar o modelo de aprendizado de máquina. Nesse conjunto de dados, o modelo “conhece” o resultado (ele é apresentado com o rótulo de saída de Y) e usará essas informações para “ajustar” um modelo que será capaz de generalizar para dados novos e “invisíveis”.
O conjunto de teste é usado para avaliar o desempenho do modelo treinado em dados novos e não vistos. Os dados de teste incluem dados de entrada e rótulos de saída correspondentes, mas os rótulos de saída __não__ são usados durante o teste. Em vez disso, o modelo faz previsões sobre os dados de teste e as saídas previstas são comparadas com as saídas reais para avaliar o desempenho do modelo.
X_train, X_test, y_train, y_test = train_test_split(X,Y, test_size = 0.3, random_state=100)
Treinando e avaliando o modelo
Usaremos o DecisionTreeClassifier no sklearn. A primeira etapa é criar uma instância da classe e especificar quaisquer hiperparâmetros que você deseja usar. Alguns dos hiperparâmetros comumente usados incluem:
- max_depth: a profundidade máxima da árvore de decisão
- min_samples_split: o número mínimo de amostras necessárias para dividir um nó interno
- critério: a função usada para medir a qualidade de uma divisão (por exemplo, 'gini' ou 'entropia')
Não usaremos mais do que isso por enquanto. E eu encorajo você a ler a documentação do sklearn para mais informações!
https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html
clf = DecisionTreeClassifier(criterion = 'gini',min_samples_split = 3, max_depth = 3)
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
print(f" Accuracy score: {accuracy_score(y_test,y_pred)}")
Visualize o que está acontecendo:
Um recurso muito interessante de uma árvore de decisão são as visualizações que elas podem fornecer. Onde você pode ver essencialmente o ponto de corte para cada recurso na tomada de decisão, quantas amostras foram classificadas em cada classe e o índice gini que é a medida de quão bem um determinado atributo separa os exemplos de treinamento em uma árvore de decisão.
plt.figure(figsize=(12,8))
from sklearn import tree
tree.plot_tree(clf.fit(X_train,y_train), feature_names = X_train.columns )
plt.show()
Um recurso muito interessante de uma árvore de decisão é a geração da importância do recurso. A importância do recurso em uma árvore de decisão refere-se a uma medida de quão importante cada recurso ou variável de entrada é na determinação da saída final da árvore.
# let's create a dictionary of features and their importance values
feat_dict= {}
for col, val in sorted(zip(X_train.columns, clf.feature_importances_),key=lambda x:x[1],reverse=True):
feat_dict[col]=val
feat_df = pd.DataFrame({'Feature':feat_dict.keys(),'Importance':feat_dict.values()})
feat_df
E para fazer uma ilustração simples da importância do recurso:
import seaborn as sns
values = feat_df.Importance
idx = feat_df.Feature
plt.figure(figsize=(10,8))
clrs = ['green' if (x < max(values)) else 'red' for x in values ]
sns.barplot(y=idx,x=values,palette=clrs).set(title='Feature Importance - Player Drafted (Y/N)')
plt.show()
Algumas ideias:
- Alterar/adicionar hiperparâmetros
- Construa um modelo para cada posição e veja se isso melhora a precisão!
- Talvez tente lidar com os dados ausentes de maneira diferente?
Se você gostou deste artigo, comente abaixo, siga-me para obter mais conteúdo e acompanhe todo o meu curso gratuito “Aprenda ciência de dados através do esporte” hospedado no meu GitHub e SubReddit:
Além disso, sinta-se à vontade para entrar em contato comigo no LinkedIn!https://www.linkedin.com/in/anthony-vessicchio/
Muito obrigado e espero que tenha gostado deste artigo!





































![O que é uma lista vinculada, afinal? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)