# ==========================================================
# Importação das bibliotecas essenciais
# ==========================================================
import numpy as np
import pandas as pd
from sklearn import datasets
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
# ==========================================================
# Carregamento do dataset Iris
# ==========================================================
# O Iris é um conjunto de dados clássico usado em Machine Learning.
# Ele contém 150 amostras de flores divididas em 3 espécies:
# Setosa, Versicolor e Virginica.
# Cada amostra possui 4 medidas físicas (features).
dataset = datasets.load_iris()
# Transformamos os dados em um DataFrame para facilitar a visualização
# e manipulação tabular dos dados.
df = pd.DataFrame(dataset.data, columns=dataset.feature_names)
# A coluna "target" representa a espécie da flor (classe que queremos prever)
df["target"] = dataset.target
# ==========================================================
# Exploração inicial dos dados
# ==========================================================
# Visualizar os primeiros registros ajuda a entender a estrutura do dataset
print("Primeiras linhas do dataset:")
print(df.head())
# Informações gerais ajudam a identificar tipos de dados e valores nulos
print("\nEstrutura do dataset:")
df.info()
# Estatísticas descritivas ajudam a entender distribuição dos dados
print("\nResumo estatístico:")
print(df.describe())
# ==========================================================
# Separação entre variáveis de entrada e saída
# ==========================================================
# X contém as características (features) usadas para prever
# y contém o alvo (espécie da flor)
X = df.iloc[:, :-1]
y = df["target"]
# ==========================================================
# Divisão em treino e teste
# ==========================================================
# O modelo precisa ser testado em dados que ele nunca viu.
# Por isso dividimos:
# - 80% para treino (aprendizado)
# - 20% para teste (avaliação real do desempenho)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
# ==========================================================
# Criação e treinamento do modelo
# ==========================================================
# Utilizamos uma Árvore de Decisão, um modelo que aprende regras
# baseadas em perguntas sobre os dados (ex: "pétala > 2.5?")
model = DecisionTreeClassifier(random_state=42)
# O método fit treina o modelo, ou seja, ele aprende padrões
# que relacionam as características com as espécies
model.fit(X_train, y_train)
# ==========================================================
# Avaliação do modelo
# ==========================================================
# O modelo faz previsões sobre dados que ele não viu
y_pred = model.predict(X_test)
# A acurácia mede a proporção de acertos do modelo
accuracy = accuracy_score(y_test, y_pred)
print(f"\nAcurácia do modelo: {accuracy:.2f}")
# ==========================================================
# Validação cruzada
# ==========================================================
# Aqui o dataset é dividido em 5 partes (folds)
# O modelo é treinado e testado várias vezes
# Isso gera uma avaliação mais confiável do desempenho
scores = cross_val_score(model, X, y, cv=5)
print(f"Acurácia média na validação cruzada: {scores.mean():.2f}")
# ==========================================================
# Teste com nova amostra
# ==========================================================
# Criamos uma nova flor fictícia com medidas desconhecidas
# O modelo tenta prever a qual espécie ela pertence
nova_amostra = np.array([[5.1, 3.5, 1.4, 0.2]])
predicao = model.predict(nova_amostra)
# Convertemos o número da classe para o nome da espécie
print(
f"\nClasse prevista para nova amostra: "
f"{dataset.target_names[predicao[0]]}"
)