Regresión polinomial (Desde cero usando Python)

requisitos previos 

  1. Regresión lineal
  2. Descenso de gradiente

Introducción

La regresión lineal encuentra la correlación entre la variable dependiente (o variable objetivo) y las variables independientes (o características). En resumen, es un modelo lineal para ajustar los datos linealmente. Pero no logra ajustarse y captar el patrón en datos no lineales. 

Primero apliquemos la regresión lineal en datos no lineales para comprender la necesidad de la regresión polinomial. El modelo de regresión lineal utilizado en este artículo se importa de sklearn. Puede consultar el artículo separado para la implementación del modelo de regresión lineal desde cero.

Python3

# Importing libraries
 
import numpy as np
 
import pandas as pd
 
from sklearn.model_selection import train_test_split
 
import matplotlib.pyplot as plt
 
from sklearn.linear_model import LinearRegression
 
# driver code
 
def main() :
     
    # Create dataset
     
    X = np.array( [ [1], [2], [3], [4], [5], [6], [7] ] )
     
    Y = np.array( [ 45000, 50000, 60000, 80000, 110000, 150000, 200000 ] )
     
    # Model training
     
    model = LinearRegression()
 
    model.fit( X, Y )
     
    # Prediction
 
    Y_pred = model.predict( X )
     
    # Visualization
     
    plt.scatter( X, Y, color = 'blue' )
     
    plt.plot( X, Y_pred, color = 'orange' )
     
    plt.title( 'X vs Y' )
     
    plt.xlabel( 'X' )
     
    plt.ylabel( 'Y' )
     
    plt.show()
     
     
if __name__ == "__main__" :
     
    main()

 

Producción : 

Visualización

Como se muestra en la visualización de salida, la regresión lineal incluso no pudo ajustar bien los datos de entrenamiento (o no pudo decodificar el patrón en Y con respecto a X). Porque su función hipotética es de naturaleza lineal e Y es una función no lineal de X en los datos. 

For univariate linear regression : 

h( x ) = w * x

here,  x is the feature vector.
and w is the weight vector.

 Este problema también se denomina desajuste . Para superar el desajuste, introducimos nuevos vectores de características simplemente agregando potencia al vector de características original.

For univariate polynomial regression : 
 
h( x ) = w1x + w2x2  + .... + wnxn 
 
here, w is the weight vector. 
where x2  is the derived feature from x. 

Después de transformar la X original en sus términos de mayor grado, hará que nuestra función hipotética pueda ajustarse a los datos no lineales. Aquí está la implementación del modelo de regresión polinomial desde cero y la validación del modelo en un conjunto de datos ficticio.

Python

# Importing libraries
 
import numpy as np
 
import math
 
import matplotlib.pyplot as plt
 
# Univariate Polynomial Regression
 
class PolynomailRegression() :
     
    def __init__( self, degree, learning_rate, iterations ) :
         
        self.degree = degree
         
        self.learning_rate = learning_rate
         
        self.iterations = iterations
         
    # function to transform X
     
    def transform( self, X ) :
         
        # initialize X_transform
         
        X_transform = np.ones( ( self.m, 1 ) )
         
        j = 0
     
        for j in range( self.degree + 1 ) :
             
            if j != 0 :
                 
                x_pow = np.power( X, j )
                 
                # append x_pow to X_transform
                 
                X_transform = np.append( X_transform, x_pow.reshape( -1, 1 ), axis = 1 )
 
        return X_transform  
     
    # function to normalize X_transform
     
    def normalize( self, X ) :
         
        X[:, 1:] = ( X[:, 1:] - np.mean( X[:, 1:], axis = 0 ) ) / np.std( X[:, 1:], axis = 0 )
         
        return X
         
    # model training
     
    def fit( self, X, Y ) :
         
        self.X = X
     
        self.Y = Y
     
        self.m, self.n = self.X.shape
     
        # weight initialization
     
        self.W = np.zeros( self.degree + 1 )
         
        # transform X for polynomial  h( x ) = w0 * x^0 + w1 * x^1 + w2 * x^2 + ........+ wn * x^n
         
        X_transform = self.transform( self.X )
         
        # normalize X_transform
         
        X_normalize = self.normalize( X_transform )
                 
        # gradient descent learning
     
        for i in range( self.iterations ) :
             
            h = self.predict( self.X )
         
            error = h - self.Y
             
            # update weights
         
            self.W = self.W - self.learning_rate * ( 1 / self.m ) * np.dot( X_normalize.T, error )
         
        return self
     
    # predict
     
    def predict( self, X ) :
      
        # transform X for polynomial  h( x ) = w0 * x^0 + w1 * x^1 + w2 * x^2 + ........+ wn * x^n
         
        X_transform = self.transform( X )
         
        X_normalize = self.normalize( X_transform )
         
        return np.dot( X_transform, self.W )
       
       
# Driver code    
 
def main() :   
     
    # Create dataset
     
    X = np.array( [ [1], [2], [3], [4], [5], [6], [7] ] )
     
    Y = np.array( [ 45000, 50000, 60000, 80000, 110000, 150000, 200000 ] )
  
    # model training
     
    model = PolynomailRegression( degree = 2, learning_rate = 0.01, iterations = 500 )
 
    model.fit( X, Y )
     
    # Prediction on training set
 
    Y_pred = model.predict( X )
     
    # Visualization
     
    plt.scatter( X, Y, color = 'blue' )
     
    plt.plot( X, Y_pred, color = 'orange' )
     
    plt.title( 'X vs Y' )
     
    plt.xlabel( 'X' )
     
    plt.ylabel( 'Y' )
     
    plt.show()
 
 
if __name__ == "__main__" :
     
    main()

Producción : 

Visualización

También normalizamos la X antes de alimentar el modelo solo para evitar problemas de explosión y desaparición de gradiente.

La visualización de salida mostró que la regresión polinomial se ajustaba a los datos no lineales generando una curva.

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 *