<jupyter_start><jupyter_text>Decision Trees<jupyter_code>import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.tree import export_graphviz
import pydot
import graphviz<jupyter_output><empty_output><jupyter_text>EXEMPLO1: Iris DatasetNo exemplo a seguir utiizaremos o Iris Dataset, disponível internamente no próprio Scikit Learn.  **Trabalhando os dados**<jupyter_code># Importando o DataSet do scikit learn
from sklearn.datasets import load_iris

iris = load_iris()

# Dividindo entre feature e target
X = iris.data[:, 2:]  # Vamos utilizar somente as colunas: petal length e petal width
y = iris.target<jupyter_output><empty_output><jupyter_text>**Treinando o modelo**<jupyter_code># Classificando com o decision tree
tree_iris = DecisionTreeClassifier(max_depth=2)
tree_iris.fit(X, y)<jupyter_output><empty_output><jupyter_text>**Verificando a acurácia**<jupyter_code>tree_iris.score(X, y)<jupyter_output><empty_output><jupyter_text>**Gerando o arquivo de visualização**<jupyter_code># Definindo o caminho/nome do arquivo .dot
arquivo = "figuras/iris_tree.dot"

# Instanciando o nome das features
labels = iris.feature_names[2:]

# Exportando o arquivo .dot
export_graphviz(
    tree_iris,
    out_file=arquivo,
    feature_names=labels,
    class_names=iris.target_names,
    rounded=True,
    filled=True)<jupyter_output><empty_output><jupyter_text>**Visualizando a Decision Tree**<jupyter_code># Visualizando o arquivo .dot
with open(arquivo) as f:
    dot_graph = f.read()
graphviz.Source(dot_graph)<jupyter_output><empty_output><jupyter_text>**Executando a predição**  A partir do modelo treinado, podemos executar predições. No exemplo abaixo, solicitamos ao modelo que classifique a partir dos valores de petal length=5 e petal width=1.5, e ele nos trouxe o valor 1, correspondente à versicolor.<jupyter_code># Imprimindo os nomes dos targets:
print(iris.target_names)
# Criando um novo dado
newFlower = [5, 1.5]

# Executando a predição:
tree_iris.predict([newFlower])<jupyter_output><empty_output><jupyter_text>**Verificando as probabilidades**  Para entender a tomada de decisão do modelo na hora de classificar, podemos verificar as probabilidades atribuídas por ele para cada possível target. Usandos os mesmos valores do exemplo anterior, podemos ver abaixoqu o modelo atribuiu 0% para setosa, 90% para versicolor e 9% para virgínica:<jupyter_code>tree_iris.predict_proba([newFlower])<jupyter_output><empty_output><jupyter_text>EXEMPLO2: Breast Cancer Dataset **Trabalhando os dados**<jupyter_code># Importando o dataset
from sklearn.datasets import load_breast_cancer

cancer = load_breast_cancer()

# Dividindo entre feature e target; treino e teste
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target)<jupyter_output><empty_output><jupyter_text>**Treinando o modelo**  Foi rodado um modelo sem limite de profundidade (max_depth=None), porém foi verificado que ao limitar a profundidade à 3, o modelo atingiu uma melhor acurácia nos dados de teste.<jupyter_code>tree_cancer = DecisionTreeClassifier(max_depth=3)

tree_cancer.fit(X_train, y_train)<jupyter_output><empty_output><jupyter_text>**Verificando a acurácia**<jupyter_code>tree_cancer.score(X_train, y_train)
tree_cancer.score(X_test, y_test)<jupyter_output><empty_output><jupyter_text>**Gerando o arquivo de visualização**<jupyter_code># Definindo o nome do arquivo com a árvore de decisão
arquivo = 'figuras/tree_cancer.dot'

export_graphviz(tree_cancer,
                out_file=arquivo,
                class_names=["malignant", "benign"],
                feature_names=cancer.feature_names,
                impurity=False,
                filled=True)

# Convertendo o arquivo .dot para .png
!dot -Tpng figuras/tree_cancer.dot -o figuras/tree_cancer.png<jupyter_output><empty_output><jupyter_text>**Visualizando a Decision Tree**<jupyter_code>from IPython.display import Image
Image("figuras/tree_cancer.png")<jupyter_output><empty_output><jupyter_text>**Importância dos Atributos**  Podemos verificar a quais atributos foi dado o maior peso na classificação, utilizando o ``feature_importances_``.<jupyter_code># Atribuindo os valores às variáveis
featuresC = cancer.feature_names
importancesC = tree_cancer.feature_importances_

# Verificando o tamanho e o tipo das variáveis
print(featuresC.dtype, featuresC.size), print(importancesC.dtype, importancesC.size);
# Criando uma estrutura vazia, com o tamanho e tipo dos dados que serão preenchidos
importancia = np.zeros(30, dtype=[('features', '<U23'), ('importances', 'float64')])
# Preenchendo os valores
importancia['features'] = featuresC
importancia['importances'] = importancesC

# Imprimindo os atributos e o percentual de importância dado pelo algoritmo
print(importancia)<jupyter_output>[('mean radius', 0.        ) ('mean texture', 0.        )
 ('mean perimeter', 0.        ) ('mean area', 0.        )
 ('mean smoothness', 0.        ) ('mean compactness', 0.        )
 ('mean concavity', 0.        ) ('mean concave points', 0.        )
 ('mean symmetry', 0.        ) ('mean fractal dimension', 0.        )
 ('radius error', 0.        ) ('texture error', 0.        )
 ('perimeter error', 0.        ) ('area error', 0.01076609)
 ('smoothness error', 0.        ) ('compactness error', 0.        )
 ('concavity error', 0.02108359) ('concave points error', 0.        )
 ('symmetry error', 0.        ) ('fractal dimension error', 0.        )
 ('worst radius', 0.        ) ('worst texture', 0.0196883 )
 ('worst perimeter', 0.        ) ('worst area', 0.12488348)
 ('worst smoothness', 0.        ) ('worst compactness', 0.        )
 ('worst concavity', 0.        ) ('worst concave points', 0.82357854)
 ('worst symmetry', 0.        ) ('worst fractal dimension', 0.        )]<jupyter_text>Podemos ver que o algoritmo deu maior importância aos atributos: worst perimeter=0.77, worst concave points=0.15, mean smoothness=0.03, worst smoothness=0.02 e area error=0.02.  Uma outra forma de visualizar a importância das features é apresentando de maneira gráfica:<jupyter_code>cancerX = list(range(len(cancer.feature_names)))  # Contando o numero de elementos do eixo x

plt.plot(tree_cancer.feature_importances_, 'o')   # Plotando o feture importances
plt.xticks(cancerX, featuresC, rotation=90)       # Inserindo rótulo
plt.ylim(0, 1);                                   # Limitando o eixo y de 0 a 1<jupyter_output><empty_output><jupyter_text>Exemplo 3: Titanic Dataset **Carregando os dados**<jupyter_code>titanic = pd.read_csv('titanic.csv')

titanic.head()<jupyter_output><empty_output><jupyter_text>**Pre-processando dos dados**<jupyter_code># Retirando as colunas que não contribuem para a classificação dos resultados
titanic = pd.DataFrame(titanic, columns=['PClass', 'Age', 'SexCode', 'Survived'])
# Verificando se há missing values
titanic.isnull().sum()<jupyter_output><empty_output><jupyter_text>Há 557 valores nulos na coluna de idade (age). Para amenizar esse problema, preencheremos tais valores com a média dos valores válidos.<jupyter_code># Preenchendo os valores nulos com a média
titanic['Age'].fillna(titanic['Age'].mean(), inplace = True)<jupyter_output><empty_output><jupyter_text>Para que o algoritmo funcione, necessitamos que todas as colunas possuam valores numéricos. A coluna PClass possui valores categóricos. Se simplesmente modificarmos os valores de 1st, 2st e 3st para 1, 2 e 3, o algoritmo pode interpretar erroneamente que há ordem nessa categoria, isso não é um problema nesse caso, mas em outros exemplos pode acarretar em uma resposta incorreta do algoritmo. Portanto, para utilizar uma abordagem geral, vamos transformar essa em colunas preenchidas com valores binários utilizando a função do pandas ``pd.get_dummies()``.<jupyter_code># Transformando os valores categóricos da coluna Class em valoer numéricos
titanic2 = pd.get_dummies(titanic)

titanic2.head()
# Dividindo entre feture e target e aplicando o feature selection
X_titanic = titanic2.drop(['Survived'], axis=1)
y_titanic = titanic2.Survived<jupyter_output><empty_output><jupyter_text>**Treinando o modelo**<jupyter_code>tree_titanic = DecisionTreeClassifier(max_depth=3)

tree_titanic.fit(X_titanic, y_titanic)<jupyter_output><empty_output><jupyter_text>**Verificando a acurácia**<jupyter_code>tree_titanic.score(X_titanic, y_titanic)
print(X_titanic[:0])
tree_titanic.feature_importances_<jupyter_output>Empty DataFrame
Columns: [Age, SexCode, PClass_*, PClass_1st, PClass_2nd, PClass_3rd]
Index: []<jupyter_text>**Gerando o arquivo de visualização**<jupyter_code># Definindo o nome do arquivo com a árvore de decisão
arquivo = 'figuras/tree_titanic.dot'

features = list(X_titanic[:0]) # Gerando a lista de nome das features

export_graphviz(tree_titanic,
                out_file=arquivo,
                class_names=["survived", "not survived"],
                feature_names=features,
                impurity=False,
                filled=True)

# Convertendo o arquivo .dot para .png
!dot -Tpng figuras/tree_titanic.dot -o figuras/tree_titanic.png<jupyter_output><empty_output><jupyter_text>**Visualisando a Decision Tree**<jupyter_code>from IPython.display import Image
Image("figuras/tree_titanic.png")<jupyter_output><empty_output><jupyter_text>**Importância dos atributos**<jupyter_code>import matplotlib.pyplot as plt

eleX = list(range(X_titanic.shape[1]))  # Conta os elementos do eixo x para plotar o nome

plt.plot(tree_titanic.feature_importances_, 'o')
plt.xticks(eleX, features, rotation='vertical')
plt.ylim(0, 1);<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10067322630761263, 'fraction_numerical': 0.014293112377006732, 'mean_word_length': 5.352631578947369, 'pattern_counts': {'":': 0, '<': 96, '<?xml version=': 0, '>': 95, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '24', 'dir': 'jupyter-structured-clean-dedup', 'id': '194254', 'license': 'MIT', 'n_tokens_mistral': 3568, 'n_tokens_neox': 3392, 'n_words': 857, 'path': 'Python/05 Scikit-learn/04.02 Decision Trees - Exemplos.ipynb', 'repo_name': 'rdemarqui/Data-Science-B-sico', 'size': '9655'}