如何在Profiler中为仿真指定相关矩阵?你好,
我正在编写一个脚本,以从一组样本数据中创建具有指定行数,均值/标准差向量和相关结构的多元正态数据。 我想利用Profiler平台中的Simulator通过以下步骤生成数据表:
- 计算每个变量的样本均值和标准差。
- 从样本数据生成相关矩阵。
- 使用(1)和(2)中的汇总统计量模拟多元数据。
当前,我的脚本为每个变量生成了具有适当均值和标准偏差的模拟数据表,但是我无法正确维护变量之间的相关结构。 我认为我的问题的原因是我如何指定[ NxN相关] X相关使用变量而不是显式指定相关矩阵(例如[1 0.3 0、0.3 1 0、0 0 1]),但是我的故障排除技能使我无解。 下面提供了当前脚本以及预期输出与实际输出,欢迎提供有关如何实现这些步骤的任何建议:
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"});预期与实际产量:
预期的
数据表脚本编写回复:如何在Profiler中为仿真指定相关矩阵?你好@eangello ,
这是一个有趣的问题,如果可以的话,我想尝试并提供帮助,但我无法重现您的问题。 当我尝试运行您的脚本时,它要求我从示例数据目录中打开数据表。 这里的一个问题是我不知道您正在使用哪个数据表,也不会遇到相同的问题。 您可以提供正在使用的数据表吗?
如果确实从示例数据中选择了一个数据表(例如2D高斯过程example.jmp文件),则下一个对话框窗口要求将列转换为角色,但是当我单击“确定”时,我得到一个错误,即未解决name多余的名称或对'Button',Button(-1)/ * ### * /的评估。 然后,您的代码中的第124行出现了另一个错误,该错误与sim.design << Simulator()send命令不一样。
显然,您有一个可以工作的数据表。 可以分享吗? 还是提供有关使用哪个表生成帖子中显示的输出的更多详细信息?
谢谢!,
DS
回复:如何在Profiler中为仿真指定相关矩阵?你好@DiedrichSchmidt ,
发布之前我没有进行尽职调查-这是示例数据中的10行示例(4个X; TP1-TP4)。 当前脚本限制为4个变量,但我希望能够将其扩展为ñ未来的变数。 此示例数据表将重现我的问题。 我相信未解决的名称错误是来自对话框(也许是取消/删除按钮),但是我没有找到根本原因。
谢谢,
EA
回复:如何在Profiler中为仿真指定相关矩阵?你好@eangello ,
谢谢你的数据表。 正如您提到的,我可以重提您的问题。 我注意到的一件事是,当您运行模拟器时,它不会在探查器旁边创建直方图,这与X Correlations的帮助索引中的疲惫示例不同。
我认为发生了两件事:
1.调用tpListY
2.调用corr.mat
我不确定为什么,但是我认为您需要在代码中明确“拼写”出X关联的列表,其中包括相关矩阵。因此,除了调用tpListY之外,您还需要将其替换为{TP1,TP2 ,TP3,TP4}。 同样,您需要在方括号[]之间放置实际的4x4(或NxN)相关矩阵。
我以为执行Parse(tpListY [1])之类的方法是可以的,但是即使包裹了Eval(),我也无法使其正常工作。 如果我将JSL代码放入{TP1,TP2,TP3,TP4}中,我只能使其自动工作。 请注意,当您放入NxN相关矩阵时,它实际上是使用矩阵的左下三角形填充表格。
我还认为调用corr.mat的元素可能会起作用,就像在corr.mat [1]等中一样,但这也不起作用。 如果尝试这样做,则会收到无效的矩阵令牌错误,并且不确定原因,因为corr.mat的元素是数字。
下面的代码(我修改了功能以对其进行一些修改)可以提供预期的输出,但是这并不能满足您从4x4系统扩展到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"});必须有一种方法可以执行此操作,因为您可以调用tpMean和tpSD的元素来填充因子的多元噪声。 我认为可能需要对JSL有更多经验的人对此发表评论。
最后,我认为您对其中一个按钮框是正确的,但我也无法确切指出它-更加专注于尝试解决tpListY和corr.mat问题!;)
我对您所发现的内容非常感兴趣。
祝你好运,
DS
回复:如何在Profiler中为仿真指定相关矩阵?你好@DiedrichSchmidt ,
谢谢您对故障排除的帮助,不胜感激。 我玩过类似的功能,例如Eval,Eval Expr(Expr(x) ) ,和缬草胺并通过在发送到Profiler之前强制对列和矩阵变量进行求值来找到解决方案( X相关似乎接受)。 我采用了与上述相同的解决方案,以使Profiler可以灵活地适应不同的列名。 现在,我的相关结构保留在模拟数据中。
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));
再次感谢,
EA
回复:如何在Profiler中为仿真指定相关矩阵?你好@eangello ,
很好的解决方案,我希望我会记得那样做。 在编写脚本以自动进行某些模型调整时,我必须做类似的事情。 EvalInsert()和转义字符(用于引号)和^^(用于插入值)非常有用。 我只是不经常使用它,而忘记了这种特定的做事方式。
出于好奇,为什么您需要生成具有指定相关结构的模拟数据。 我很感兴趣,因为它为我提供了一些有关如何将其整合到我正在研究的东西中的想法。
谢谢!,
DS
回复:如何在Profiler中为仿真指定相关矩阵?你好@DiedrichSchmidt ,
我经常出于建模目的(通常是在其中进行模型调整)来模拟多变量数据集,通常基于一些历史参数。 该脚本只是提供此模拟数据的简单解决方案。 我目前没有特定的用例,但我打算将此脚本缩放为n维,并有可能将其用作功能模块我可以将其合并到使用大样本技术的更广泛的脚本中。 给定将均值/ sd向量和相关矩阵发送到Profiler平台的约束,我可能会求助于显式编写线性运算,以便将模拟缩放到n维。
问候,
恩格洛
回复:如何在Profiler中为仿真指定相关矩阵?你好@eangello ,
当我意识到您想要对相关结构进行操作时,这正是我的想法。 我想借用您的想法并将其修改为我面临的一些特定问题。 我在另一个线程中发布了关于归纳为N个输入的信息。 我认为我已经很近了,但还不是很远。 在调用X Correlations()并设置因子的均值和标准差值时,我很难按比例放大它。
随附的是我正在使用的模型数据表和脚本,全部基于您的原始脚本。 也许您可以找到我正在犯的错误? 正如您所指出的那样,我很乐意看到此方法适用于任意数量的列,这对历史数据非常有帮助。
谢谢!,
DS
回复:如何在Profiler中为仿真指定相关矩阵?你好@eangello ,
我认为我已经能够设计出可扩展到N列的脚本。 我给@小姐大量的信用额度,用于帮助概括Profiler的相关部分。 该线程是这里。
有两个脚本,一个是独立版本,类似于您实现的脚本,但没有原始帖子中包含的额外变量,还有一个可以从数据表本身运行的脚本。 独立服务器在下面,而要从数据表运行的服务器在Gendt.jmp数据表中。 它既适用于具有4列的数据表,也适用于我具有11列的其他数据表。 我还尝试对带有其他列类型的数据表的独立脚本进行泛化。
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>
另外,我认为您收到的“按钮框”错误与对话窗口的<< Modal调用有关。 我将其替换为<<返回结果,并且不再收到错误。 我还包括了“调用”按钮,但您不必一定要使用它。
我希望这会有所帮助,这真的很棒,并且我从中学到了很多。 我知道我一定可以在工作中使用它!
谢谢!,
DS
回复:如何在Profiler中为仿真指定相关矩阵?你好@DiedrichSchmidt ,
我从来没有想到过这种方法,做得很好。 至于对话窗口,我认为您是对的,我必须仔细看一下。 事实证明,避免同时使用Profiler平台并不是件容易的事,尽管这是一个不错的主意,但对我而言并不成功。 这是相同的结果,但大惊小怪(类似于我在R中执行的步骤),并且仅作为输入所需的均值向量和协方差矩阵。
//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));
我更喜欢使用更少的代码来完成相同的工作,因此它比Profiler路由更具吸引力。 希望这使得在其他地方实现起来更容易。
再次感谢,
恩格洛