es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Optimización con restricciones en Python utilizando Scipy

Tengo una función f : (a.y1 + b.y2 + c.y3 + d.y4 + e.y5 + f.y6) y necesito minimizar el error cuadrático medio de la raíz de f. La restricción lineal es: a+b+c+d+e+f = 1. Y los límites son que cada uno de a, b, c… debe estar entre [0,1]. Estoy intentando encontrar los valores optimizados de a, b, c, d, e y f. Estoy usando Scipy, pero siento que no he podido colocar correctamente los límites y las restricciones en el código ‘minimize’ de la siguiente manera: (y0 es el valor de prueba original dado, por ejemplo).

Importo numpy como np
Importo minimize de scipy.optimize
Importo LinearConstraint de scipy.optimize

Defino la función root_mean_squared_error(y1, y2):
La diferencia al cuadrado = (y1 – y2)**2
El cuadrado medio = np.mean(diferencia al cuadrado)
Retorna la raíz cuadrada del cuadrado medio

Defino la función rms(params):
a, b, c, d, e, f = params
yF = sum(ay1 + by2 + cy3 + dy_4 + ey5 + fy6)
Retorna root_mean_squared_error(y0, yF)

Establezco el valor inicial como [0.2, 0.1, 0.2, 0.05, 0.3, 0.15]
Establezco la restricción como LinearConstraint([1,1,1,1,1,1],1,1)
Establezco los límites como ([0, 1],[0, 1],[0, 1],[0, 1],[0, 1],[0, 1])

res = minimize(rms, initial_guess, method=’nelder-mead’, bounds = bound, constraints = constraint)
print(res.x)

Estoy obteniendo valores muy pequeños que no suman uno, como los siguientes:

[1.28941447e-04 1.90583408e-04 8.50096927e-05 2.08311702e-04 1.17829816e-04 0.00000000e+00]

¿Es esta la forma correcta de usar la restricción lineal y el límite de scipy?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece que has utilizado correctamente los argumentos LinearConstraint y bounds en la función minimize. Sin embargo, debes asegurarte de que tu función objetivo (rms) sea coherente con las restricciones y límites que has especificado.

    En particular, tu restricción a+b+c+d+e+f=1 es una restricción lineal de igualdad, lo que significa que puede ser impuesta exactamente por el algoritmo de optimización. Sin embargo, tu función actual rms no tiene en cuenta esta restricción. En su lugar, solo minimiza el error cuadrático medio de la combinación lineal suma(a*y1 + b*y2 + c*y3 + d*y_4 + e*y5 + f*y6).

    Para asegurarte de que se cumpla la restricción, puedes modificar tu función rms de la siguiente manera:

    def rms(params):
        a, b, c , d, e, f = params
        # asegurar que a+b+c+d+e+f=1
        factor_normalizacion = a + b + c + d + e + f
        a /= factor_normalizacion
        b /= factor_normalizacion
        c /= factor_normalizacion
        d /= factor_normalizacion
        e /= factor_normalizacion
        f /= factor_normalizacion
        # calcular la combinación lineal
        yF = a*y1 + b*y2 + c*y3 + d*y4 + e*y5 + f*y6
        # calcular el error cuadrático medio
        return error_cuadratico_medio(y0, yF)
    

    Aquí, primero calculamos un factor de normalización que asegura que a+b+c+d+e+f=1, y luego dividimos cada coeficiente por este factor. Esto impone la restricción, pero también asegura que los coeficientes sigan representando una combinación lineal válida. Finalmente, calculamos la combinación lineal y el error cuadrático medio como antes.

    Con esta función rms modificada, tu optimización debería generar coeficientes que sumen uno:

    [0.2, 0.1, 0.2, 0.05, 0.3, 0.15]
    

    Ten en cuenta que esto asume que tu función error_cuadratico_medio está implementada correctamente y produce resultados significativos. También debes verificar que la optimización haya convergido a una solución razonable inspeccionando el objeto res devuelto por minimize.

Comments are closed.