Problema con la funzione di minimizzazione in JSLCiao a tutti,
Sto cercando di utilizzare la funzione di minimizzazione in JSL per ottenere i valori di due (o più) variabili che riducono al minimo il quadrato medio dell'errore di un modello di grandi dimensioni. Non riesco a farlo convergere anche se so a quale valore dovrebbe convergere (per tentativi ed errori).
La sintassi di base che ho usato è:
minfun = Minimize( min_test, {kD( 0.4, 0.8 ), wshc( 0.1, 1.5 )}, <<DETAILS></DETAILS>Ho provato diversi messaggi ma non cambiano nulla.
L'obiettivo qui è trovare i valori di kD e wshc minimizzando l'espressione min_test che è essa stessa una sequenza di espressioni valutate come in
min_test = Expr(
Eval( light );
Eval( parafile );
Eval( runprg );
Eval( reshandling2 );
Eval( SSE2 );
);
I valori kD e wshc alterati modificano le espressioni "light" e "parafile" che quindi eseguono un programma eseguibile (nell'espressione runprg) i cui risultati vengono manipolati e da cui l'errore quadratico medio (MSE) è l'ultima cosa che viene valutato nell'espressione SSE2. Per contesto, l'espressione "runprg" invia più file creati a un eseguibile autonomo che simula l'evoluzione termica dei laghi. Ogni passaggio nell'espressione "runprg" richiede circa 10-20 secondi di calcolo, i cui risultati vengono reintegrati in JSL per calcolare MSE.
Il processo stesso sembra funzionare correttamente in quanto legge correttamente il valore della funzione obiettivo in ogni passaggio e sembra passare correttamente i valori dei parametri all'espressione. Il problema è che l'algoritmo "sposta" i parametri kD e wshc così leggermente (solo nella 5a cifra decimale) rispetto ai valori iniziali che ho dato loro che non riesce a convergere. Ad esempio, se inizio con valori iniziali rispettivamente di 0,8 e 0,5, in genere otterrò qualcosa come
0,8
0,49999945654133
alla successiva iterazione e pertanto non influisce in modo significativo sul MSE risultante. Con i limiti dei parametri che ho fornito nella funzione di minimizzazione, c'è molto spazio per lo spostamento dei parametri. Capisco che il mio caso è piuttosto lontano dalla tipica funzione differenziabile semplice. Tuttavia, eseguendo "manualmente" il programma con valori di parametri diversi, so che la funzione obiettivo è piuttosto convessa rispetto ai parametri e quindi ho pensato che la funzione di minimizzazione avrebbe funzionato bene, soprattutto utilizzando il messaggio <
Qualche suggerimento su una soluzione alternativa che potrebbe aiutare in questa situazione?
Molte grazie in anticipo, Yves
Modellazione statistica avanzataAutomazione e scriptingMac OSRe: Problema con la funzione di minimizzazione in JSLL'algoritmo terminerà dopo MaxIter iterazioni, quindi lo aumenterei a un valore molto più grande di quello predefinito e vedrei se questo aiuta.
Re: Problema con la funzione di minimizzazione in JSLGrazie per il suggerimento David, ma temo che non sia d'aiuto. Tuttavia, avrei dovuto essere più chiaro nel dire che il numero di iterazioni effettivamente eseguite prima che si blocchi non è elevato, forse qualcosa come 20-30, ma ogni volta la modifica nei valori dei parametri è troppo piccola per avere alcun impatto.
Yves
Re: Problema con la funzione di minimizzazione in JSLQuesta non è proprio la mia zona, ma sembra che dovrebbe funzionare. Ecco il mio JSL di prova.
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>
Ecco il registro. Sembra strano che un certo numero di chiamate vengano effettuate con le stesse identiche ipotesi iniziali errate, anche se sembrano ottenere una risposta quasi perfetta alla prima *vera* ipotesi.
"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;
Sembra che potresti aspettarti 27 chiamate alla funzione da 10-20 secondi.
Il tuo algoritmo genera la stessa risposta per lo stesso input o c'è una componente casuale? Questo potrebbe fare la differenza.
Re: Problema con la funzione di minimizzazione in JSLCraige molto interessante. Ho seguito il tuo approccio e ho osservato i valori mentre era in funzione. In questo esempio, i miei valori iniziali sono rispettivamente 0.8 e 0.5 .
minfun = Minimize( min_test, {kD( 0.4, 0.8 ), wshc( 0.1, 1.5 )}, <<DETAILS></DETAILS>la seconda iterazione produce questo
/*:2 2 44.86266 210.178 0.080004 128 12 1 0 0.799999 0.50001
e il 3°
/*:3 2 45.33956 0 0.080004 4096 16 0 0 0.799999 0.50001
e non può fare meglio dell'iterazione 2, quindi si ferma qui. Qui, il miglior valore della funzione obiettivo è 44,86 .
Tuttavia, se fornisco "manualmente" all'algoritmo i valori dei parametri di 0,52 e 1,13 (rispettivamente), la funzione obiettivo (MSE) è circa 6,8, molto migliore dei risultati di cui sopra. L'unica cosa che mi viene in mente è che esiste un minimo molto locale ai valori iniziali, ma sembra improbabile perché ottengo lo stesso tipo di risultati indipendentemente da quali siano i miei valori iniziali...
Re: Problema con la funzione di minimizzazione in JSLSono abbastanza sicuro che la minimizzazione dipenda dalle pendenze che lo portano alla risposta.
In passato ho giocato utilizzando una serie di punti di partenza casuali per minimizzare, mantenendo la risposta migliore e creando nuovi punti di partenza casuali con una distribuzione normale attorno a quel punto. Ma funziona solo se hai abbastanza tempo... e non sai mai se hai trovato la risposta migliore.
Re: Problema con la funzione di minimizzazione in JSLSì, propendo per una soluzione di "forza bruta" simile a quella che suggerisci. Oppure dovrei programmare una routine di ottimizzazione Nelder-Mead che potrebbe essere più adatta a questo tipo di problemi. C'è qualche possibilità che qualcuno in JMP abbia già scritto un codice del genere?? 
Grazie, Yves
Re: Problema con la funzione di minimizzazione in JSLÈ difficile dire esattamente cosa sta succedendo senza la possibilità di eseguire io stesso l'esempio, ma ci sono altri due approcci che ti vengono in mente che potresti provare.Il primo è usare il minimizzazione vincolata funzione senza alcun vincolo lineare.Utilizza un metodo diverso da quello minimizzare funzione, quindi potrebbe essere d'aiuto. Quindi, dall'esempio di Craige potresti fare qualcosa del genere:
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} );
Oppure un altro approccio che potresti provare è creare una piccola tabella di dati e utilizzare il profiler per eseguire l'ottimizzazione.Non sono proprio sicuro di quanto funzionerà con la tua formula, ma allego un esempio di come funzionerebbe con l'esempio di Craige. Ecco un'immagine della soluzione che ottieni se ottimizzi la funzione nel profiler:

Se esegui il primo script allegato alla tabella dati, avvierai il profiler prima dell'ottimizzazione.Il secondo script avvia il profiler con la soluzione ottimale. Il profiler utilizza più avvii casuali, quindi è più robusto per trovare la soluzione ottimale globale.
Re: Problema con la funzione di minimizzazione in JSLCiao Laura,
Grazie per i vostri suggerimenti. Finora ho provato solo la prima (minimizzazione vincolata) e sicuramente si comporta in modo diverso rispetto alla funzione di minimizzazione! Tuttavia, ora ho il problema inverso, cioè i parametri si spostano ovunque all'interno dello spazio parametrico consentito senza apparentemente mai raggiungere valori stabili!! Una cosa che non mi è del tutto chiara è la differenza tra le "iterazioni" e il numero di volte in cui viene valutata la funzione obiettivo. Chiaramente non sono la stessa cosa. Avevo impostato un max iter(5) ma la funzione è stata valutata più volte senza convergere. Ho dovuto forzare l'uscita da JMP dopo alcuni minuti.
Comincio a pensare che il tipo di modello che sto cercando di ottimizzare sia piuttosto fastidioso!
Darò una chance al tuo secondo suggerimento! I migliori saluti, Yves