Comment spécifier une matrice de corrélation dans Profiler pour la simulation?Bonjour,
J'écris un script pour créer des données normales multivariées avec un nombre spécifié de lignes, des vecteurs d'écart moyen / standard et une structure de corrélation à partir d'un ensemble d'exemples de données. Je souhaite profiter du simulateur de la plate-forme Profiler pour générer la table de données en suivant les étapes suivantes:
- Calculez la moyenne de l'échantillon et l'écart type pour chaque variable.
- Générez une matrice de corrélation à partir d'échantillons de données.
- Simulez des données multivariées à l'aide des statistiques récapitulatives de (1) et (2).
Actuellement, mon script génère la table de données simulée avec les moyennes et les écarts types appropriés pour chaque variable, mais je n'arrive pas à maintenir correctement la structure de corrélation entre les variables. Je pense que la cause de mon problème est la manière dont je spécifie le [ NxN corrélations] avec Corrélations X en utilisant une variable au lieu de spécifier explicitement la matrice de corrélation (par exemple [1 0,3 0, 0,3 1 0, 0 0 1]), mais mes compétences en dépannage ne m'ont laissé aucune solution. Script actuel et sortie attendue par rapport à la sortie réelle fournie ci-dessous, toutes les suggestions sur la façon de réaliser ces étapes sont les bienvenues:
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"});Sortie attendue ou réelle:
attenduvsactuel
Tableau de donnéesScriptingRe: Comment spécifier une matrice de corrélation dans Profiler pour la simulation?salut @eangello ,
C'est une question intéressante, et j'aimerais essayer de vous aider si je le peux, mais je ne suis pas en mesure de reproduire votre problème. Lorsque j'essaie d'exécuter votre script, il me demande d'ouvrir une table de données à partir du répertoire de données d'exemple. Un problème ici est que je ne sais pas avec quelle table de données vous travaillez et que je n'aurai pas le même problème. Pouvez-vous fournir le tableau de données avec lequel vous travaillez?
Si je sélectionne une table de données à partir des données d'exemple - par exemple le fichier 2D Gaussian process example.jmp, la fenêtre de dialogue suivante demande de convertir les colonnes en rôles, mais lorsque je clique sur OK, j'obtiens l'erreur qu'il y a un non résolu name Nom en excès ou évaluation de 'Button', Button (-1) / * ### * /. Ensuite, une autre erreur survient à partir de la ligne 124 de votre code où elle n'aime pas la commande d'envoi sim.design << Simulator ().
Apparemment, vous avez une table de données où cela fonctionne. Pouvez-vous le partager? Ou donner plus de détails sur la table que vous utilisez pour générer la sortie que vous avez affichée dans votre message?
Merci!,
DS
Re: Comment spécifier une matrice de corrélation dans Profiler pour la simulation?salut @DiedrichSchmidt ,
Je n'ai pas dû faire preuve de diligence raisonnable avant de publier - voici un échantillon de 10 lignes à partir des exemples de données (4 X; TP1-TP4). Le script actuel est limité à 4 variables, mais j'espère pouvoir le mettre à l'échelle à N variables à l’avenir. Cet exemple de tableau de données recréera mon problème. Je crois que l'erreur de nom non résolue provient de la boîte de dialogue (peut-être des boutons d'annulation / de suppression), mais je n'ai pas trouvé la cause principale.
Merci,
EA
Re: Comment spécifier une matrice de corrélation dans Profiler pour la simulation?salut @eangello ,
Merci pour le tableau de données. Je peux recréer votre problème comme vous le mentionnez. Une chose que je remarque est que lorsque vous exécutez le simulateur, il ne crée pas l'histogramme à côté du profileur, contrairement à l'exemple tiretread dans l'index de l'aide sur X Correlations.
Je pense qu'il se passe deux choses:
1. appeler tpListY
2. appeler corr.mat
Je ne sais pas pourquoi, mais je pense que vous devez explicitement «épeler» la liste des X Correltions dans votre code et cela inclut la matrice de corrélation., Donc au lieu d'appeler tpListY, vous devez la remplacer par {TP1, TP2 , TP3, TP4}. De même, vous devez mettre la matrice de corrélation 4x4 (ou NxN) réelle entre les crochets [].
Je pensais que faire quelque chose comme Parse (tpListY [1]) fonctionnerait, mais je ne peux pas le faire fonctionner, même avec un Eval () enroulé autour. Je ne peux le faire fonctionner automatiquement que si je mets le code JSL comme {TP1, TP2, TP3, TP4}. Notez que lorsque vous insérez la matrice de corrélation NxN, elle utilise en fait le triangle inférieur gauche de la matrice pour remplir le tableau.
J'ai aussi pensé qu'appeler les éléments du corr.mat pourrait fonctionner, comme dans corr.mat [1], etc., mais cela ne fonctionne pas non plus. Si j'essaye cela, j'obtiens une erreur de jeton de matrice invalide, et je ne sais pas vraiment pourquoi, car les éléments de corr.mat sont des nombres.
Le code ci-dessous (j'ai modifié votre fonction pour la changer un peu) fonctionne pour fournir la sortie attendue, mais cela n'aide pas votre désir de passer d'un système 4x4 à un système 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"});Il doit y avoir un moyen de le faire, puisque vous pouvez appeler les éléments de tpMean et tpSD pour remplir le bruit multivarié des facteurs. Je pense que quelqu'un avec plus d'expérience en JSL pourrait être nécessaire pour commenter cela.
Enfin, je pense que vous avez raison à propos de l'une des boîtes à boutons, mais je ne pouvais pas non plus l'identifier exactement - j'étais plus concentré sur la résolution des problèmes de tpListY et corr.mat!;)
Je suis vraiment intéressé par ce que vous découvrez.
Bonne chance,
DS
Re: Comment spécifier une matrice de corrélation dans Profiler pour la simulation?salut @DiedrichSchmidt ,
Merci pour l'aide au dépannage, très appréciée. J'ai joué avec des fonctions similaires comme Eval, Eval Expr (Expr (x) ) , et Evalinsert et a trouvé une solution en forçant la ou les variables de colonne et de matrice à évaluer avant de les envoyer à Profiler (qui Corrélations X semble accepter). J'ai appliqué la même solution ci-dessus pour rendre mon Profiler flexible à différents noms de colonnes. Maintenant, ma structure de corrélation est maintenue dans les données simulées.
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));
Merci encore,
EA
Re: Comment spécifier une matrice de corrélation dans Profiler pour la simulation?salut @eangello ,
Excellente solution, et j'aurais aimé me souvenir de le faire de cette façon. J'ai dû faire quelque chose de similaire lors de l'écriture d'un script pour automatiser certains réglages de modèles. EvalInsert () et les caractères d'échappement pour les guillemets et ^^ pour l'insertion de valeurs ont été très utiles. Je ne l'utilise pas souvent et j'ai oublié cette façon particulière de faire les choses.
Par curiosité, pourquoi avez-vous besoin de générer des données simulées comme celles-ci avec la structure de corrélation spécifiée. Je suis très intéressé, car cela m'a donné quelques idées sur la façon d'intégrer cela dans certaines choses sur lesquelles je travaille.
Merci!,
DS
Re: Comment spécifier une matrice de corrélation dans Profiler pour la simulation?salut @DiedrichSchmidt ,
Je simule fréquemment des ensembles de données multivariées à des fins de modélisation (réglage du modèle entre eux), généralement en fonction de certains paramètres historiques. Ce script était juste une solution simple pour servir ces données simulées. Je n'ai pas de cas d'utilisation spécifique pour le moment, mais j'ai l'intention de mettre à l'échelle ce script à n dimensions et de l'utiliser potentiellement comme un module Je peux intégrer dans des scripts plus étendus qui utilisent des techniques à grand échantillon. Compte tenu des contraintes liées à l'envoi des vecteurs moyenne / sd et de la matrice de corrélation à la plate-forme Profiler, je recourrai probablement à l'écriture explicite des opérations linéaires afin de mettre à l'échelle la simulation à n dimensions.
Salutations,
eangello
Re: Comment spécifier une matrice de corrélation dans Profiler pour la simulation?salut @eangello ,
C'est exactement ce qui m'est venu à l'esprit lorsque j'ai réalisé ce que vous vouliez faire avec la structure de corrélation. Je voudrais emprunter votre idée et la modifier en fonction de certains des problèmes spécifiques auxquels je suis confronté. J'ai posté dans un autre fil de discussion sur la généralisation à N entrées. Je pense que je suis assez proche, mais pas tout à fait là. J'ai des difficultés à le mettre à l'échelle lors de l'appel des corrélations X () et de la définition des valeurs de développement moyennes et std pour les facteurs.
Vous trouverez ci-joint une table de données et un script de maquette sur lesquels je travaille, tous basés sur votre script d'origine. Peut-être pouvez-vous trouver les erreurs que je fais? J'adorerais voir cela fonctionner pour un nombre arbitraire de colonnes, ce serait très utile pour les données historiques, comme vous le faites remarquer.
Merci!,
DS
Re: Comment spécifier une matrice de corrélation dans Profiler pour la simulation?salut @eangello ,
Je pense que j'ai pu élaborer un script évolutif à N colonnes. je donne @Mme un énorme crédit pour aider à généraliser la partie corrélation du profileur. Ce fil est ici .
Il existe deux scripts, une version autonome comme celle que vous avez implémentée, mais sans les variables supplémentaires que vous aviez dans votre article d'origine, ainsi qu'un script qui peut s'exécuter à partir d'une table de données elle-même. La version autonome est ci-dessous et celle à exécuter à partir de la table de données se trouve dans la table de données Gendt.jmp. Cela fonctionne à la fois avec votre table de données à 4 colonnes et l'autre table de données que j'ai créée avec 11 colonnes. J'ai essayé de généraliser également le script autonome pour les tables de données avec d'autres types de colonnes.
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>
De plus, je pense que l'erreur Button Box que vous recevez est liée à l'appel << Modal pour la fenêtre de dialogue. J'ai remplacé cela par << Return Result, et je n'obtiens plus l'erreur. J'ai également inclus un bouton de rappel, mais vous n'êtes pas obligé de l'avoir.
J'espère que cela aide, c'était vraiment cool et j'en ai beaucoup appris. Je sais que je pourrai certainement l'utiliser pour mon travail!
Merci!,
DS
Re: Comment spécifier une matrice de corrélation dans Profiler pour la simulation?salut @DiedrichSchmidt ,
Je n'aurais jamais pensé à cette approche, bien faite. En ce qui concerne la fenêtre de dialogue, je pense que vous avez raison, il faut bien y regarder de plus près. Cela s'est avéré moins difficile d'éviter la plate-forme Profiler dans son ensemble, alors que c'était une bonne idée, cela n'a pas fonctionné pour moi. Voici le même résultat mais avec moins de tracas (similaire aux étapes que je prends pour implémenter dans R) et ne signifie que la matrice vectorielle et de covariance nécessaires comme entrées.
//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));
Je préfère utiliser moins de code pour faire le même travail, donc c'était plus attrayant que la route Profiler. Espérons que cela facilite la mise en œuvre ailleurs.
Merci encore,
eangello