Implementación de K-vecinos más cercanos desde cero usando Python

Aprendizaje basado en instancias

K Clasificación de vecinos más cercanos es una de las técnicas de clasificación basadas en el aprendizaje basado en instancias. Modelos basados ​​en aprendizaje basado en instancias para generalizar más allá de los ejemplos de entrenamiento. Para ello, primero almacenan los ejemplos de entrenamiento. Cuando encuentra una nueva instancia (o ejemplo de prueba), instantáneamente construyen una relación entre los ejemplos de entrenamiento almacenados y este nuevo instante para asignar un valor de función de destino para esta nueva instancia. Los métodos basados ​​en instancias a veces se denominan métodos de aprendizaje diferidos porque posponen el aprendizaje hasta que se encuentra la nueva instancia para la predicción.

En lugar de estimar la función hipotética (o función objetivo) una vez para todo el espacio, estos métodos la estimarán localmente y de manera diferente para cada nueva instancia que se va a predecir.

Aprendizaje del clasificador de vecinos más cercanos K

Suposición básica:

  1. Todas las instancias corresponden a puntos en el espacio n-dimensional donde n representa el número de características en cualquier instancia.
  2. Los vecinos más cercanos de una instancia se definen en términos de la distancia euclidiana.
An instance can be represented by < x1, x2, .............., xn >.
Euclidean distance between two instances xa and xb is given by d( xa, xb ) :

\sqrt{\sum_{j=1}^{n}\left(x_{j}^{a}-x_{j}^{b}\right)^{2}}

¿Como funciona?

K-Nearest Neighbors Classifier primero almacena los ejemplos de entrenamiento. Durante la predicción, cuando encuentra una nueva instancia (o ejemplo de prueba) para predecir, encuentra el número K de instancias de entrenamiento más cercanas a esta nueva instancia. Luego asigna la clase más común entre las instancias de capacitación K-Nearest a esta instancia de prueba.

La opción óptima para K es mediante la validación de errores en los datos de prueba. K también se puede elegir por la raíz cuadrada de m, donde m es el número de ejemplos en el conjunto de datos.

Representación gráfica de trabajo de KNN

En la figura anterior, «+» denota instancias de entrenamiento etiquetadas con 1. «-» denota instancias de entrenamiento con 0. Aquí clasificamos la instancia de prueba x t como la clase más común entre las K-instancias de entrenamiento más cercanas. Aquí elegimos K = 3, por lo que x t se clasifica como “-” o 0.

Pseudocódigo:

  1. Almacene todos los ejemplos de entrenamiento.
  2. Repita los pasos 3, 4 y 5 para cada ejemplo de prueba.
  3. Encuentre el número K de ejemplos de entrenamiento más cercano al ejemplo de prueba actual.
  4. y_pred para el ejemplo de prueba actual = clase más común entre las K-instancias de entrenamiento más cercanas.
  5. Vaya al paso 2.

Implementación:

El conjunto de datos de diabetes utilizado en esta implementación se puede descargar desde el enlace .

Tiene 8 columnas de características como, por ejemplo, «Edad», «Glucosa», etc., y la variable objetivo «Resultado» para 108 pacientes. Entonces, en esto, crearemos un modelo de clasificador de vecinos de enlace para predecir la presencia de diabetes o no para los pacientes con dicha información.

# Importing libraries
  
import pandas as pd
  
import numpy as np
  
from sklearn.model_selection import train_test_split
  
from scipy.stats import mode
  
from sklearn.neighbors import KNeighborsClassifier
  
# K Nearest Neighbors Classification
  
class K_Nearest_Neighbors_Classifier() : 
      
    def __init__( self, K ) :
          
        self.K = K
          
    # Function to store training set
          
    def fit( self, X_train, Y_train ) :
          
        self.X_train = X_train
          
        self.Y_train = Y_train
          
        # no_of_training_examples, no_of_features
          
        self.m, self.n = X_train.shape
      
    # Function for prediction
          
    def predict( self, X_test ) :
          
        self.X_test = X_test
          
        # no_of_test_examples, no_of_features
          
        self.m_test, self.n = X_test.shape
          
        # initialize Y_predict
          
        Y_predict = np.zeros( self.m_test )
          
        for i in range( self.m_test ) :
              
            x = self.X_test[i]
              
            # find the K nearest neighbors from current test example
              
            neighbors = np.zeros( self.K )
              
            neighbors = self.find_neighbors( x )
              
            # most frequent class in K neighbors
              
            Y_predict[i] = mode( neighbors )[0][0]    
              
        return Y_predict
      
    # Function to find the K nearest neighbors to current test example
            
    def find_neighbors( self, x ) :
          
        # calculate all the euclidean distances between current 
        # test example x and training set X_train
          
        euclidean_distances = np.zeros( self.m )
          
        for i in range( self.m ) :
              
            d = self.euclidean( x, self.X_train[i] )
              
            euclidean_distances[i] = d
          
        # sort Y_train according to euclidean_distance_array and 
        # store into Y_train_sorted
          
        inds = euclidean_distances.argsort()
          
        Y_train_sorted = self.Y_train[inds]
          
        return Y_train_sorted[:self.K]
      
    # Function to calculate euclidean distance
              
    def euclidean( self, x, x_train ) :
          
        return np.sqrt( np.sum( np.square( x - x_train ) ) )
  
# Driver code
  
def main() :
      
    # Importing dataset
      
    df = pd.read_csv( "diabetes.csv" )
  
    X = df.iloc[:,:-1].values
  
    Y = df.iloc[:,-1:].values
      
    # Splitting dataset into train and test set
  
    X_train, X_test, Y_train, Y_test = train_test_split( 
      X, Y, test_size = 1/3, random_state = 0 )
      
    # Model training
      
    model = K_Nearest_Neighbors_Classifier( K = 3 )
      
    model.fit( X_train, Y_train )
      
    model1 = KNeighborsClassifier( n_neighbors = 3 )
      
    model1.fit( X_train, Y_train )
      
    # Prediction on test set
  
    Y_pred = model.predict( X_test )
      
    Y_pred1 = model1.predict( X_test )
      
    # measure performance
      
    correctly_classified = 0
      
    correctly_classified1 = 0
      
    # counter
      
    count = 0
      
    for count in range( np.size( Y_pred ) ) :
          
        if Y_test[count] == Y_pred[count] :
              
            correctly_classified = correctly_classified + 1
          
        if Y_test[count] == Y_pred1[count] :
              
            correctly_classified1 = correctly_classified1 + 1
              
        count = count + 1
          
    print( "Accuracy on test set by our model       :  ", ( 
      correctly_classified / count ) * 100 )
    print( "Accuracy on test set by sklearn model   :  ", ( 
      correctly_classified1 / count ) * 100 )
      
      
if __name__ == "__main__" : 
      
    main()

Producción :

Accuracy on test set by our model       :   63.888888888888886
Accuracy on test set by sklearn model   :   63.888888888888886

La precisión alcanzada por nuestro modelo y sklearn es igual, lo que indica la correcta implementación de nuestro modelo.

Nota: La implementación anterior es para la creación de modelos desde cero, no para mejorar la precisión del conjunto de datos de diabetes.

K Regresión de vecinos más cercanos:

K Nearest Neighbors Regression primero almacena los ejemplos de entrenamiento. Durante la predicción, cuando encuentra una nueva instancia (o ejemplo de prueba) para predecir, encuentra el número K de instancias de entrenamiento más cercanas a esta nueva instancia. Luego predice el valor objetivo para esta instancia calculando la media de los valores objetivo de estos vecinos más cercanos.

La opción óptima para K es mediante la validación de errores en los datos de prueba. K también se puede elegir por la raíz cuadrada de m, donde m es el número de ejemplos en el conjunto de datos.

Pseudocódigo:

  1. Almacene todos los ejemplos de entrenamiento.
  2. Repita los pasos 3, 4 y 5 para cada ejemplo de prueba.
  3. Encuentre el número K de ejemplos de entrenamiento más cercano al ejemplo de prueba actual.
  4. y_pred para el ejemplo de prueba actual = media de los verdaderos valores objetivo de estos K vecinos.
  5. Vaya al paso 2.

Implementación:

El conjunto de datos utilizado en esta implementación se puede descargar desde el enlace

Tiene 2 columnas: » Años de experiencia » y » Salario » para 30 empleados en una empresa. Entonces, en esto, crearemos un modelo de regresión de K vecinos más cercanos para conocer la correlación entre la cantidad de años de experiencia de cada empleado y su salario respectivo.

El modelo que creamos predice el mismo valor que el modelo sklearn predice para el conjunto de prueba.

Python3

# Importing libraries
  
import pandas as pd
  
import numpy as np
  
from sklearn.model_selection import train_test_split
  
from sklearn.neighbors import KNeighborsRegressor
  
# K Nearest Neighbors Regression
  
class K_Nearest_Neighbors_Regressor() : 
      
    def __init__( self, K ) :
          
        self.K = K
          
    # Function to store training set
          
    def fit( self, X_train, Y_train ) :
          
        self.X_train = X_train
          
        self.Y_train = Y_train
          
        # no_of_training_examples, no_of_features
          
        self.m, self.n = X_train.shape
      
    # Function for prediction
          
    def predict( self, X_test ) :
          
        self.X_test = X_test
          
        # no_of_test_examples, no_of_features
          
        self.m_test, self.n = X_test.shape
          
        # initialize Y_predict
          
        Y_predict = np.zeros( self.m_test )
          
        for i in range( self.m_test ) :
              
            x = self.X_test[i]
              
            # find the K nearest neighbors from current test example
              
            neighbors = np.zeros( self.K )
              
            neighbors = self.find_neighbors( x )
              
            # calculate the mean of K nearest neighbors
              
            Y_predict[i] = np.mean( neighbors )
              
        return Y_predict
      
    # Function to find the K nearest neighbors to current test example
            
    def find_neighbors( self, x ) :
          
        # calculate all the euclidean distances between current test
        # example x and training set X_train
          
        euclidean_distances = np.zeros( self.m )
          
        for i in range( self.m ) :
              
            d = self.euclidean( x, self.X_train[i] )
              
            euclidean_distances[i] = d
          
        # sort Y_train according to euclidean_distance_array and 
        # store into Y_train_sorted
          
        inds = euclidean_distances.argsort()
          
        Y_train_sorted = self.Y_train[inds]
          
        return Y_train_sorted[:self.K]
      
    # Function to calculate euclidean distance
              
    def euclidean( self, x, x_train ) :
          
        return np.sqrt( np.sum( np.square( x - x_train ) ) )
   
# Driver code
  
def main() :
      
    # Importing dataset
      
    df = pd.read_csv( "salary_data.csv" )
  
    X = df.iloc[:,:-1].values
  
    Y = df.iloc[:,1].values
      
    # Splitting dataset into train and test set
  
    X_train, X_test, Y_train, Y_test = train_test_split( 
      X, Y, test_size = 1/3, random_state = 0 )
      
    # Model training
      
    model = K_Nearest_Neighbors_Regressor( K = 3 )
  
    model.fit( X_train, Y_train )
      
    model1 = KNeighborsRegressor( n_neighbors = 3 )
      
    model1.fit( X_train, Y_train )
      
    # Prediction on test set
  
    Y_pred = model.predict( X_test )
      
    Y_pred1 =  model1.predict( X_test )
      
    print( "Predicted values by our model     :  ", np.round( Y_pred[:3], 2 ) ) 
      
    print( "Predicted values by sklearn model :  ", np.round( Y_pred1[:3], 2 ) )
      
    print( "Real values                       :  ", Y_test[:3] )
  
  
if __name__ == "__main__" : 
      
    main()

Producción :

Predicted values by our model     :   [ 43024.33 113755.33  58419.  ]
Predicted values by sklearn model :   [ 43024.33 113755.33  58419.  ]
Real values                       :   [ 37731 122391  57081]

Desventaja: los modelos de aprendizaje de instancias son computacionalmente muy costosos porque todos los cálculos se realizan durante la predicción. También considera todos los ejemplos de entrenamiento para la predicción de cada ejemplo de prueba.

Publicación traducida automáticamente

Artículo escrito por mohit baliyan y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *