O método dos “Vizinhos mais Próximos” (k vizinho mais próximo, k-Nearest Neighbors ou kNN) é uma técnica muito legal em aprendizado de máquinas que se baseia na ideia de que coisas parecidas se juntam. Neste tutorial, vamos entender e usar o kNN passo a passo com Python, usando a biblioteca scikit-learn. Também vamos falar sobre jeitos de fazer o modelo funcionar melhor.
Como o kNN Funciona?
Pense que você quer adivinhar a categoria de um novo ponto de dados usando pontos de dados que já temos categorizados. O kNN faz isso assim: quando tem um ponto novo, ele olha para os k pontos mais perto usando uma régua (distância) – geralmente a distância reta. Ele olha quais categorias têm mais entre esses pontos e aí coloca a mesma categoria no ponto novo.
Fazendo o kNN do Zero
Primeiro, vamos fazer o kNN sem usar outras ajudas, só o NumPy. Geramos alguns dados de exemplo e vemos algumas coisas sobre eles.
Depois a gente escolhe como medir a distância. Normalmente é a régua reta, mas tem outras maneiras dependendo do problema. Aí o kNN vê os k vizinhos mais perto do ponto novo e coloca a categoria do ponto novo igual à dos vizinhos.
import numpy as np
from collections import Counter
# Dados de exemplo
dados_categorizados = np.array([[2, 3, 'A'],
[4, 5, 'B'],
[6, 7, 'A'],
[8, 9, 'B']], dtype=object)
# Novo ponto de dado
novo_ponto = np.array([5, 6])
# Valor de k
k = 3
# Função para calcular a distância entre dois pontos
def distancia(p1, p2):
return np.sqrt(np.sum((p1.astype(np.float) - p2.astype(np.float)) ** 2))
# Encontrar os k vizinhos mais próximos
vizinhos = sorted(dados_categorizados, key=lambda x: distancia(x[:-1], novo_ponto))[:k]
# Contar as categorias dos vizinhos
categorias_vizinhos = [vizinho[-1] for vizinho in vizinhos]
categoria_mais_comum = Counter(categorias_vizinhos).most_common(1)[0][0]
print(f"O novo ponto pertence à categoria: {categoria_mais_comum}")
Usando o scikit-learn
Usar só o NumPy é legal, mas a biblioteca scikit-learn ajuda mais. Só umas linhas de código e dá para criar um modelo kNN, treinar com dados e adivinhar coisas.
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
# Carregar o conjunto de dados Iris
dados = load_iris()
X = dados.data
y = dados.target
# Dividir os dados em conjunto de treinamento e teste
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Criar um modelo kNN com o scikit-learn
modelo_knn = KNeighborsClassifier(n_neighbors=3)
# Treinar o modelo kNN com os dados de treinamento
modelo_knn.fit(X_train, y_train)
# Fazer previsões com o modelo treinado
y_pred = modelo_knn.predict(X_test)
# Imprimir as previsões
print("Previsões do modelo:")
for i in range(len(y_pred)):
print(f"Instância {i+1}: Classe prevista {y_pred[i]}")
Ainda dá para melhorar o jeito do modelo com a técnica “bagging”. Isso significa treinar vários modelos kNN com partes diferentes dos dados e juntar as respostas para melhorar tudo.
Melhorando o Desempenho com Bagging
Para melhorar ainda mais o desempenho do kNN, podemos usar a técnica de bagging. O bagging envolve treinar múltiplos modelos kNN em subconjuntos aleatórios dos dados de treinamento e, em seguida, combinar suas previsões para obter um resultado final. Isso pode reduzir a variância e melhorar o desempenho geral do modelo.
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import BaggingClassifier
from sklearn.metrics import accuracy_score
# Carregar o conjunto de dados de exemplo (Íris)
dados = load_iris()
X = dados.data
y = dados.target
# Dividir os dados em conjunto de treinamento e teste
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Criar um modelo kNN com o scikit-learn
modelo_knn = KNeighborsClassifier(n_neighbors=3)
# Treinar o modelo kNN com os dados de treinamento
modelo_knn.fit(X_train, y_train)
# Fazer previsões com o modelo treinado
y_pred = modelo_knn.predict(X_test)
# Calcular a precisão do modelo
precisao = accuracy_score(y_test, y_pred)
print(f"Precisão do modelo kNN: {precisao}")
# Usar a técnica de Bagging para melhorar o modelo kNN
modelo_bagging = BaggingClassifier(base_estimator=modelo_knn, n_estimators=10)
# Treinar o modelo Bagging com os dados de treinamento
modelo_bagging.fit(X_train, y_train)
# Fazer previsões com o modelo Bagging
y_pred_bagging = modelo_bagging.predict(X_test)
# Calcular a precisão do modelo Bagging
precisao_bagging = accuracy_score(y_test, y_pred_bagging)
print(f"Precisão do modelo Bagging: {precisao_bagging}")
Conclusão
O algoritmo k-Nearest Neighbors é uma ferramenta poderosa para classificação e regressão em aprendizado de máquina. Neste tutorial, você aprendeu como o kNN funciona, desde sua compreensão intuitiva até a implementação prática em Python, usando tanto a implementação do zero quanto a biblioteca scikit-learn. Além disso, exploramos maneiras de melhorar o desempenho do modelo, como ajustar hiperparâmetros e utilizar a técnica de bagging. Com esses conhecimentos, você está pronto para aplicar o kNN em problemas do mundo real e continuar explorando o vasto campo do aprendizado de máquina.
Espero que este tutorial tenha sido útil e inspirador para você. Se tiver alguma dúvida ou comentário, sinta-se à vontade para compartilhar!
Outras Referências
Link para o KNN do SkLearn: https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html