Decision Tree


In [27]:
import os
import subprocess
import pandas as pd
import math
import numpy as np
from sklearn.tree import DecisionTreeClassifier, export_graphviz

In [28]:
headers = ["buying", "maint", "doors", "persons","lug_boot", "safety", "class"]
data = pd.read_csv("carData.csv", header=None, names=headers)

data = data.take(np.random.permutation(len(data)))

No código acima, faremos a leitura do arquivo, informando que não há cabeçário (obrigatório) e a nossa coluna 6 (0-6) representa a label


In [29]:
data.head()


Out[29]:
buying maint doors persons lug_boot safety class
913 med vhigh 3 more med med acc
1321 low vhigh 2 more big med acc
478 high vhigh 3 more small med unacc
1389 low vhigh 5more 4 med low unacc
581 high high 3 4 med high acc

In [30]:
data.dtypes


Out[30]:
buying      object
maint       object
doors       object
persons     object
lug_boot    object
safety      object
class       object
dtype: object

O problema é que nossos dados categóricos são strings. Então precisamos converter em representantes numéricos para aplicarmos no algoritmo


In [31]:
for h in headers:
    data[h] = data[h].astype('category')
    data[h] = data[h].cat.codes

data.set_index("class", inplace=True)
data.head()


Out[31]:
buying maint doors persons lug_boot safety
class
0 2 3 1 2 1 2
0 1 3 0 2 0 2
2 0 3 1 2 2 2
2 1 3 3 1 1 1
0 0 0 1 1 1 0

Faremos a separação dos dados em conjunto de treino e teste


In [32]:
size = len(data)
trainSize = int(math.floor(size * 0.7))
trainData = data[:trainSize]
testData = data[trainSize:]

Agora ok!

Vamos ao que interessa...


In [33]:
dTree = DecisionTreeClassifier(criterion="entropy")
dTree.fit(trainData.ix[:,0:6], trainData.index)


Out[33]:
DecisionTreeClassifier(class_weight=None, criterion='entropy', max_depth=None,
            max_features=None, max_leaf_nodes=None, min_samples_leaf=1,
            min_samples_split=2, min_weight_fraction_leaf=0.0,
            presort=False, random_state=None, splitter='best')

In [34]:
dTree.predict(testData.ix[:, 0:6])
dTree.score(testData.ix[:, 0:6], testData.index)


Out[34]:
0.96724470134874763

Atividades

  1. Utilizamos a medida de Entropia como fator de decisão (medida de impureza de um nó). Teste o mesmo conjunto randômico de dados para a medida Gini e compare os resultados. Ref1.: http://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html#sklearn.tree.DecisionTreeClassifier Ref2.: https://en.wikipedia.org/wiki/Decision_tree_learning

  2. Aplique Decision Tree em outro dataset (link abaixo) e analise os resultados. Procure identificar (se há) relações entre as features (correlacionadas, por exemplo) e faça testes eliminando as que você achar desnecessárias, de forma a tentar melhorar seu classificador, seja em predição ou perfomance. Dataset: https://archive.ics.uci.edu/ml/datasets/Wine+Quality

  3. Execute a função abaixo para gerar a árvore que representa seu classificador (ambos utilizando entropia e gini como medidas). Analise a saida, entendendo como ela foi criada e os seus respectivos valores em relação a medida utilizada. Reflexão: seria possível construir nosso classificador apenas utilizando a estrutura condicional if-else?


In [ ]:
def visualize_tree(tree, feature_names):
    """Cria png que representa a arvore gerada.

    Args
    ----
    tree -- DecsisionTree.
    feature_names -- vetor com os nomes das features.
    """
    with open("dt.dot", 'w') as f:
        export_graphviz(tree, out_file=f,
                        feature_names=feature_names)

    command = ["dot", "-Tpng", "dt.dot", "-o", "dt.png"]
    try:
        subprocess.check_call(command)
    except:
        exit("Nao foi possivel gerar a arvore.")