Regresión simbólica con GPlearn

La regresión simbólica es un modelo de machine learning que busca en el espacio de posibles expresiones matemáticas la expresión que mejor se ajusta a los datos. Al contrario que otras técnicas de regresión, como la regresión lineal, no se especifica una estructura previa del modelo a optimizar sino que va construyendo expresiones matemáticas aleatoriamente. La regresión simbólica normalmente se realiza usando programación genética, métodos bayesiano o redes neuronales.

La librería GPlearn es una librería en Python para realizar regresión simbólica usando programación genética. Para ello comienza construyendo una población de fórmulas aleatorias para representar una relación entre variables independientes conocidas y sus objetivos de variables dependientes con el fin de predecir los datos. Luego, cada generación sucesiva de programas evoluciona a partir de la anterior seleccionando a los individuos más aptos de la población, los que mejor predicen los datos.

Vamos a ver un ejemplo. Primero definimos una expresión, y = 4X1 + X1X2 + 3X2 + 6X3, donde X1, X2, X3 son las variables de entrada. Esta es la expresión que el algoritmo de regresión simbólica deberá aproximar. Generamos 5000 iteraciones de las variables de entrada y de la variable salida y los almacenamos en tensores.

import random
import numpy as np

# Define the expression y = 4x1 + x1x2 + 3x2 + 6x3
def evaluate_expression(x1, x2, x3):
    y = 4 * x1 + x1*x2 + 3 * x2 + 6 * x3
    return y

# Generate 5000 iterations of input values between 0 and 1 and evaluate the output
inputs = []
outputs = []
for _ in range(5000):
    x1 = random.uniform(0, 1)
    x2 = random.uniform(0, 1)
    x3 = random.uniform(0, 1)
    y = evaluate_expression(x1, x2, x3)
    inputs.append([x1, x2, x3])
    outputs.append(y)

# Convert inputs and outputs to numpy tensors
inputs_tensor = np.array(inputs)
outputs_tensor = np.array(outputs)

# Print the shapes of the tensors to verify
print("Inputs Tensor Shape:", inputs_tensor.shape)
print("Outputs Tensor Shape:", outputs_tensor.shape)

Ahora vamos a usar la clase Symbolic Regressor de GPlearn para realizar la regresión simbólica. Utilizamos 20 generaciones con 5000 programas en cada una. Instanciamos un objeto con estos parámetros y llamamos al método fit pasándoles los tensores con las entradas y salidas almacenadas para que encuentre el programa que más se aproxime a nuestros datos.

from gplearn.genetic import SymbolicRegressor

# Assuming inputs_tensor and outputs_tensor are already defined as in the previous steps

# Use GPlearn to find the symbolic expression
est_gp = SymbolicRegressor(population_size=5000,
                           generations=20, stopping_criteria=0.01,
                           p_crossover=0.7, p_subtree_mutation=0.1,
                           p_hoist_mutation=0.05, p_point_mutation=0.1,
                           max_samples=0.9, verbose=1,
                           parsimony_coefficient=0.01, random_state=0)

est_gp.fit(inputs_tensor, outputs_tensor)

# Print the best found program
print(est_gp._program)

Vemos el mejor programa obtenido:

    |   Population Average    |             Best Individual              |
---- ------------------------- ------------------------------------------ ----------
 Gen   Length          Fitness   Length          Fitness      OOB Fitness  Time Left
   0    33.42      1.11652e+07       19          1.75105          1.76371      2.50m
   1    14.50          7.90331       21         0.848016         0.846612      2.34m
   2    17.98          6.49148       27         0.623554         0.622864      1.75m
   3    17.23          45.5395       23         0.343093         0.347378      1.94m
   4    20.21          4.74417       25         0.257995         0.248204      1.55m
   5    21.13          4.46877       29         0.131815         0.128787      1.77m
   6    21.28          3.39233       23         0.129661         0.135818      1.36m
   7    20.43          4.21088       29      4.12312e-16      3.57492e-16      1.49m
add(add(add(X2, X0), add(X2, X2)), add(mul(X1, X0), add(add(add(add(X0, X1), X2), add(X0, X2)), add(add(X2, X1), add(X0, X1)))))

Si sumamos los términos del programa salida y simplificamos vemos que obtenemos la expresión y = 4X1 + X1X2 + 3X2 + 6X3 que coincide exactamente con la función que ha generado los datos, teniendo en cuenta que el regresor empieza llamando las variables X0 en lugar de X1 como hemos hecho nosotros.

Deja una respuesta

Orgullosamente ofrecido por WordPress | Tema: Baskerville 2 por Anders Noren.

Subir ↑