Come specificare una matrice di correlazione in Profiler per la simulazione?Ciao,
Sto scrivendo uno script per creare dati normali multivariati con un numero specificato di righe, vettori di deviazione media / standard e struttura di correlazione da un insieme di dati di esempio. Vorrei sfruttare il simulatore nella piattaforma Profiler per generare la tabella dati attraverso i seguenti passaggi:
- Calcola la media campionaria e la deviazione standard per ciascuna variabile.
- Genera matrice di correlazione dai dati del campione.
- Simula dati multivariati utilizzando le statistiche di riepilogo da (1) e (2).
Attualmente, il mio script genera la tabella dati simulata con i mezzi appropriati e le deviazioni standard per ciascuna variabile, ma non riesco a mantenere correttamente la struttura di correlazione tra le variabili. Credo che la causa del mio problema sia il modo in cui specifico [ NxN correlazioni] con X Correlazioni utilizzando una variabile invece di specificare esplicitamente la matrice di correlazione (ad es. [1 0,3 0, 0,3 1 0, 0 0 1]), ma le mie capacità di risoluzione dei problemi non mi hanno lasciato alcuna soluzione. Script corrente e output previsto rispetto a quello effettivo forniti di seguito, eventuali suggerimenti su come ottenere questi passaggi sono i benvenuti:
JSL:
names default to here(1);
Try( Close( Data Table(dt) ) );
If( Is Empty( dt ),
Try( dt = Open(), Throw( "No data found" ) )
);
ncol = NCol(dt);
//Dialog Window.
Dlg = New Window("New Window",
<< Modal,
BorderBox(left(3), top(2),
V List Box(
TextBox("Simulate multivariate data"),
HListBox(
VListBox(
PanelBox("Select variables",
colListData = ColListBox(all,nLines,(min(ncol,10)))
),
),
PanelBox("Cast Selected Variables",
LineupBox(NCol(2), Spacing(3),
ButtonBox("Variables", colListY << Append(colListData << Get Selected)),
colListY = ColListBox(nLines(6), "numeric"))
),
//specifications - not in use.
PanelBox("Enter Specifications",
Spacer Box(Size(10, 1)),
HListBox(
VListBox(
Spacer Box(Size(5, 10)),
lsl1 = Number Edit Box(, 3),
Spacer Box(Size(5, 10)),
lsl2 = Number Edit Box(, 3),
Spacer Box(Size(5, 10)),
lsl3 = Number Edit Box(, 3),
Spacer Box(Size(5, 10)),
lsl4 = Number Edit Box(, 3)
),
SpacerBox(Size(10,10)),
VListBox(
Spacer Box(Size(5, 10)),
usl1 = Number Edit Box(, 3),
Spacer Box(Size(5, 10)),
usl2 = Number Edit Box(, 3),
Spacer Box(Size(5, 10)),
usl3 = Number Edit Box(, 3),
Spacer Box(Size(5, 10)),
usl4 = Number Edit Box(, 3)
)
),
),
PanelBox("Action",
LineupBox(NCol(1),
// OK button
Button Box("OK",
lsl_mat = J(4,1, .);
lsl_mat[1] = Eval(lsl1 << Get);
lsl_mat[2] = Eval(lsl2 << Get);
lsl_mat[3] = Eval(lsl3 << Get);
lsl_mat[4] = Eval(lsl4 << Get);
usl_mat = J(4,1, .);
usl_mat[1] = Eval(usl1 << Get);
usl_mat[2] = Eval(usl2 << Get);
usl_mat[3] = Eval(usl3 << Get);
usl_mat[4] = Eval(usl4 << Get);
// Store summary statistics
tpListY = colListY << Get Items;
tpMean = J(4, 1, 0);
tpSD = J(4, 1, 0);
for (i=1, i <= nitems(tpListY), i++,
one_col = tpListY[i];
Meani = Col Mean(Column(dt, one_col));
SDi = Col Std Dev(Column(dt, one_col));
tpMean[i] = Meani;
tpSD[i] = SDi;
);
Dlg << CloseWindow
),
// Cancel button
Button Box("Cancel", Dlg << CloseWindow),
Spacer Box(Size(10,10)),
// Remove button
Button Box("Remove", collistY << RemoveSelected)
)
),
)
)
)
);
//correlation matrix
corr = multivariate(
Y(Eval List(tpListY)),
estimation method("Row-wise"),
matrix format("Square"),
scatterplot matrix(0)
);
corr.run = corr << run;
corr.rep = corr.run << report;
corr.mat = corr.rep["Correlations"][matrix box(1)] << get(1);
//only used to launch profiler
prof.x = J(2,4 ,1);
prof.tbl = as table(prof.x, << column names(tpListY), << invisible);
prof.tbl << new column("Y",
Formula( :TP1 + :TP2 + :TP3 + :TP4)
);
prof.tbl = current data table();
random reset(1234);
//specify multivariate data from summary statistics
sim.design = Profiler(
Y(:Y),
Invisible
);
sim.design << Simulator(
1,
Factors(
TP1 << multivariate( tpMean[1], tpSD[1]),
TP2 << multivariate( tpMean[2], tpSD[2]),
TP3 << multivariate( tpMean[3], tpSD[3]),
TP4 << multivariate( tpMean[4], tpSD[4]),
),
X Correlations(
1,
tpListY,
corr.mat
),
N Runs(10000)
);
//Make data table
report( sim.design )["Simulate to Table"][button box( 1 )] << click( 1 );
sim.dt = data table( 1 );
sim.dt << set name( "Simulated multivariate data" );
sim.dt << delete columns({"Y","Obj"});Produzione attesa rispetto a quella effettiva:
atteso rispetto al reale
Tabella datiScriptingRi: Come specificare una matrice di correlazione in Profiler per la simulazione?Ciao @eangello ,
Questa è una domanda interessante e vorrei provare ad aiutarti se posso, ma non sono in grado di riprodurre il tuo problema. Quando provo a eseguire il tuo script, mi chiede di aprire una tabella di dati dalla directory dei dati di esempio. Un problema qui è che non so con quale tabella dati stai lavorando e non avrò lo stesso problema. Potete fornire la tabella dati con cui state lavorando?
Se seleziono una tabella di dati dai dati di esempio, ad esempio il file di processo gaussiano 2D example.jmp, la finestra di dialogo successiva chiede di lanciare le colonne nei ruoli, ma poi quando faccio clic su OK, ottengo l'errore che c'è un name Nome in eccesso o valutazione di "Button", Button (-1) / * ### * /. Quindi, un altro errore viene visualizzato dalla riga 124 del codice in cui non gli piace il comando sim.design << Simulator () send.
A quanto pare, hai una tabella dati in cui funziona. Puoi condividerlo? O fornire maggiori dettagli su quale tabella stai utilizzando per generare l'output che hai mostrato nel tuo post?
Grazie!,
DS
Ri: Come specificare una matrice di correlazione in Profiler per la simulazione?Ciao @DiedrichSchmidt ,
Non ho dovuto eseguire la due diligence prima della pubblicazione: ecco un campione di 10 righe dai dati campione (4 X; TP1-TP4). Lo script corrente è limitato a 4 variabili, ma spero di essere in grado di ridimensionarlo a N variabili in futuro. Questa tabella di dati di esempio ricrea il mio problema. Credo che l'errore del nome non risolto provenga dalla finestra di dialogo (forse annulla / rimuovi pulsanti), ma non ho trovato la causa principale.
Grazie,
EA
Ri: Come specificare una matrice di correlazione in Profiler per la simulazione?Ciao @eangello ,
Grazie per la tabella dei dati. Posso ricreare il tuo problema mentre menzioni. Una cosa che sto notando è che quando esegui il simulatore, non crea l'istogramma accanto al profiler, a differenza dell'esempio di tiretread nell'indice della guida su X Correlations.
Penso che stiano succedendo due cose:
1. chiamando tpListY
2. chiamando corr.mat
Non sono sicuro del perché, ma penso che sia necessario "compitare" esplicitamente l'elenco per le correlazioni X nel codice e questo include la matrice di correlazione., Quindi invece di chiamare tpListY, è necessario sostituirlo con {TP1, TP2 , TP3, TP4}. Allo stesso modo, è necessario inserire la matrice di correlazione 4x4 (o NxN) effettiva tra le parentesi quadre [].
Pensavo che fare qualcosa come Parse (tpListY [1]) avrebbe funzionato, ma non riesco a farlo funzionare, anche con un Eval () avvolto attorno ad esso. Posso farlo funzionare automaticamente solo se inserisco il codice JSL come {TP1, TP2, TP3, TP4}. Si noti che quando si inserisce la matrice di correlazione NxN, in realtà utilizza il triangolo in basso a sinistra della matrice per compilare la tabella.
Ho anche pensato che chiamare gli elementi di corr.mat potrebbe funzionare, come in corr.mat [1], ecc., Ma neanche questo funziona. Se ci provo, ottengo un errore di token di matrice non valido e non sono proprio sicuro del perché, perché gli elementi di corr.mat sono numeri.
Il codice seguente (ho modificato la tua funzione per cambiarla un po ') funziona per fornire l'output previsto, ma non aiuta con il tuo desiderio di espandere da un sistema 4x4 a un sistema NxN.
names default to here(1);
Try( Close( Data Table(dt) ) );
If( Is Empty( dt ),
Try( dt = Open(), Throw( "No data found" ) )
);
ncol = NCol(dt);
//Dialog Window.
Dlg = New Window("New Window",
<< Modal,
BorderBox(left(3), top(2),
V List Box(
TextBox("Simulate multivariate data"),
HListBox(
VListBox(
PanelBox("Select variables",
colListData = ColListBox(all,nLines,(min(ncol,10)))
),
),
PanelBox("Cast Selected Variables",
LineupBox(NCol(2), Spacing(3),
ButtonBox("Variables", colListY << Append(colListData << Get Selected)),
colListY = ColListBox(nLines(6), "numeric"))
),
//specifications - not in use.
PanelBox("Enter Specifications",
Spacer Box(Size(10, 1)),
HListBox(
VListBox(
Spacer Box(Size(5, 10)),
lsl1 = Number Edit Box(, 3),
Spacer Box(Size(5, 10)),
lsl2 = Number Edit Box(, 3),
Spacer Box(Size(5, 10)),
lsl3 = Number Edit Box(, 3),
Spacer Box(Size(5, 10)),
lsl4 = Number Edit Box(, 3)
),
SpacerBox(Size(10,10)),
VListBox(
Spacer Box(Size(5, 10)),
usl1 = Number Edit Box(, 3),
Spacer Box(Size(5, 10)),
usl2 = Number Edit Box(, 3),
Spacer Box(Size(5, 10)),
usl3 = Number Edit Box(, 3),
Spacer Box(Size(5, 10)),
usl4 = Number Edit Box(, 3)
)
),
),
PanelBox("Action",
LineupBox(NCol(1),
// OK button
Button Box("OK",
lsl_mat = J(4,1, .);
lsl_mat[1] = Eval(lsl1 << Get);
lsl_mat[2] = Eval(lsl2 << Get);
lsl_mat[3] = Eval(lsl3 << Get);
lsl_mat[4] = Eval(lsl4 << Get);
usl_mat = J(4,1, .);
usl_mat[1] = Eval(usl1 << Get);
usl_mat[2] = Eval(usl2 << Get);
usl_mat[3] = Eval(usl3 << Get);
usl_mat[4] = Eval(usl4 << Get);
// Store summary statistics
tpListY = colListY << Get Items;
tpMean = J(4, 1, 0);
tpSD = J(4, 1, 0);
for (i=1, i <= nitems(tpListY), i++,
one_col = tpListY[i];
Meani = Col Mean(Column(dt, one_col));
SDi = Col Std Dev(Column(dt, one_col));
tpMean[i] = Meani;
tpSD[i] = SDi;
);
Dlg << CloseWindow
),
// Cancel button
Button Box("Cancel", Dlg << CloseWindow),
Spacer Box(Size(10,10)),
// Remove button
Button Box("Remove", collistY << RemoveSelected)
)
),
)
)
)
);
//correlation matrix
corr = multivariate(
Y(Eval List(tpListY)),
estimation method("Row-wise"),
matrix format("Square"),
scatterplot matrix(0)
);
corr.run = corr << run;
corr.rep = corr.run << report;
corr.mat = corr.rep["Correlations"][matrix box(1)] << get(1);
//only used to launch profiler
prof.x = J(200,4 ,1);
prof.tbl = as table(prof.x, << column names(tpListY), << invisible);
prof.tbl << new column("Y",
Formula( :TP1+:TP2^2-:TP3+:TP4*Random Normal(0,2))
);
prof.tbl = current data table();
random reset(1234);
//specify multivariate data from summary statistics
sim.design = Profiler( Y( :Y ), Invisible );
sim.design << Simulator(
1,
Factors(
TP1 << multivariate( tpMean[1], tpSD[1] ), TP2 << multivariate( tpMean[2], tpSD[2] ),
TP3 << multivariate( tpMean[3], tpSD[3] ), TP4 << multivariate( tpMean[4], tpSD[4] ),
),
Responses( Y << No Noise ),
Automatic Histogram Update( 1 ),
X Correlations( 1, {TP1, TP2, TP3, TP4},
[1 0.6401843997 0.670478399654806 0.6405126152, 0.6401843997 1 0.9443055859 0.8815992957, 0.6704783997 0.9443055859 1 0.9355872238, 0.6405126152 0.8815992957 0.9355872238 1]
),
N Runs( 10000 ),
Simulate
);
//Make data table
report( sim.design )["Simulate to Table"][button box( 1 )] << click( 1 );
sim.dt = data table( 1 );
sim.dt << set name( "Simulated multivariate data" );
sim.dt << delete columns({"Y","Obj"});Deve esserci un modo per farlo, poiché puoi chiamare gli elementi di tpMean e tpSD per riempire il rumore multivariato per i fattori. Penso che qualcuno con più esperienza in JSL potrebbe essere necessario per commentare questo.
Infine, penso che tu abbia ragione su una delle caselle dei pulsanti, ma non sono riuscita a individuarla esattamente - ero più concentrato sul tentativo di risolvere i problemi di tpListY e corr.mat!;)
Sono davvero interessato a quello che scopri.
In bocca al lupo,
DS
Ri: Come specificare una matrice di correlazione in Profiler per la simulazione?Ciao @DiedrichSchmidt ,
Grazie per l'aiuto nella risoluzione dei problemi, molto apprezzato. Ho giocato con funzioni simili come Eval, Eval Espr (Espr (x) ) , e Evalinsert e ha trovato una soluzione forzando la valutazione delle variabili di colonna e matrice prima di inviarle a Profiler (che X Correlazioni sembra accettare). Ho applicato la stessa soluzione sopra per rendere il mio Profiler flessibile a nomi di colonne diversi. Ora la mia struttura di correlazione viene mantenuta nei dati simulati.
new.design = evalinsert(
"\[sim.design << Simulator(
1,
Factors(
Name( "^col1^" ) << multivariate( tpMean[1], tpSD[1]),
Name( "^col2^" ) << multivariate( tpMean[2], tpSD[2]),
Name( "^col3^" ) << multivariate( tpMean[3], tpSD[3]),
Name( "^col4^" ) << multivariate( tpMean[4], tpSD[4]),
),
X Correlations(
1,
^tpListY^,
^corr.mat^
),
N Runs(10000)) ]\");
eval(parse(new.design));
Grazie ancora,
EA
Ri: Come specificare una matrice di correlazione in Profiler per la simulazione?Ciao @eangello ,
Ottima soluzione, e avrei voluto ricordarmi di farlo in quel modo. Ho dovuto fare qualcosa di simile durante la scrittura di uno script per automatizzare la messa a punto di alcuni modelli. I caratteri EvalInsert () e di escape per le virgolette e ^^ per l'inserimento dei valori sono stati molto utili. Semplicemente non lo uso spesso e mi sono dimenticato di quel particolare modo di fare le cose.
Per curiosità, perché è necessario generare dati simulati come quello con la struttura di correlazione specificata. Sono piuttosto interessato, poiché mi ha dato alcune idee su come incorporarlo in alcune cose su cui sto lavorando.
Grazie!,
DS
Ri: Come specificare una matrice di correlazione in Profiler per la simulazione?Ciao @DiedrichSchmidt ,
Spesso simulo set di dati multivariati per scopi di modellazione (tra cui l'ottimizzazione del modello), in genere sulla base di alcuni parametri storici. Questo script era solo una semplice soluzione per fornire questi dati fittizi. Non ho un caso d'uso specifico in questo momento, ma intendo ridimensionare questo script in n-dimensioni e potenzialmente utilizzarlo come funzionale modulo Posso incorporare in script più estesi che utilizzano tecniche di campioni di grandi dimensioni. Dati i vincoli con l'invio di vettori media / sd e matrice di correlazione alla piattaforma Profiler, probabilmente ricorrerò alla scrittura esplicita delle operazioni lineari per scalare la simulazione in n-dimensioni.
Saluti,
eangello
Ri: Come specificare una matrice di correlazione in Profiler per la simulazione?Ciao @eangello ,
Questo è esattamente quello che mi è passato per la mente quando ho capito cosa volevi fare con la struttura di correlazione. Vorrei prendere in prestito la tua idea e modificarla per alcuni dei problemi specifici che sto affrontando. Ho postato in un altro thread sulla generalizzazione a N input. Penso di essere abbastanza vicino, ma non del tutto lì. Ho difficoltà a ridimensionarlo quando chiamo le correlazioni X () e l'impostazione dei valori di media e dev std per i fattori.
In allegato c'è una tabella di dati di mock-up e uno script su cui sto lavorando, tutti basati sul tuo script originale. Forse riesci a trovare gli errori che sto facendo? Mi piacerebbe vederlo funzionare per un numero arbitrario di colonne, sarebbe molto utile per i dati storici, come fai notare.
Grazie!,
DS
Ri: Come specificare una matrice di correlazione in Profiler per la simulazione?Ciao @eangello ,
Penso di essere stato in grado di elaborare uno script scalabile a N colonne. io do @SM una quantità ENORME di credito per l'aiuto nella generalizzazione della parte di correlazione del Profiler. Quel filo è Qui .
Ci sono due script, una versione standalone come quella che hai implementato, ma senza le variabili extra che avevi nel tuo post originale, così come uno script che può essere eseguito da una tabella di dati stessa. Lo standalone è sotto e quello da eseguire dalla tabella dei dati è nella tabella dei dati Gendt.jmp. Funziona sia con la tua tabella dati con 4 colonne che con l'altra tabella dati che ho creato con 11 colonne. Ho provato anche a generalizzare lo script autonomo per le tabelle di dati con altri tipi di colonne.
Names Default To Here( 1 );
// Expression to clear all current settings
clearRoles = Expr( ColListY << RemoveAll );
// Expression to store the current settings in global variables
recallRoles = Expr(
::ycolRecall = ColListY << GetItems
);
//get data table
Try( Close( Data Table( dt ) ) );
If( Is Empty( dt ),
Try( dt = Open(), Throw( "No data found" ) )
);
//Find the number of columns in the data table
ncol = N Col( dt );
ColList = dt << Get Column Names( Numeric, Continuous );
//Dialog Window.
Dlg = New Window( "New Window",
<<RETURN result=""></RETURN>
Inoltre, penso che l'errore della casella dei pulsanti che ricevi abbia a che fare con la << chiamata modale per la finestra di dialogo. L'ho sostituito con << Restituisci risultato e non ricevo più l'errore. Ho anche incluso un pulsante Recall, ma non devi averlo.
Spero che questo aiuti, è stato davvero fantastico e ho imparato molto da questo. So che sarò sicuramente in grado di usarlo per il mio lavoro che svolgo!
Grazie!,
DS
Ri: Come specificare una matrice di correlazione in Profiler per la simulazione?Ciao @DiedrichSchmidt ,
Non avrei mai pensato a quell'approccio, ben fatto. Per quanto riguarda la finestra di dialogo penso che tu abbia ragione, devo dare un'occhiata più da vicino. Si è rivelato meno fastidioso evitare la piattaforma Profiler tutta insieme, anche se è stata una bella idea che non ha funzionato per me. Ecco lo stesso risultato ma con meno confusione (simile ai passaggi che eseguo per implementare in R) e solo il vettore medio e la matrice di covarianza necessari come input.
//tpListY is variables.<BR /><BR />cov = multivariate(
Y(eval list(tpListY)),
estimation method("Row-wise"),
matrix format("Lower Triangular"),
scatterplot matrix(1)
);
cov << covariance matrix(1);
cov.run = cov << run;
cov.rep = cov.run << report;
cov.mat = cov.rep["Covariance Matrix"][matrix box(1)] << get(1);
random reset(1234);
//generate X = (X1, . . . , Xn) where X ∼ MNn(µ, Σ) using the Cholesky decomposition of Σ
//to find (nxn) matrix, C, such that C*C` = Σ.
//let Z = (Z1, . . . , Zn)` where the Zi’s are IID N(µ, 1) for i = 1, . . . , n.
//mean.M is mean vector.
sim.n = 1e4;
dummy.mat = j(1,sim.n,1);
mean.mat = mean.M*dummy.mat;
n.means = n row(mean.M);
sim.C = cholesky(cov.mat);
sim.Z = j(n.means, sim.n, random normal());
sim.X = sim.C*sim.Z;
sim.X2 = sim.X + mean.mat;
sim.Xt = transpose(sim.X2);
as table(sim.Xt, << column names(tpListY));
Preferisco usare meno codice per ottenere lo stesso lavoro, quindi questo è stato più interessante piuttosto che il percorso di Profiler. Si spera che questo renda più facile l'implementazione altrove.
Grazie ancora,
eangello