如何在Profiler中指定相關矩陣進行仿真?你好,
我正在編寫一個腳本,用於根據一組樣本數據創建具有指定行數、均值/標準差向量和相關結構的多元正態數據。 我想利用Profiler平台中的模擬器通過以下步驟生成數據表:
- 計算每個變量的樣本均值和標準差。
- 從樣本數據生成相關矩陣。
- 使用 (1) 和 (2) 中的匯總統計來模擬多變量數據。
目前,我的腳本為每個變量生成具有適當平均值和標準差的模擬數據表,但我無法正確維護變量之間的相關結構。 我相信我的問題的原因是我如何指定 [ N×N相關性] 與X 相關性使用變量而不是顯式指定相關矩陣(例如 [1 0.3 0, 0.3 1 0, 0 0 1]),但我的故障排除技巧讓我沒有解決方案。 下面提供了當前腳本以及預期與實際輸出,歡迎就如何實現這些步驟提出任何建議:
傑士林:
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"});預期輸出與實際輸出:
expectedvsactualexpectedvsactual預期與實際
自動化和腳本編寫數據探索和可視化回复:如何在 Profiler 中指定相關矩陣進行仿真?你好@eangello ,
很不錯! 我當然喜歡更短、更優雅的代碼(儘管我不太擅長)。 出於好奇,您是否檢查過使用均值和標準差以及相關矩陣的結果是否與僅使用均值和協方差矩陣提供了(大約)相同的模擬數據?
抱歉,這種其他方法沒有成功,但很高興您找到了一個很好的解決方案,可以移植到您正在使用的其他數據。 我正在對模擬數據進行一些建模測試,看看它與基於實際數據構建的模型有何不同。 我可以看到,當真實數據集相對較小並且模擬數據可以讓您有機會至少構建一個不那麼糟糕的模型時,這會非常有幫助,該模型可以儘早部署,然後隨著更多數據的進入而更新。 也就是說,不必等待數月才能生成足夠大的數據集。 有時,建立一個適當的模型是有價值的,即使它並不“完美”。
感謝大家的討論和學習要點!
祝你好運!,
DS
回复:如何在 Profiler 中指定相關矩陣進行仿真?你好@SDF1 ,
我從來沒有想到過這種方法,做得很好。 至於對話框窗口,我認為你是對的,我必須仔細看看。 事實證明,完全避開 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 路線更有吸引力。 希望這能讓它在其他地方更容易實施。
再次感謝,
埃安傑洛
回复:如何在 Profiler 中指定相關矩陣進行仿真?你好@eangello ,
我想我已經能夠編寫一個可擴展到 N 列的腳本。 我給@多發性硬化症在概括分析器的相關部分方面提供了大量的幫助。 該線程是這裡。
有兩個腳本,一個是與您實現的腳本類似的獨立版本,但沒有原始帖子中的額外變量,另一個是可以從數據表本身運行的腳本。 獨立版本如下,從數據表運行的版本位於 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>
另外,我認為您收到的按鈕框錯誤與對話窗口的 <
我希望這會有所幫助,這真的很酷,我從中學到了很多東西。 我知道我一定能夠在我所做的工作中使用它!
謝謝!,
DS
回复:如何在 Profiler 中指定相關矩陣進行仿真?你好@eangello ,
當我意識到你想要對相關結構做什麼時,這正是我的想法。 我想藉用你的想法並根據我面臨的一些具體問題進行修改。 我在另一個線程中發布了關於泛化到 N 個輸入的內容。 我想我已經很接近了,但還沒有完全實現。 在調用 X Correlations() 並設置因子的平均值和標準差值時,我很難擴展它。
附件是我正在工作的模型數據表和腳本,全部基於您的原始腳本。 也許你能發現我犯的錯誤? 我很高興看到它適用於任意數量的列,正如您所指出的,這對歷史數據非常有幫助。
謝謝!,
DS
回复:如何在 Profiler 中指定相關矩陣進行仿真?你好@SDF1 ,
我經常出於建模目的(其中的模型調整)模擬多變量數據集,通常基於一些歷史參數。 該腳本只是一個提供模擬數據的簡單解決方案。 我現在沒有具體的用例,但我打算將此腳本擴展到 n 維,並可能將其用作函數模塊我可以將其納入使用大樣本技術的更廣泛的腳本中。 考慮到向 Profiler 平台發送均值/標準差向量和相關矩陣的限制,我可能會顯式編寫線性運算,以便將模擬擴展到 n 維。
問候,
埃安傑洛
回复:如何在 Profiler 中指定相關矩陣進行仿真?你好@eangello ,
很好的解決方案,我希望我記得這樣做。 在編寫腳本來自動化某些模型調整時,我必須做類似的事情。 用於插入值的 EvalInsert() 和引號的轉義字符以及 ^^ 非常有用。 我只是不經常使用它並且忘記了那種特殊的做事方式。
出於好奇,為什麼需要生成具有指定關聯結構的模擬數據。 我很感興趣,因為它給了我一些關於如何將其融入到我正在做的事情中的想法。
謝謝!,
DS
回复:如何在 Profiler 中指定相關矩陣進行仿真?你好@SDF1 ,
感謝您幫助解決問題,非常感謝。 我玩過類似的功能,比如求值,求值 Expr( Expr(x) ) ,和評估插入並找到了一個解決方案,通過在發送到 Profiler 之前強制對列和矩陣變量進行評估(其中X 相關性看來可以接受)。 我應用了上面相同的解決方案,使我的探查器能夠靈活地適應不同的列名稱。 現在我的相關結構保留在模擬數據中。
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 ,
感謝您提供數據表。 我可以按照您提到的方式重現您的問題。 我注意到的一件事是,當您運行模擬器時,它不會在分析器旁邊創建直方圖,這與 X Correlations 幫助索引中的輪胎花紋示例不同。
我認為有兩件事正在發生:
1. 調用tpListY
2.調用corr.mat
我不確定為什麼,但我認為您需要在代碼中顯式“拼寫”出 X 相關性列表,其中包括相關矩陣。因此,您需要將其替換為 {TP1, TP2,而不是調用 tpListY ,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 中指定相關矩陣進行仿真?你好@SDF1 ,
我在發布之前沒有盡職調查 - 這是示例數據中的 10 行示例(4 X;TP1-TP4)。 當前腳本僅限於 4 個變量,但我希望能夠將其擴展到氮未來的變數。 這個示例數據表將重現我的問題。 我相信未解決的名稱錯誤來自對話框(可能是取消/刪除按鈕),但我還沒有找到根本原因。
謝謝,
EA
回复:如何在 Profiler 中指定相關矩陣進行仿真?你好@eangello ,
這是一個有趣的問題,如果可以的話我想嘗試提供幫助,但我無法重現您的問題。 當我嘗試運行您的腳本時,它要求我從示例數據目錄中打開數據表。 這裡的一個問題是,我不知道您正在使用哪個數據表,並且不會遇到同樣的問題。 您能提供您正在使用的數據表嗎?
如果我從示例數據中選擇一個數據表 - 例如 2D 高斯過程 example.jmp 文件,下一個對話窗口會要求將列轉換為角色,但是當我單擊“確定”時,我收到錯誤,表示存在未解決的問題name 超出的名稱或“Button”的評估,Button(-1) /*###*/。 然後,代碼中的第 124 行出現另一個錯誤,它不喜歡 sim.design << Simulator() 發送命令。
顯然,您有一個可以實現此功能的數據表。 你能分享一下嗎? 或者提供有關您使用哪個表來生成您在帖子中顯示的輸出的更多詳細信息?
謝謝!,
DS