Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

1
resposta

Faça como eu fiz: ajustando modelos de machine learning

import pandas as pd
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score, classification_report
url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.data.csv"

colunas = [
'Pregnancies', 'Glucose', 'BloodPressure', 'SkinThickness',
'Insulin', 'BMI', 'DiabetesPedigreeFunction',
'Age', 'Outcome'
]

df = pd.read_csv(url, names=colunas)
X = df.drop('Outcome', axis=1)
y = df['Outcome']
X_train, X_test, y_train, y_test = train_test_split(
X, y,
test_size=0.3,
random_state=42
)
tree = DecisionTreeClassifier(random_state=42)
param_grid = {
'max_depth': [3, 5, 7, 10],
'min_samples_split': [2, 5, 10],
'criterion': ['gini', 'entropy']
}
grid_search = GridSearchCV(
estimator=tree,
param_grid=param_grid,
cv=5,
scoring='accuracy'
)

grid_search.fit(X_train, y_train)

print("Melhores parâmetros:")
print(grid_search.best_params_)

print("\nMelhor score:")
print(grid_search.best_score_)

best_model = grid_search.best_estimator_
y_pred = best_model.predict(X_test)

print("\nAcurácia no conjunto de teste:")
print(accuracy_score(y_test, y_pred))

print("\nRelatório:")
print(classification_report(y_test, y_pred))
import pandas as pd

importancias = best_model.feature_importances_

resultado = pd.DataFrame({
'Feature': X.columns,
'Importancia': importancias
})

resultado = resultado.sort_values(
by='Importancia',
ascending=False
)

print(resultado)
import matplotlib.pyplot as plt

resultado.plot(
x='Feature',
y='Importancia',
kind='bar'
)

plt.title('Importância das Variáveis')
plt.ylabel('Importância')
plt.xlabel('Características')
plt.tight_layout()
plt.show()

Melhores parâmetros:
{'criterion': 'gini', 'max_depth': 5, 'min_samples_split': 10}

Melhor score:
0.7522845275181724

Acurácia no conjunto de teste:
0.7532467532467533

Relatório:
precision recall f1-score support

       0       0.78      0.86      0.82       151
       1       0.68      0.55      0.61        80

accuracy                           0.75       231

macro avg 0.73 0.71 0.71 231
weighted avg 0.75 0.75 0.75 231

                Feature  Importancia

1 Glucose 0.551588
5 BMI 0.198030
7 Age 0.170566
6 DiabetesPedigreeFunction 0.046163
2 BloodPressure 0.033652
0 Pregnancies 0.000000
3 SkinThickness 0.000000
4 Insulin 0.000000

1 resposta

Olá, Marcelo. Como vai?

Parabéns pela excelente implementação! O seu código demonstra uma aplicação sólida e muito bem estruturada dos conceitos de Machine Learning. Você cobriu todo o fluxo essencial: desde o carregamento dos dados, divisão em treino e teste, otimização de hiperparâmetros com o GridSearchCV, até a avaliação detalhada e análise de importância das variáveis.

Como o objetivo da atividade "Faça como eu fiz" é consolidar o aprendizado, vou trazer alguns complementos técnicos e boas práticas baseados nos seus resultados para enriquecer ainda mais o seu estudo:

1. Análise do Relatório de Classificação (Classification Report)

A sua acurácia geral no conjunto de teste ficou em 75.3%, o que é um bom resultado inicial. No entanto, ao olharmos para as classes individualmente, podemos notar um comportamento comum em problemas médicos:

  • Classe 0 (Não possui diabetes): Teve um ótimo desempenho, com um recall de 0.86. Isso significa que o modelo identifica muito bem as pessoas que não estão doentes.
  • Classe 1 (Possui diabetes): O modelo encontrou mais dificuldades aqui. O recall foi de 0.55, indicando que o modelo deixa passar quase metade dos casos positivos reais de diabetes (falsos negativos).

Sugestão de Boas Práticas: Em contextos de saúde, o falso negativo costuma ser mais perigoso do que o falso positivo. Para tentar melhorar o diagnóstico da classe 1, você poderia experimentar o parâmetro class_weight='balanced' dentro do DecisionTreeClassifier, ajudando a árvore a dar mais peso para a classe minoritária.

2. Importância das Variáveis (Feature Importance)

O seu gráfico de barras trouxe um insight valioso: as variáveis Glucose, BMI e Age dominam a tomada de decisão da árvore de decisão. Por outro lado, Pregnancies, SkinThickness e Insulin receberam importância 0.000000.

  • Por que isso acontece? Como a sua árvore teve a profundidade máxima limitada (max_depth: 5) pelo Grid Search para evitar o overfitting, ela selecionou apenas os atributos que geravam o maior ganho de informação nos primeiros cortes (nós).

3. Próximos Passos para Evoluir o Modelo

Se quiser continuar explorando e melhorando esses números, deixo três sugestões bem bacanas:

  • Feature Engineering: Como o dataset Pima Indians possui vários valores que estão como zero mas clinicamente deveriam ser nulos (como BMI ou BloodPressure zerados), tratar esses zeros aplicando a média ou a mediana antes de treinar o modelo pode melhorar a precisão.
  • Métricas Alternativas no Grid Search: Você utilizou scoring='accuracy'. Experimente trocar para scoring='f1' ou scoring='recall' no GridSearchCV para focar a otimização na descoberta dos casos positivos.
  • Testar Novos Algoritmos: A árvore de decisão é um excelente ponto de partida pela sua interpretabilidade. O próximo passo ideal seria testar o Random Forest (RandomForestClassifier), que combina várias árvores e costuma reduzir a variância e os erros do modelo.

Continue com esse ótimo ritmo de estudos e implementações!

Espero que possa ter lhe ajudado!