Implementación de Lasso Regression From Scratch usando Python

requisitos previos: 

  1. Regresión lineal
  2. Descenso de gradiente

Introducción: 

Lasso Regression también es otro modelo lineal derivado de Linear Regression que comparte la misma función hipotética para la predicción. La función de costo de la regresión lineal está representada por J.

\frac{1}{m} \sum_{i=1}^{m}\left(y^{(i)}-h\left(x^{(i)}\right)\right)^{2}

Here, m is the total number of training examples in the dataset.
h(x(i)) represents the hypothetical function for prediction.
y(i)represents the value of target variable for ith training example.

El modelo de regresión lineal considera todas las características igualmente relevantes para la predicción. Cuando hay muchas características en el conjunto de datos e incluso algunas de ellas no son relevantes para el modelo predictivo. Esto hace que el modelo sea más complejo con una predicción demasiado inexacta en el conjunto de prueba (o sobreajuste). Tal modelo con alta varianza no generaliza sobre los nuevos datos. Entonces, Lasso Regression viene al rescate. Introdujo una penalización L1 (o igual al valor absoluto de la magnitud de los pesos) en la función de costo de Regresión Lineal. La función de costo modificada para la regresión de Lasso se muestra a continuación.

\frac{1}{m}\left[\sum_{i=1}^{m}\left(y^{(i)}-h\left(x^{(i)}\right)\right)^{2}+\lambda \sum_{j=1}^{n} w_{j}\right]

Here, w(j) represents the weight for jth feature.  
n is the number of features in the dataset.
lambda is the regularization strength.
 

Lasso Regression realiza tanto la selección de variables como la regularización.

Intuición matemática: 

Durante la optimización del descenso de gradiente, se agregaron pesos reducidos de penalización l1 cercanos a cero o cero. Esos pesos que se reducen a cero eliminan las características presentes en la función hipotética. Debido a esto, las características irrelevantes no participan en el modelo predictivo. Esta penalización de los pesos simplifica la hipótesis lo que favorece la escasez (modelo con pocos parámetros).

Si se agrega la intersección, permanece sin cambios.

Podemos controlar la fuerza de la regularización mediante el hiperparámetro lambda. Todos los pesos se reducen por el mismo factor lambda. 

Diferentes casos para ajustar valores de lambda.

  1. Si lambda se establece en 0, la regresión de lazo es igual a la regresión lineal.
  2. Si lambda se establece en infinito, todos los pesos se reducen a cero.

Si aumentamos lambda, el sesgo aumenta si disminuimos el aumento de la varianza de lambda. A medida que aumenta la lambda, más y más pesos se reducen a cero y elimina características del modelo.

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, entrenaremos un modelo de regresión de Lasso para conocer la correlación entre la cantidad de años de experiencia de cada empleado y su salario respectivo. Una vez entrenado el modelo, podremos predecir el salario de un empleado en base a sus años de experiencia.

 

Código:

# Importing libraries
  
import numpy as np
  
import pandas as pd
  
from sklearn.model_selection import train_test_split
  
import matplotlib.pyplot as plt
  
# Lasso Regression
  
class LassoRegression() :
      
    def __init__( self, learning_rate, iterations, l1_penality ) :
          
        self.learning_rate = learning_rate
          
        self.iterations = iterations
          
        self.l1_penality = l1_penality
          
    # Function for model training
              
    def fit( self, X, Y ) :
          
        # no_of_training_examples, no_of_features
          
        self.m, self.n = X.shape
          
        # weight initialization
          
        self.W = np.zeros( self.n )
          
        self.b = 0
          
        self.X = X
          
        self.Y = Y
          
        # gradient descent learning
                  
        for i in range( self.iterations ) :
              
            self.update_weights()
              
        return self
      
    # Helper function to update weights in gradient descent
      
    def update_weights( self ) :
             
        Y_pred = self.predict( self.X )
          
        # calculate gradients  
          
        dW = np.zeros( self.n )
          
        for j in range( self.n ) :
              
            if self.W[j] > 0 :
                  
                dW[j] = ( - ( 2 * ( self.X[:, j] ).dot( self.Y - Y_pred ) ) 
                           
                         + self.l1_penality ) / self.m
          
            else :
                  
                dW[j] = ( - ( 2 * ( self.X[:, j] ).dot( self.Y - Y_pred ) ) 
                           
                         - self.l1_penality ) / self.m
  
       
        db = - 2 * np.sum( self.Y - Y_pred ) / self.m 
          
        # update weights
      
        self.W = self.W - self.learning_rate * dW
      
        self.b = self.b - self.learning_rate * db
          
        return self
      
    # Hypothetical function  h( x ) 
      
    def predict( self, X ) :
      
        return X.dot( self.W ) + self.b
      
  
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 = LassoRegression( iterations = 1000, learning_rate = 0.01, l1_penality = 500 )
  
    model.fit( X_train, Y_train )
      
    # Prediction on test set
  
    Y_pred = model.predict( X_test )
      
    print( "Predicted values ", np.round( Y_pred[:3], 2 ) ) 
      
    print( "Real values      ", Y_test[:3] )
      
    print( "Trained W        ", round( model.W[0], 2 ) )
      
    print( "Trained b        ", round( model.b, 2 ) )
      
    # Visualization on test set 
      
    plt.scatter( X_test, Y_test, color = 'blue' )
      
    plt.plot( X_test, Y_pred, color = 'orange' )
      
    plt.title( 'Salary vs Experience' )
      
    plt.xlabel( 'Years of Experience' )
      
    plt.ylabel( 'Salary' )
      
    plt.show()
      
  
if __name__ == "__main__" : 
      
    main()

Producción:

Predicted values  [ 40600.91 123294.39  65033.07]
Real values       [ 37731 122391  57081]
Trained W         9396.99
Trained b         26505.43

Visualización

Nota: Automatiza ciertas partes de la selección del modelo y, a veces, se denomina eliminador de variables.

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 *