Resultado de 100% é bem suspeito sempre, neste caso não significa necessariamente overfitting nem erro no código.
O Iris é um dataset muito pequeno 150 amostras, 50 de cada classe.
A classe Setosa é linearmente separável.
As classes Versicolor e Virginica possuem alguma mistura, mas pouca.
Algumas divisões treino/teste produzem 100%. usei seed 42 pode ter pegados amostras bem separadas
Talvez pegar amostra estratificada no treino e teste fosse mais generalista.
Na validação cruzada tivemos:
Média: 95%
Desvio padrão: 0.0521
# Passo 0: Importar as bibliotecas necessárias
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_iris
import pandas as pd
# Passo 1: Carregar e explorar dados
iris_dataset = load_iris()
#converter o iris_dataset para dataframe do pandas
#nota: data é o campo iris_dataset.data e as colunas do campo iris_dataset.feature_names
df_iris = pd.DataFrame(data=iris_dataset.data, columns=iris_dataset.feature_names)
df_iris['target'] = iris_dataset.target # target é o alvo ou classe 0,1,2 são 3 temos 150 amostras 50 de cada classe
df_iris['target_name'] = df_iris.target.apply(lambda x: iris_dataset.target_names[x]) #convertendo para nomes de classes para visualização
display(df_iris)
df_iris.shape
#estatisticas descritivas
df_iris.describe()
#descobrindo os tipos de dados
df_iris.info()
#Descobrindo quantas amostras de cada classe temos
df_iris.groupby('target_name').size()
df_iris.head()
# Passo 2: Pré-processar os dados e normalizar
#separando os astributos e os rótulos
X = df_iris.drop(columns=['target','target_name']) # Características (comprimento e largura das pétalas e sépalas)
y = df_iris['target'] # Rótulos (espécies das flores) lembrando que knn trabalho melhor com rótulos numéricos
#normalizando os dados
scaler = StandardScaler() #Ao normalizar, retiramos um pouco da variação para melhorar o desempenho do algorítmo e acurácia no processo de treinamento.
X_scaled = scaler.fit_transform(X)
# Passo 3: Dividir os dados em treino e teste 80/20
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)
# Treinar
knn_model = KNeighborsClassifier()
knn_model.fit(X_train, y_train)
# Passo 4: Avaliar o modelo
knn_accuracy = accuracy_score(y_test, knn_model.predict(X_test))
print(f"Acurácia do KNN: {knn_accuracy * 100:.2f}%")
#predizer uma amostra nova
nova_amostra = [[5.1, 3.5, 1.4, 0.2]] # Exemplo de uma nova amostra
nova_amostra_scaled = scaler.transform(nova_amostra) # como escalei no treino na predição também precisa fazer
predicao = knn_model.predict(nova_amostra_scaled) # predizer com dados escalados
print("-" * 50)
print(f'Predição para a nova amostra: {df_iris.target_name[predicao[0]]}')
from sklearn.metrics import confusion_matrix
y_pred = knn_model.predict(X_test)
cm = confusion_matrix(y_test, y_pred)
print(cm)
from sklearn.metrics import classification_report
print(
classification_report(
y_test,
y_pred,
target_names=iris_dataset.target_names
)
)
from sklearn.model_selection import cross_val_score
knn_model = KNeighborsClassifier()
scores = cross_val_score(
knn_model,
X_scaled,
y,
cv=10
)
print("Scores:")
print(scores)
print()
print(f"Média: {scores.mean():.4f}")
print(f"Desvio padrão: {scores.std():.4f}")