À la suite du Chapitre 4, exemple d'exécution de Première reconnaissance de formes Sera reproduit en Python. Cette fois, il s'agit du chapitre 5 «Méthode k plus proche voisin (méthode kNN)».
Cependant, nous avons abandonné la reproduction de l'exemple d'exécution en utilisant la base de données de nombres manuscrits ETL1 (exemple d'exécution 5.1, exemple d'exécution 5.2 Figure 5.9 (a)) car il y a une partie où les données sont échantillonnées aléatoirement. .. .. L'environnement d'exploitation du code décrit est numpy 1.16.2, pandas 0.24.2, scikit-learn 0.20.3.
La méthode k plus proche voisin (méthode kNN) est une méthode d'identification dans laquelle k modèles sont prélevés au voisinage le plus proche d'un échantillon et l'échantillon appartient à la classe à laquelle ils appartiennent le plus. Ci-dessous le code.
--Chargement des bibliothèques requises
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style('whitegrid')
from sklearn.preprocessing import StandardScaler
--k Implémentation de la méthode du plus proche voisin
class kNearestNeiborsClassifier:
def __init__(self, k=5):
self._k = k
self._templates = None
self._classes = None
def fit(self, templates, classes):
self._templates = templates
self._classes = classes
def predict(self, X):
pred = np.zeros(len(X))
for i in range(len(X)): #Traitez chaque échantillon avec une instruction for pour assurer la lisibilité
distance = np.sum((X[i, :] - self._templates)**2, axis=1) #Calculer la distance euclidienne entre X et le modèle
idx = np.argsort(distance)[:self._k] #Obtenez l'indice de k moules avec la distance la plus courte à X
_, count = np.unique(self._classes[idx], return_counts=True) #Calculer le nombre de modèles appartenant à chaque classe sur k modèles
cls = np.where(count == np.max(count))[0] #Identifiez la classe qui maximise le nombre de modèles auxquels elle appartient
if len(cls) == 1:
pred[i] = cls[0] #Si une classe a le plus grand nombre de modèles auxquels elle appartient, retournez cette classe
else:
pred[i] = np.nan #S'il y a plusieurs classes qui maximisent le nombre de modèles auxquels elles appartiennent, np sera rejeté..Renvoie nan
return pred
def error_rate(self, y_true, y_pred):
return np.sum(((y_true==1)&(y_pred==0))|((y_true==0)&(y_pred==1)))/len(y_pred) #Calculer le taux d'erreur en excluant les rejets
def reject_rate(self, y_pred):
return np.sum(np.isnan(y_pred))/len(y_pred) #Taux de rejet
--Lecture des données indiennes Pima
Les données sont empruntées à R datasets.
pima_train = pd.read_csv('https://raw.githubusercontent.com/vincentarelbundock/Rdatasets/master/csv/MASS/Pima.tr.csv')
pima_test = pd.read_csv('https://raw.githubusercontent.com/vincentarelbundock/Rdatasets/master/csv/MASS/Pima.te.csv')
--Calculer le taux d'erreur par la méthode holdout
#Données d'entraînement (X_train, Y_train) et données de vérification (X)_test, Y_la préparation du test
sc = StandardScaler()
X_train = sc.fit_transform(pima_train.drop(['Unnamed: 0', 'type'], axis=1))
Y_train = pima_train['type'].map({'Yes':1, 'No':0}).values
X_test = sc.transform(pima_test.drop(['Unnamed: 0', 'type'], axis=1))
Y_test = pima_test['type'].map({'Yes':1, 'No':0}).values
#Calculer le taux d'erreur lorsque k (nombre impair uniquement) est modifié
hold_out_error_rate_list = np.empty((0,2), int)
for k in range(1, 120, 2):
knn = kNearestNeiborsClassifier(k=k)
knn.fit(X_train, Y_train)
Y_pred = knn.predict(X_test)
error_rate = knn.error_rate(y_true=Y_test, y_pred=Y_pred)
hold_out_error_rate_list = np.append(hold_out_error_rate_list, np.array([[k, error_rate]]), axis=0)
--Calculer le taux d'erreur par la méthode d'exclusion unique
#Préparation des données
pima = pd.concat([pima_train, pima_test])
sc = StandardScaler()
X = sc.fit_transform(pima.drop(['Unnamed: 0', 'type'], axis=1))
Y = pima['type'].map({'Yes':1, 'No':0}).values
#Calculer le taux d'erreur lorsque k (nombre impair uniquement) est modifié
leave_one_out_error_rate_list = np.empty((0,2), int)
for k in range(1, 120, 2):
error_list = []
for i in range(len(X)):
idx = np.ones(len(X), dtype=bool)
idx[i] = False #L'échantillon d'index i n'est pas utilisé pour la formation
knn = kNearestNeiborsClassifier(k=k)
knn.fit(X[idx], Y[idx]) #Apprenez avec des échantillons autres que l'index i
Y_pred = knn.predict(X[i].reshape([1, -1]))
error = knn.error_rate(y_true=Y[i], y_pred=Y_pred) #Validé avec un exemple d'index i
error_list.append(error)
error_rate = np.mean(error_list)
leave_one_out_error_rate_list = np.append(leave_one_out_error_rate_list, np.array([[k, error_rate]]), axis=0)
plt.scatter(hold_out_error_rate_list[:, 0], hold_out_error_rate_list[:, 1], label='hold out')
plt.scatter(leave_one_out_error_rate_list[:, 0], leave_one_out_error_rate_list[:, 1], label='leave one out')
plt.legend()
plt.xlabel('k')
plt.ylabel('error rate')
plt.show()
--Calcul du taux d'erreur
#Calculer le taux d'erreur de maintien lorsque k (impair) est modifié
odd_error_rate_list = np.empty((0,2), int)
for k in range(1, 62, 2):
knn = kNearestNeiborsClassifier(k=k)
knn.fit(X_train, Y_train)
Y_pred = knn.predict(X_test)
error_rate = knn.error_rate(y_true=Y_test, y_pred=Y_pred)
odd_error_rate_list = np.append(odd_error_rate_list, np.array([[k, error_rate]]), axis=0)
#Calculer le taux d'erreur de maintien lorsque k (pair) est modifié
even_error_rate_list = np.empty((0,2), int)
for k in range(2, 62, 2):
knn = kNearestNeiborsClassifier(k=k)
knn.fit(X_train, Y_train)
Y_pred = knn.predict(X_test)
error_rate = knn.error_rate(y_true=Y_test, y_pred=Y_pred)
even_error_rate_list = np.append(even_error_rate_list, np.array([[k, error_rate]]), axis=0)
--Taux d'erreurs --Fig.5.12 (a)
plt.scatter(odd_error_rate_list[:, 0], odd_error_rate_list[:, 1], label='odd')
plt.scatter(even_error_rate_list[:, 0], even_error_rate_list[:, 1], label='even')
plt.legend()
plt.xlabel('k')
plt.ylabel('error rate')
plt.show()
--Calcul du taux de rejet
reject_rate_list = np.empty((0,2), int)
for k in range(2, 62, 2):
knn = kNearestNeiborsClassifier(k=k)
knn.fit(X_train, Y_train)
Y_pred = knn.predict(X_test)
reject_rate = knn.reject_rate(y_pred=Y_pred)
reject_rate_list = np.append(reject_rate_list, np.array([[k, reject_rate]]), axis=0)
--Taux de rejet --Fig.5.12 (b)
plt.scatter(reject_rate_list[:, 0], reject_rate_list[:, 1])
plt.xlabel('k')
plt.ylabel('reject rate')
plt.show()
J'ai essayé d'exécuter l'exemple d'exécution du chapitre 5 de Hajipata en Python. Si vous avez des erreurs de code ou des méthodes d'implémentation plus efficaces, nous vous serions reconnaissants de bien vouloir faire une demande de modification.
Recommended Posts