Classificador de árvore de decisão explicado: um guia visual…

Classificador de árvore de decisão explicado: um guia visual...

ALGORITMO DE CLASSIFICAÇÃO

Um novo olhar sobre nossa árvore invertida favorita

Rumo à Ciência de Dados

Árvores de decisão estão por toda secção no aprendizagem de máquina, adoradas por sua saída intuitiva. Quem não patroa um fluxograma simples de “se-então”? Apesar de sua popularidade, é surpreendente o quão reptador é encontrar uma explicação clara e passo a passo de uma vez que as Árvores de Decisão funcionam. (Na verdade, estou envergonhado pelo tempo que levei para realmente entender uma vez que o algoritmo funciona.)

Logo, nesta estudo, vou focar nos fundamentos da construção de árvores. Vamos desempacotar exatamente o que está acontecendo em cada nó e por quê, da raiz às folhas finais (com visuais, é evidente).

Todos os visuais: criados pelo responsável usando o Canva Pro. Otimizado para dispositivos móveis; pode parecer grande demais no desktop.

Um classificador de Árvore de Decisão cria uma árvore invertida para fazer previsões, começando no topo com uma pergunta sobre um recurso importante em seus dados, logo ramifica-se com base nas respostas. Conforme você segue essas ramificações para grave, cada paragem faz outra pergunta, estreitando as possibilidades. Esse jogo de perguntas e respostas continua até você chegar ao fundo — um nó folha — onde você obtém sua previsão ou classificação final.

Árvore de decisão é um dos algoritmos de aprendizagem de máquina mais importantes — é uma série de perguntas de sim ou não.

Ao longo deste item, usaremos oriente conjunto de dados de golfe sintético (inspirado em [1]) uma vez que exemplo. Oriente conjunto de dados prevê se uma pessoa jogará golfe com base nas condições climáticas.

Colunas: ‘Perspectiva’ (já codificado uma vez que ensolarado, nublado, pluvial), ‘Temperatura’ (em Fahrenheit), ‘Umidade’ (em %), ‘Vento’ (sim/não) e ‘Reproduzir’ (recurso de tramontana)
# Import libraries
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import pandas as pd
import numpy as np

# Load data
dataset_dict = {
'Outlook': ['sunny', 'sunny', 'overcast', 'rainy', 'rainy', 'rainy', 'overcast', 'sunny', 'sunny', 'rainy', 'sunny', 'overcast', 'overcast', 'rainy', 'sunny', 'overcast', 'rainy', 'sunny', 'sunny', 'rainy', 'overcast', 'rainy', 'sunny', 'overcast', 'sunny', 'overcast', 'rainy', 'overcast'],
'Temperature': [85.0, 80.0, 83.0, 70.0, 68.0, 65.0, 64.0, 72.0, 69.0, 75.0, 75.0, 72.0, 81.0, 71.0, 81.0, 74.0, 76.0, 78.0, 82.0, 67.0, 85.0, 73.0, 88.0, 77.0, 79.0, 80.0, 66.0, 84.0],
'Humidity': [85.0, 90.0, 78.0, 96.0, 80.0, 70.0, 65.0, 95.0, 70.0, 80.0, 70.0, 90.0, 75.0, 80.0, 88.0, 92.0, 85.0, 75.0, 92.0, 90.0, 85.0, 88.0, 65.0, 70.0, 60.0, 95.0, 70.0, 78.0],
'Wind': [False, True, False, False, False, True, True, False, False, False, True, True, False, True, True, False, False, True, False, True, True, False, True, False, False, True, False, False],
'Play': ['No', 'No', 'Yes', 'Yes', 'Yes', 'No', 'Yes', 'No', 'Yes', 'Yes', 'Yes', 'Yes', 'Yes', 'No', 'No', 'Yes', 'Yes', 'No', 'No', 'No', 'Yes', 'Yes', 'Yes', 'Yes', 'Yes', 'Yes', 'No', 'Yes']
}
df = pd.DataFrame(dataset_dict)

# Preprocess data
df = pd.get_dummies(df, columns=['Outlook'], prefix='', prefix_sep='', dtype=int)
df['Wind'] = df['Wind'].astype(int)
df['Play'] = (df['Play'] == 'Yes').astype(int)

# Reorder the columns
df = df[['sunny', 'overcast', 'rainy', 'Temperature', 'Humidity', 'Wind', 'Play']]

# Prepare features and target
X, y = df.drop(columns='Play'), df['Play']

# Split data
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.5, shuffle=False)

# Display results
print(pd.concat([X_train, y_train], axis=1), 'n')
print(pd.concat([X_test, y_test], axis=1))

O classificador Decision Tree opera dividindo recursivamente os dados com base nos recursos mais informativos. Veja uma vez que funciona:

  1. Comece com todo o conjunto de dados no nó raiz.
  2. Selecione o melhor recurso para dividir os dados (com base em medidas uma vez que impureza de Gini).
  3. Crie nós filhos para cada valor provável do recurso selecionado.
  4. Repita as etapas 2–3 para cada nó fruto até que um critério de paragem seja atendido (por exemplo, profundidade máxima atingida, amostras mínimas por folha ou nós de folha puros).
  5. Atribua a classe majoritária a cada nó folha.

No scikit-learn, o algoritmo de árvore de decisão é chamado CART (Classification and Regression Trees). Ele constrói árvores binárias e normalmente segue estas etapas:

  1. Comece com todas as amostras de treinamento no nó raiz.
Começando com o nó raiz contendo todas as 14 amostras de treinamento, descobriremos a melhor maneira de apresentar e o melhor ponto para dividir os dados para estrear a erigir a árvore.

2. Para cada recurso:
a. Classifique os valores dos recursos.
b. Considere todos os limites possíveis entre valores adjacentes uma vez que potenciais pontos de partilha.

Neste nó raiz, há 23 pontos de partilha para verificar. Colunas binárias têm somente um ponto de partilha.
def potential_split_points(attr_name, attr_values):
sorted_attr = np.sort(attr_values)
unique_values = np.unique(sorted_attr)
split_points = [(unique_values[i] + unique_values[i+1]) / 2 for i in range(len(unique_values) - 1)]
return {attr_name: split_points}

# Calculate and display potential split points for all columns
for column in X_train.columns:
splits = potential_split_points(column, X_train[column])
for attr, points in splits.items():
print(f"{attr:11}: {points}")

3. Para cada ponto de partilha potencial:
a. Calcule a impureza (por exemplo, impureza de Gini) do nó atual.
b. Calcule a média ponderada das impurezas.

Por exemplo, para o recurso “ensolarado” com ponto de partilha 0,5, a impureza (uma vez que “Impureza de Gini”) é calculada para ambas as partes do conjunto de dados.
Outro exemplo, o mesmo processo pode ser feito para recursos contínuos uma vez que “Temperatura”.
def gini_impurity(y):
p = np.bincount(y) / len(y)
return 1 - np.sum(p**2)

def weighted_average_impurity(y, split_index):
n = len(y)
left_impurity = gini_impurity(y[:split_index])
right_impurity = gini_impurity(y[split_index:])
return (split_index * left_impurity + (n - split_index) * right_impurity) / n

# Sort 'sunny' feature and corresponding labels
sunny = X_train['sunny']
sorted_indices = np.argsort(sunny)
sorted_sunny = sunny.iloc[sorted_indices]
sorted_labels = y_train.iloc[sorted_indices]

# Find split índice for 0.5
split_index = np.searchsorted(sorted_sunny, 0.5, side='right')

# Calculate impurity
impurity = weighted_average_impurity(sorted_labels, split_index)

print(f"Weighted average impurity for 'sunny' at split point 0.5: {impurity:.3f}")

4. Depois de calcular todas as impurezas para todos os recursos e pontos de partilha, escolha o menor.

O recurso “overcast” com ponto de partilha 0,5 fornece a menor impureza. Isso significa que a partilha será a mais pura dentre todos os outros pontos de partilha!
def calculate_split_impurities(X, y):
split_data = []

for feature in X.columns:
sorted_indices = np.argsort(X[feature])
sorted_feature = X[feature].iloc[sorted_indices]
sorted_y = y.iloc[sorted_indices]

unique_values = sorted_feature.unique()
split_points = (unique_values[1:] + unique_values[:-1]) / 2

for split in split_points:
split_index = np.searchsorted(sorted_feature, split, side='right')
impurity = weighted_average_impurity(sorted_y, split_index)
split_data.append({
'feature': feature,
'split_point': split,
'weighted_avg_impurity': impurity
})

return pd.DataFrame(split_data)

# Calculate split impurities for all features
calculate_split_impurities(X_train, y_train).round(3)

5. Crie dois nós filhos com base no recurso escolhido e no ponto de partilha:
– Rebento esquerdo: amostras com valor de propriedade <= ponto de partilha
– Rebento recta: amostras com valor de propriedade > ponto de partilha

O ponto de partilha selecionado dividiu os dados em duas partes. Porquê uma secção já é pura (o lado recta! É por isso que sua impureza é baixa!), precisamos somente continuar a árvore no nó esquerdo.

6. Repita recursivamente as etapas 2–5 para cada nó fruto. Você também pode parar até que um critério de paragem seja atendido (por exemplo, profundidade máxima atingida, número mínimo de amostras por nó folha ou subtracção mínima de impurezas).

# Calculate split impurities forselected índice
selected_index = [4,8,3,13,7,9,10] # Change it depending on which indices you want to check
calculate_split_impurities(X_train.iloc[selected_index], y_train.iloc[selected_index]).round(3)
Sua visita nos ajuda a continuar oferecendo o melhor para você! qj l qk ql">from sklearn.tree import DecisionTreeClassifier

# The whole Training Phase above is done inside sklearn like this
dt_clf = DecisionTreeClassifier()
dt_clf.fit(X_train, y_train)

Árvore Final Completa

O rótulo de classe de um nó folha é a classe majoritária das amostras de treinamento que alcançaram esse nó.

A da direita é a árvore final que será usada para classificação. Não precisamos mais das amostras neste momento.
import matplotlib.pyplot as plt
from sklearn.tree import plot_tree
# Plot the decision tree
plt.figure(figsize=(20, 10))
plot_tree(dt_clf, filled=True, feature_names=X.columns, class_names=['Not Play', 'Play'])
plt.show()
Nesta saída do scikit-learn, as informações do nó não folha também são armazenadas, uma vez que o número de amostras e o número de cada classe no nó (valor).

Veja Sua visita nos ajuda a continuar oferecendo o melhor para você! vez que o processo de previsão funciona depois que a árvore de decisão é treinada:

  1. Comece no nó raiz da árvore de decisão treinada.
  2. Avalie o recurso e a requisito de partilha no nó atual.
  3. Repita o passo 2 em cada nó subsequente até chegar a um nó folha.
  4. O rótulo de classe do nó folha se torna a previsão para a novidade instância.
Precisamos somente das colunas que são solicitadas pela árvore. Além de “overcast” e “Temperature”, outros valores não importam para fazer a previsão.
# Make predictions
y_pred = dt_clf.predict(X_test)
print(y_pred)
A árvore de decisão fornece uma precisão adequada. Porquê nossa árvore verifica somente dois recursos, ela pode não conquistar muito a propriedade do conjunto de teste.
# Evaluate the classifier
print(f"Accuracy: {accuracy_score(y_test, y_pred)}")

Árvores de decisão têm vários parâmetros importantes que controlam seu prolongamento e complicação:

1 . Profundidade Máxima: Isso define a profundidade máxima da árvore, o que pode ser uma utensílio valiosa para evitar overfitting.

👍 Dica útil: Considere estrear com uma árvore rasa (talvez de 3 a 5 níveis de profundidade) e aumentar gradualmente a profundidade.

Comece com uma árvore superficial (por exemplo, profundidade de 3 a 5) e aumente gradualmente até encontrar o estabilidade ideal entre a complicação do protótipo e o desempenho em dados de validação.

2. Amostras mínimas divididas: Oriente parâmetro determina o número mínimo de amostras necessárias para dividir um nó interno.

👍 Dica útil: Definir isso para um valor mais cume (muro de 5–10% dos seus dados de treinamento) pode ajudar a evitar que a árvore crie muitas divisões pequenas e específicas que podem não ser muito generalizadas para novos dados.

3. Amostras mínimas de folhas: Isso especifica o número mínimo de amostras necessárias em um nó folha.

👍 Dica útil: Escolha um valor que garanta que cada folha represente um subconjunto significativo dos seus dados (aproximadamente 1–5% dos seus dados de treinamento). Isso pode ajudar a evitar previsões excessivamente específicas.

4. Critério: A função usada para medir a qualidade de uma partilha (geralmente “gini” para impureza de Gini ou “entropia” para lucro de informação).

👍 Dica útil: Embora Gini seja geralmente mais simples e rápido de calcular, a entropia geralmente tem melhor desempenho para problemas multiclasse. Dito isso, eles frequentemente dão resultados semelhantes.

Exemplo de cômputo de entropia para ‘ensolarado’ com ponto de partilha 0,5.

Porquê qualquer algoritmo em aprendizagem de máquina, as Árvores de Decisão têm seus pontos fortes e limitações.

Prós:

  1. Interpretabilidade: Fácil de entender e visualizar o processo de tomada de decisão.
  2. Sem dimensionamento de recursos: Pode manipular dados numéricos e categóricos sem normalização.
  3. Lida com relacionamentos não lineares: Pode conquistar padrões complexos nos dados.
  4. Preço do recurso: Fornece uma indicação clara de quais recursos são mais importantes para a previsão.

Contras:

  1. Sobreajuste: Propenso a gerar árvores excessivamente complexas que não generalizam muito, mormente com pequenos conjuntos de dados.
  2. Instabilidade:Pequenas alterações nos dados podem resultar na geração de uma árvore completamente dissemelhante.
  3. Tendencioso com conjuntos de dados desequilibrados:Pode ser tendencioso em relação às classes dominantes.
  4. Incapacidade de extrapolar: Não é provável fazer previsões além do pausa dos dados de treinamento.

Em nosso exemplo de golfe, uma Árvore de Decisão pode gerar regras muito precisas e interpretáveis ​​para sentenciar se jogar golfe com base nas condições climáticas. No entanto, ela pode se ajustar demais a combinações específicas de condições se não for podada corretamente ou se o conjunto de dados for pequeno.

Classificadores de Árvores de Decisão são uma ótima utensílio para resolver muitos tipos de problemas em aprendizagem de máquina. Eles são fáceis de entender, podem mourejar com dados complexos e nos mostram uma vez que eles tomam decisões. Isso os torna úteis em muitas áreas, de negócios a medicina. Embora Árvores de Decisão sejam poderosas e interpretáveis, elas são frequentemente usadas uma vez que blocos de construção para métodos de conjunto mais avançados, uma vez que Random Forests ou Gradient Boosting Machines.

# Import libraries
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from sklearn.tree import plot_tree, DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# Load data
dataset_dict = {
'Outlook': ['sunny', 'sunny', 'overcast', 'rainy', 'rainy', 'rainy', 'overcast', 'sunny', 'sunny', 'rainy', 'sunny', 'overcast', 'overcast', 'rainy', 'sunny', 'overcast', 'rainy', 'sunny', 'sunny', 'rainy', 'overcast', 'rainy', 'sunny', 'overcast', 'sunny', 'overcast', 'rainy', 'overcast'],
'Temperature': [85.0, 80.0, 83.0, 70.0, 68.0, 65.0, 64.0, 72.0, 69.0, 75.0, 75.0, 72.0, 81.0, 71.0, 81.0, 74.0, 76.0, 78.0, 82.0, 67.0, 85.0, 73.0, 88.0, 77.0, 79.0, 80.0, 66.0, 84.0],
'Humidity': [85.0, 90.0, 78.0, 96.0, 80.0, 70.0, 65.0, 95.0, 70.0, 80.0, 70.0, 90.0, 75.0, 80.0, 88.0, 92.0, 85.0, 75.0, 92.0, 90.0, 85.0, 88.0, 65.0, 70.0, 60.0, 95.0, 70.0, 78.0],
'Wind': [False, True, False, False, False, True, True, False, False, False, True, True, False, True, True, False, False, True, False, True, True, False, True, False, False, True, False, False],
'Play': ['No', 'No', 'Yes', 'Yes', 'Yes', 'No', 'Yes', 'No', 'Yes', 'Yes', 'Yes', 'Yes', 'Yes', 'No', 'No', 'Yes', 'Yes', 'No', 'No', 'No', 'Yes', 'Yes', 'Yes', 'Yes', 'Yes', 'Yes', 'No', 'Yes']
}
df = pd.DataFrame(dataset_dict)

# Prepare data
df = pd.get_dummies(df, columns=['Outlook'], prefix='', prefix_sep='', dtype=int)
df['Wind'] = Sua visita nos ajuda a continuar oferecendo o melhor para você! = (df['Play'] == 'Yes').astype(int)

# Split data
X, y = df.drop(columns='Play'), df['Play']
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.5, shuffle=False)

# Train model
dt_clf = DecisionTreeClassifier(
max_depth=None, # Maximum depth of the tree
min_samples_split=2, # Minimum number of samples required to split an internal node
min_samples_leaf=1, # Minimum number of samples required to be at a leaf node
criterion='gini' # Function to measure the quality of a split
)
dt_clf.fit(X_train, y_train)

# Make predictions
y_pred = dt_clf.predict(X_test)

# Evaluate model
print(f"Accuracy: {accuracy_score(y_test, y_pred)}")

# Visualize tree
plt.figure(figsize=(20, 10))
plot_tree(dt_clf, filled=True, feature_names=X.columns,
class_names=['Not Play', 'Play'], impurity=False)
plt.show()

Adriano Pina

Adriano Pina

Análise de Sistemas | SEO e Google Ads | Fundador da Loja Script PHP Aqui & Marca Shoslh de tecnologia

Especialista em transformar ideias em soluções digitais e acelerar o crescimento online.

Deixe um comentário

Tem perguntas? Nos envia sua mensagem 24/7!

(17) 99100-0874

Endereço & Contato

Centro, Interior de São Paulo
E-mail: [email protected]

Links Úteis
BAIXAR APP | SCRIPT PHP AQUI
Certificados
0
    0
    Seu carrinho
    Seu carrinho está vazio

    Usamos cookies para garantir que oferecemos a melhor experiência em nosso site. 

       

    X

    Clique em um de nossos representantes abaixo para conversar no WhatsApp ou envie um email para: 📧 [email protected]

    Precisa de ajuda fale conosco?