Tra le tante novità di JMP13 sono state rinnovate le funzioni Minimize() e Maximize() in JSL. Queste funzioni JSL sono ottimizzatori iterativi che trovano i valori estremi di una funzione dati i valori iniziali. La GIF qui sotto è una dimostrazione visiva per dare un'idea di come funziona l'algoritmo in un semplice ambiente unidimensionale.

Mentre la maggior parte JMP gli utenti troveranno le piattaforme predefinite (come Fit Y by X e Nonlinear) sufficienti per i loro problemi di ottimizzazione, ma non è sempre così, e queste funzioni JSL offrono grande flessibilità e generalità. Queste funzioni offrono all'utente l'accesso agli stessi ottimizzatori di cui si avvalgono gli sviluppatori JMP quando creano piattaforme JMP.
In generale, ovunque sia segnalata una probabilità JMP , il modello è stato adattato con una tecnica di ottimizzazione chiamata Maximium Likelihood. Allo stesso modo, il nome stesso, Minimi quadrati, descrive il metodo di ottimizzazione utilizzato per adattare i modelli lineari. Sebbene JMP disponga di un'ampia varietà di modelli, a volte si desidera adattare un modello personalizzato che non è precostruito in JMP. Inoltre, per ragioni pedagogiche, può essere utile per gli studenti trasformare i programmi di modellazione statistica in problemi di ottimizzazione per comprendere come funziona il modello.
Le prossime sezioni illustrano le basi dell'utilizzo di un ottimizzatore generale. Gli utenti che hanno già familiarità con gli ottimizzatori iterativi potrebbero voler passare all'ultima sezione per vedere la sintassi di esempio per alcune delle funzionalità avanzate in Minimize() e Maximize().
Per il resto di questo articolo, scriverò tutto dal punto di vista di Minimize(). Si noti che minimizzare una funzione, f(x), equivale a massimizzare -1 * f(x), quindi scambiare “f(x)” con “–f(x)”, “minimizzare” con “massimizzare”, “concavo " con "convesso", ecc., generalizzerà i risultati in Maximize().
Esempio semplice
Il problema di ottimizzazione più elementare richiede due argomenti di funzione: un'espressione e le variabili da ottimizzare. Come in passato, una chiamata come Minimize( espressione , { x, y }) restituisce il valore minimo ottenuto. Per dimostrare come funziona, il primo esempio minimizza una banale espressione quadratica.
x = 2; /*starting value for x */
y = 2; /*starting value for y */
expr1 = expr((x ^ 2 + (y - 1) ^ 2));
minFun = Minimize( expr1, {x, y});
Show(minFun, x, y);
Produzione:
minFun = 0;
x = 0;
y = 1;
Dopo qualche riflessione, possiamo convincerci che il minimo di questa funzione dovrebbe essere 0 e verificarsi in x = 0 e y = 1. Dopo aver eseguito questo script, vediamo che è davvero così.
Si noti che xey sono stati modificati dalla funzione Minimize() per riflettere i valori degli argomenti che hanno raggiunto il valore minimo della funzione. Un diagramma di contorno per questa funzione è mostrato qui:
Scelta dei valori iniziali
L'ottimizzatore deve iniziare con un particolare insieme di valori di parametri, chiamati valori iniziali, e poi tenta iterativamente di migliorarli. Il successo e il fallimento dell'ottimizzazione dipendono fortemente dalla qualità dei valori iniziali. Parte dell'arte di sviluppare software statistico ruota attorno alla ricerca di valori iniziali efficaci. Esistono diversi modi per inventarli. È essenziale che la funzione possa essere valutata ai valori iniziali (cioè non restituisca un valore mancante).A volte la cosa migliore che puoi fare è trovare valori "predefiniti" sensati che funzionino bene, come impostare i parametri di regressione uguali a zero. Spesso i migliori valori iniziali si ottengono adattando un modello più semplice ai dati e utilizzando tali risultati, ad esempio utilizzando le stime dei minimi quadrati lineari come valori iniziali per una regressione logistica.
Punti critici globali e locali
Un avvertimento importante da tenere presente è che Minimize trova i punti critici locali, che possono o meno essere il minimo globale. Il prossimo esempio è un semplice polinomio che illustra questo. Con i valori iniziali di x = 0, y = 0, si trova un minimo locale in x = 0,25 e y = -0,0833. Tuttavia, per x=-1 e y = -1, la risposta va a –infinito.
x = 0; /*starting value for x */
y = 0; /*starting value for y */
expr2 = expr((y * 3 - 2 * x ^ 2 - 12 * x * y));
minFun = Minimize(expr2, {x, y});
Show( x, y, minFun);
Produzione:
x = 0.25;
y = -0.0833333333333333;
minFun = -0.125;
x = -1; /*starting value for x */
y = -1; /*starting value for y */
minFun = Minimize(expr2, {x, y});
Show( x, y, minFun);
Produzione:
Optimization failed: Failed: Maximum Iterations Exceeded
x = -6.55731043158825e+85;
y = -1.31136919553771e+89;
minFun = -1.03197258530774e+176;
Si noti che Minimize() non fornisce alcun avviso per questo perché non sa se ha raggiunto un minimo locale o globale. Infatti, in questo esempio, il primo insieme di valori iniziali convergono ad a punto di sella , che, in questo caso, è un minimo in una direzione e un massimo in un'altra. Se si desidera un minimo globale e il problema non lo è convesso (o se non sei sicuro), un'opzione è provare più valori iniziali per verificare se convergono tutti nella stessa posizione. In alternativa, se ci sono due o meno parametri, la funzione può essere tracciata, il che rende facile capire se si tratta di un minimo locale, ad esempio ecco il diagramma dei contatori dell'ultima funzione con i due diversi valori iniziali:
Esempio realistico 1: minimizzare una funzione di perdita
In statistica, le stime dei parametri sono spesso determinate trovando i valori dei parametri che minimizzano la somma dei termini di errore al quadrato, somma (osservata – prevista) ^ 2. Ad esempio, si consideri il Caso di test NIST Dan Wood non lineare (“ " ).
Qui, vogliamo minimizzare la somma degli errori quadratici dato il modello, cioè trovare gli argomenti per
E
che minimizza
.
Il seguente codice JSL lo implementa.
x = [1.309, 1.471, 1.49, 1.565, 1.611, 1.68];
y = [2.138, 3.421, 3.597, 4.34, 4.882, 5.66];
b1 = 1; /*starting value for b1 */
b2 = 5; /*starting value for b2 */
sseExpr = Expr(
Summation( i = 1, 6, (y[i] - b1 * x[i] ^ b2) ^ 2 )
);
minFun = Minimize( sseExpr, {b1, b2} );
Show( b1, b2, minFun );
Produzione:
b1 = 0.768858626467797;
b2 = 3.86041439611906;
minFun = 0.00431730849313329;
Trama di contorno:
Esempio realistico 2: regressione logistica lineare semplice
Come accennato in precedenza, un altro uso comune delle routine di ottimizzazione è la ricerca di stime di massima verosimiglianza. Ad esempio, supponiamo di aver osservato 100 valori di risposta binaria, y, e un predittore continuo associato, x, e di voler adattare un modello di regressione logistica. Per una regressione logistica lineare semplice, assumiamo che per ogni i,
, Dove
. La probabilità del log associata è
. Per brevità ho saltato le derivazioni, ma si possono trovare maggiori dettagli Qui .Il seguente codice JSL massimizza questa probabilità:
b0 = 0;
b1 = 0;
logLik = Expr(
Summation( i = 1, 100, y[i] * log( logist(b0 + b1 * x[i]) ) + (1 - y[i]) * log(1- logist(b0 + b1 * x[i]) ) )
);
minFun = Maximize( logLik, {b0, b1} );
Show( b0, b1);
Produzione:
b0 = 0.169912186525928;
b1 = 2.37904556815702;
Pertanto, questo modello prevede che per qualche nuovo valore x, le probabilità stimate sono:

Con una trama dell'adattamento:

Se interessati, consultare lo script JSL allegato per i valori specifici di xey che ho utilizzato per questo esempio e per vedere come li ho generati.
Nuova funzionalità opzionale <
La mia nuova funzionalità preferita consente all'utente di recuperare i dettagli dell'output utilizzando l'argomento opzionale <
x = [1.309, 1.471, 1.49, 1.565, 1.611, 1.68];
y = [2.138, 3.421, 3.597, 4.34, 4.882, 5.66];
b1 = 1; /*starting value for b1 */
b2 = 5; /*starting value for b2 */
sseExpr = Expr(
Summation( i = 1, 6, (y[i] - b1 * x[i] ^ b2) ^ 2 )
);
{objVal, iters, gradient, hessian} = Minimize( sseExpr, {b1, b2} , <<SHOWDETAILS></SHOWDETAILS>
Produzione:
nParm=2 Newton ******************************************************
Iter nFree Objective RelGrad NormGrad2 Ridge nObj nGrad nHess Parm0 Parm1
0 2 149.7192 332.8046 182170.1 0 1 1 1 1 5
1 2 31.87877 101.5969 19003.84 0 1 1 1 1.010662 4.225573
2 2 4.215765 28.12531 1448.206 0 1 1 1 1.024865 3.630484
3 2 0.378951 7.636836 51.97781 0 1 1 1 1.058064 3.252922
4 2 0.153712 0.003012 0.615041 0.125 2 1 1 1.008287 3.272327
5 2 0.08553 0.100794 0.100071 0.031 1 1 1 0.937871 3.42031
6 2 0.035115 0.074061 0.132669 0.016 1 1 1 0.868411 3.588806
7 2 0.00829 0.164555 1.452852 0 1 1 1 0.772783 3.836035
8 2 0.00432 1.62e-5 0.00021 0 1 1 1 0.769751 3.858031
9 2 0.004317 2.313e-9 2.057e-8 0 1 1 1 0.768859 3.860414
Convergence SUCCESS: Gradient
Time: 0.033333333209157
b1 = 0.768858626467797;
b2 = 3.86041439611906;
objVal = 0.00431730849313329;
iters = 9;
gradient = [-0.000193577585687388, -0.000060622489899298];
hessian = [351.567213300015 123.108731500088, 123.108731500088 43.9222933905666];
Elenco di tutte le funzionalità facoltative per Minimize() e Maximize()
- Imposta i limiti superiore e inferiore : imposta i limiti inferiori e/o superiori per le variabili. Per esempio, Riduci a icona( x^2, x(1,5) ), limita x a rimanere tra 1 e 5 e Riduci a icona ( x^2, x(. , 5) ), garantisce che x sia inferiore a 5 senza limite inferiore .
- Imposta il numero massimo di iterazioni : Il numero massimo di iterazioni per impostazione predefinita è 250 ma può essere modificato con < nuovoMaxIter ). Il valore predefinito è 250.
- Imposta la tolleranza per la convergenza : Il criterio di convergenza può essere modificato con < nuovaTolleranza ). Il valore predefinito è 10^-8.
- Mostra più dettagli : L'opzione <
- Utilizzare l'approssimazione numerica per i derivati : Per impostazione predefinita, Minimize() tenterà di trovare le derivate analitiche, ma in alcuni casi le approssimazioni numeriche potrebbero funzionare meglio. Selezionare questa opzione aggiungendo "<
- Immettere il gradiente definito dall'utente : Nella maggior parte dei casi, Minimize() sarà in grado di calcolare i gradienti analitici per impostazione predefinita. Nell'improbabile caso in cui lo desideri, un utente può inserire il proprio gradiente. Per fare ciò, utilizzare <
- Immettere l'iuta definita dall'utente : L'inserimento di una tela di iuta definita dall'utente è ancora più complicato. La sintassi si complica molto rapidamente e consiglierei di utilizzarla solo come ultima risorsa. Per inserire una tela di iuta analitica, utilizzare <
Esempio semplice con tutti gli argomenti opzionali
Di seguito è riportato un utile modello di Minimize() con tutti gli argomenti opzionali selezionati. In JMP 13.2, questo esempio è disponibile anche in Riduci a icona nell'Indice di scripting con JMP. È l'Esempio 3 (selezionalo scegliendo il menu a discesa accanto a Esempio 1).
x = 0;
y = 0;
{objVal, iters, gradient, hessian} =
Minimize(
((2 * x ^ 2 + 12 * x * y - y * 3)),
{x( -1, 1 ), y( -1, 1 )},
<<MAXITER></MAXITER>
Rimani aggiornato per un possibile post futuro sul blog sulle nuove funzioni JSL, Constrained Minimize() e Constrained Maximize(), che ottimizzano i problemi con funzioni obiettivo non lineari e vincoli lineari.