Problema con la función de minimizar en JSLHola a todos,
Estoy intentando utilizar la función de minimizar en JSL para obtener los valores de dos (o más) variables que minimizan el error cuadrático medio de un modelo grande. No puedo lograr que converja aunque sé a qué valor debería converger (por prueba y error).
La sintaxis básica que utilicé es:
minfun = Minimize( min_test, {kD( 0.4, 0.8 ), wshc( 0.1, 1.5 )}, <<DETAILS></DETAILS>He probado diferentes mensajes pero no cambian nada.
El objetivo aquí es encontrar los valores de kD y wshc minimizando la expresión min_test que es en sí misma una secuencia de expresiones evaluadas como en
min_test = Expr(
Eval( light );
Eval( parafile );
Eval( runprg );
Eval( reshandling2 );
Eval( SSE2 );
);
Los valores alterados de kD y wshc modifican las expresiones "light" y "parafile" que luego ejecuta un programa ejecutable (en la expresión runprg) cuyos resultados se manipulan y del cual el error cuadrático medio (MSE) es lo último que se evaluado en la expresión SSE2. Para contextualizar, la expresión "runprg" envía múltiples archivos creados a un ejecutable independiente que simula la evolución térmica de los lagos. Cada paso en la expresión "runprg" requiere entre 10 y 20 segundos de cálculo, cuyos resultados se reingieren en JSL para calcular el MSE.
El proceso en sí parece funcionar correctamente porque lee correctamente el valor de la función objetivo en cada paso y parece pasar los valores de los parámetros correctamente a la expresión. El problema es que el algoritmo "mueve" los parámetros kD y wshc tan ligeramente (sólo en el quinto decimal) en relación con los valores iniciales que les he dado que no logra converger. Por ejemplo, si empiezo con valores iniciales de 0,8 y 0,5, respectivamente, normalmente obtendré algo como
0,8
0.49999945654133
en la siguiente iteración y por lo tanto no afecta significativamente el MSE resultante. Con los límites de parámetros que he proporcionado en la función de minimizar, hay mucho espacio para que se muevan los parámetros. Entiendo que mi caso dista bastante de la típica función diferenciable simple. Sin embargo, al ejecutar "manualmente" el programa con diferentes valores de parámetros, sé que la función objetivo es bastante convexa con respecto a los parámetros y pensé que la función de minimización funcionaría bien, especialmente usando el mensaje <
¿Alguna sugerencia de solución alternativa que pueda ayudar en esta situación?
Muchas gracias de antemano, Yves.
Modelado estadístico avanzadoAutomatización y secuencias de comandosMac OSRe: Problema con la función de minimizar en JSLEl algoritmo finalizará después MaxIter iteraciones, por lo que lo aumentaría a un valor mucho mayor que el predeterminado y vería si eso ayuda.
Re: Problema con la función de minimizar en JSLGracias por la sugerencia David, pero me temo que no ayuda. Sin embargo, debería haber sido más claro en que el número de iteraciones que realmente hace antes de fallar no es alto, quizás entre 20 y 30, pero cada vez el cambio en los valores de los parámetros es demasiado pequeño para tener algún impacto.
Yves
Re: Problema con la función de minimizar en JSLEsta no es realmente mi área, pero parece que debería funcionar. Aquí está mi JSL de prueba.
aa = expr(
Show( "evaluating", Char( a, 19, 16 ), Char( b, 19, 16 ) ); // peek inside
(a - 10) ^ 2 + (b - 11) ^ 2 // the function, roots at 10 and 11
);
min_test = Expr( Eval( aa ) );
a = 33; // initial guesses
b = -55; // (not very good)
minfun = Minimize(
min_test,
{a( -100, 100 ), b( -100, 100 )},
<<DETAILS></DETAILS>
Aquí está el registro. Parece extraño que se realicen varias llamadas con exactamente las mismas malas suposiciones iniciales, aunque parecen obtener una respuesta casi perfecta en la primera suposición *real*.
"evaluating";
Char(a, 19, 16) = "33.0000000000000000";
Char(b, 19, 16) = "-55.000000000000000";
"evaluating";
Char(a, 19, 16) = "33.0000000000000000";
Char(b, 19, 16) = "-55.000000000000000";
"evaluating";
Char(a, 19, 16) = "33.0000000000000000";
Char(b, 19, 16) = "-55.000000000000000";
"evaluating";
Char(a, 19, 16) = "33.0000000000000000";
Char(b, 19, 16) = "-55.000000000000000";
"evaluating";
Char(a, 19, 16) = "33.0000005066394806";
Char(b, 19, 16) = "-55.000000000000000";
"evaluating";
Char(a, 19, 16) = "32.9999994933605194";
Char(b, 19, 16) = "-55.000000000000000";
"evaluating";
Char(a, 19, 16) = "33.0000000000000000";
Char(b, 19, 16) = "-54.999999165534973";
"evaluating";
Char(a, 19, 16) = "33.0000000000000000";
Char(b, 19, 16) = "-55.000000834465027";
"evaluating";
Char(a, 19, 16) = "33.0002058854513791";
Char(b, 19, 16) = "-55.000000000000000";
"evaluating";
Char(a, 19, 16) = "32.9997941145486209";
Char(b, 19, 16) = "-55.000000000000000";
"evaluating";
Char(a, 19, 16) = "33.0000000000000000";
Char(b, 19, 16) = "-54.999660894550665";
"evaluating";
Char(a, 19, 16) = "33.0000000000000000";
Char(b, 19, 16) = "-55.000339105449335";
"evaluating";
Char(a, 19, 16) = "33.0003391054493349";
Char(b, 19, 16) = "-54.999660894550665";
"evaluating";
Char(a, 19, 16) = "32.9996608945506651";
Char(b, 19, 16) = "-54.999660894550665";
"evaluating";
Char(a, 19, 16) = "33.0003391054493349";
Char(b, 19, 16) = "-55.000339105449335";
"evaluating";
Char(a, 19, 16) = "32.9996608945506651";
Char(b, 19, 16) = "-55.000339105449335";
nParm=2 SR1 ******************************************************
Iter nFree Objective RelGrad NormGrad2 Ridge nObj nGrad nHess Parm0 Parm1
0 2 4885 9770 9770 0 1 1 1 33 -55
"evaluating";
Char(a, 19, 16) = "9.9999350076876112";
Char(b, 19, 16) = "11.0000734771922168";
"evaluating";
Char(a, 19, 16) = "9.9999351715994163";
Char(b, 19, 16) = "11.0000734771922168";
"evaluating";
Char(a, 19, 16) = "9.9999348437758062";
Char(b, 19, 16) = "11.0000734771922168";
"evaluating";
Char(a, 19, 16) = "9.9999350076876112";
Char(b, 19, 16) = "11.0000736560072454";
"evaluating";
Char(a, 19, 16) = "9.9999350076876112";
Char(b, 19, 16) = "11.0000732983771883";
1 2 9.623e-9 0.006344 1.925e-8 0 1 1 0 9.999935 11.00007
"evaluating";
Char(a, 19, 16) = "9.9999999999733351";
Char(b, 19, 16) = "10.9999999999907079";
"evaluating";
Char(a, 19, 16) = "10.0000001638861082";
Char(b, 19, 16) = "10.9999999999907079";
"evaluating";
Char(a, 19, 16) = "9.9999998360605620";
Char(b, 19, 16) = "10.9999999999907079";
"evaluating";
Char(a, 19, 16) = "9.9999999999733351";
Char(b, 19, 16) = "11.0000001788046422";
"evaluating";
Char(a, 19, 16) = "9.9999999999733351";
Char(b, 19, 16) = "10.9999998211767736";
2 2 7.97e-22 2.42e-15 1.59e-21 0 1 1 0 10 11
Convergence SUCCESS: Gradient
Time: 0
"evaluating";
Char(a, 19, 16) = "9.9999999999733351";
Char(b, 19, 16) = "10.9999999999907079";
minfun = 7.97360035815878e-22;
a = 9.99999999997334;
b = 10.9999999999907;
Parece que podría esperar 27 llamadas a la función de 10 a 20 segundos.
¿Su algoritmo genera la misma respuesta para la misma entrada o tiene un componente aleatorio? Eso podría hacer una diferencia.
Re: Problema con la función de minimizar en JSLMuy interesante Craig. Seguí su enfoque y eché un vistazo a los valores mientras estaba en ejecución. En este ejemplo, mis valores iniciales son 0,8 y 0,5, respectivamente.
minfun = Minimize( min_test, {kD( 0.4, 0.8 ), wshc( 0.1, 1.5 )}, <<DETAILS></DETAILS>la segunda iteración produce esto
/*:2 2 44.86266 210.178 0.080004 128 12 1 0 0.799999 0.50001
y el tercero
/*:3 2 45.33956 0 0.080004 4096 16 0 0 0.799999 0.50001
y no puede hacerlo mejor que la iteración 2, por lo que se detiene allí. Aquí, el mejor valor de la función objetivo es 44,86.
Sin embargo, si le doy "manualmente" al algoritmo los valores de parámetro de 0,52 y 1,13 (respectivamente), la función objetivo (MSE) es aproximadamente 6,8, mucho mejor que los resultados anteriores. Lo único que se me ocurre es que hay un mínimo muy local en los valores iniciales, pero eso parece poco probable porque obtengo el mismo tipo de resultados sin importar cuáles sean mis valores iniciales...
Re: Problema con la función de minimizar en JSLEstoy bastante seguro de que minimizar depende de las pendientes que lo lleven a la respuesta.
En el pasado, he jugado usando un montón de puntos de partida aleatorios para minimizar, manteniendo la mejor respuesta y creando nuevos puntos de partida aleatorios con una distribución normal alrededor de ese punto. Pero eso sólo funciona si tienes suficiente tiempo... y nunca sabes si has encontrado la mejor respuesta.
Re: Problema con la función de minimizar en JSLSí, me inclino por una solución de "fuerza bruta" similar a la que usted sugiere. De lo contrario, tendría que programar una rutina de optimización de Nelder-Mead que podría adaptarse mejor a este tipo de problemas. ¿Existe alguna posibilidad de que alguien en JMP ya haya escrito dicho código? 
Gracias, yves
Re: Problema con la función de minimizar en JSLEs difícil decir exactamente qué está sucediendo sin la capacidad de ejecutar el ejemplo yo mismo, pero se me ocurren otros dos enfoques que posiblemente podría probar.La primera es utilizar el minimizar restringido funcionar sin restricciones lineales.Utiliza un método diferente al minimizar funciona, por lo que posiblemente podría ayudar. Entonces, según el ejemplo de Craige, podrías hacer algo como lo siguiente:
aa = expr(
Show( "evaluating", Char( a, 19, 16 ), Char( b, 19, 16 ) ); // peek inside
(a - 10) ^ 2 + (b - 11) ^ 2 // the function, roots at 10 and 11
);
min_test = Expr( Eval( aa ) );
minFun =
Constrained Minimize(
min_test,
{a( -100, 100 ), b( -100, 100 )},
<<StartingValues( [0, 0] ), <<show details(true)
);
Eval List( {a, b, minFun} );
U otro enfoque que podría probar es crear una pequeña tabla de datos y usar el generador de perfiles para realizar la optimización.No estoy realmente seguro de qué tan bien funcionará con su fórmula, pero adjunto un ejemplo de cómo funcionaría con el ejemplo de Craige. Aquí hay una imagen de la solución que obtiene si optimiza la función en el generador de perfiles:

Si ejecuta el primer script adjunto a la tabla de datos, iniciará el generador de perfiles antes de la optimización.El segundo script inicia el generador de perfiles con la solución óptima. El generador de perfiles utiliza múltiples inicios aleatorios, por lo que es más sólido para encontrar la solución óptima global.
Re: Problema con la función de minimizar en JSLHola, Laura,
Gracias por tus sugerencias. Hasta ahora solo he probado la primera (minimización restringida) y seguro que se comporta de manera diferente a la función de minimización. Sin embargo, ahora tengo el problema inverso, es decir, los parámetros se mueven por todas partes dentro del espacio de parámetros permitido sin aparentemente alcanzar valores estables. Una cosa que no tengo muy clara es la diferencia entre "iteraciones" y el número de veces que se evalúa la función objetivo. Está claro que no son lo mismo. Había establecido un iter máximo (5) pero la función se evaluó muchas más veces sin converger. Tuve que forzar el cierre de JMP después de unos minutos.
¡Estoy empezando a pensar que el tipo de modelo que intento optimizar es bastante molesto!
¡Le daré una oportunidad a tu segunda sugerencia! Saludos cordiales, Yves.