JMP > JSL > フィット モデル (N > 2000) の複数呼び出しのスクリプト アクセラレーション?JMP コミュニティの皆様、こんにちは。
データセットのサイズが大きくなり、しばらく前に作成した基本的なスクリプト (以下を参照) が速度の観点から追いついていません。
このタイプのスクリプトを最適化して速度を向上させる方法についてのアイデアを聞いていただければ幸いです。 たとえば、「連結」のような操作は比較的遅いと思いますが、このタイプの操作では行列を操作するのが理にかなっているかもしれません。
Names Default to Here (1);
dt = Current Data Table ();
CList = dt << Get Column Names (string);
dtoutl = New Table ("LSM OUTPUT", "invisible");
dtoutp = New Table ("PVal OUTPUT", "invisible");
For (i = 1, i<= 2000, i++,
fm = dt << Fit Model(
Y( Column (i) ),
Effects( :VISIT, :TREATMENT, :VISIT * :TREATMENT, Column (i+2000) ),
Personality( "Standard Least Squares" ),
Emphasis( "Minimal Report" ),
Run(
Column (i) << {Summary of Fit( 1 ), Analysis of Variance( 1 ),
Parameter Estimates( 1 ), Scaled Estimates( 0 ),
Plot Actual by Predicted( 0 ), Plot Regression( 0 ),
Plot Residual by Predicted( 0 ), Plot Studentized Residuals( 0 ),
Plot Effect Leverage( 0 ), Plot Residual by Normal Quantiles( 0 ),
Box Cox Y Transformation( 0 ), {:VISIT * :TRT01A <<
{LSMeans Contrast( [0 0 1 -1 0 0, 0 0 0 0 1 -1] )}}}
)
);
fmr = report (fm);
table_list = fmr << xpath ("//OutlineBox [text() = 'VISIT*TREATMENT']//TableBox");
temp_lsm = table_list [1];
temp_pval = table_list [2];
temp_tbl_lsm = temp_lsm << Make into Data Table (invisible (1));
temp_tbl_pval = temp_pval << Make into Data Table (invisible (1));
temp_tbl_lsm << New column ("ID", character, nominal, << set each value (CList [i]));
temp_tbl_pval << New column ("ID", character, nominal, << set each value (CList [i]));
fmr << close window;
dtoutl << Concatenate (Data table (temp_tbl_lsm), "Append to First Table");
Wait (0);
dtoutp << Concatenate (Data table (temp_tbl_pval), "Append to First Table");
Close (temp_tbl_lsm, NoSave);
Close (temp_tbl_pval, NoSave);
);
dtoutl << Bring Window to Front;
dtoutp << Bring Window to Front;
すべてのフィードバックを歓迎します。
一番、
TS
スクリプティングRe: JMP > JSL > 適合モデル (N > 2000) の複数呼び出しのスクリプト アクセラレーション?こんにちは。
モデルの適合を非表示にすると、さらに 8 秒短縮され (61 秒から 53 秒に)、「For Each Row」を直接割り当てに置き換えると、さらに 5 秒短縮されます (53 秒から 48 秒に短縮されます)。
素晴らしい!
一番、
TS
Re: JMP > JSL > 適合モデル (N > 2000) の複数呼び出しのスクリプト アクセラレーション?これらにより、さらに速度が向上する可能性があります (ほとんどの場合、かなり小さい可能性があります)。
ほとんどの場合、モデルに合わせて非表示を追加できます
fm = dt << Fit Model(
Y( Column (i) ),
Effects( :VISIT, :TRT01A, :VISIT * :TRT01A, Column (i-1933) ),
Personality( "Standard Least Squares" ),
Emphasis( "Minimal Report" ),
Run(
Column (i) << {Summary of Fit( 1 ), Analysis of Variance( 1 ),
Parameter Estimates( 1 ), Scaled Estimates( 0 ),
Plot Actual by Predicted( 0 ), Plot Regression( 0 ),
Plot Residual by Predicted( 0 ), Plot Studentized Residuals( 0 ),
Plot Effect Leverage( 0 ), Plot Residual by Normal Quantiles( 0 ),
Box Cox Y Transformation( 0 ), {:VISIT * :TRT01A <<
{LSMeans Contrast( [0 0 1 -1 0 0, 0 0 0 0 1 -1] )}}}
),
invisible
);
また、数式を使用して列を作成し、すぐに削除する場合は、[数式] と [数式の削除] の代わりに << Set Each value を使用できます。
dtoutl << New Column("METAB_ID", Character, Nominal, << Set Each Value(Substitute(:MET_ID, "LOG10 FC ", "")));
For Each Row を << Set Each Value に置き換えることもできます (これについてはわかりません。また、速度が向上するかどうかもわかりません)。
Column(dtoutp, "LABEL") << Set Each Value(annot_pv[Sequence( 1, N Items (annot_pv), 1, 1 )]);
必要になるまで、データテーブルを非公開 (少なくとも非表示) に保つこともできます。 << New Data View でプライベート テーブルを表示できます(今日まで知りませんでした)。
データテーブル/レポート/ウィンドウが不要になったらすぐに閉じます。
Re: JMP > JSL > 適合モデル (N > 2000) の複数呼び出しのスクリプト アクセラレーション?JMP コミュニティの皆様、こんにちは。
最も改善されたスクリプトの注釈付きバージョンを以下で見つけて、多数のモデル適合分析の出力を実行およびキャプチャします。
実行時間を改善するための最も重要な 2 つの手順は次のとおりです。
- 分析出力を集計するためのデータ テーブルの代わりにマトリックスを使用
- メイン ループの前に作成されたマスター マトリックスへの分析出力データの挿入ではなく置換。
Names Default to Here (1);
st = Today();
dt = Current Data Table ();
lc_path = dt << GetPath;
// START: CAPTURING OUTPUT ANNOTATION TO REBUILD ANNOTATION //
dts = dt << Summary( Group( :VISIT, :TRT01A ), Freq( "None" ), Weight( "None" ), invisible );
annot_lsm = {};
met_l = {};
annot_pv = {};
CList = dt << Get Column Names (string);
For (j = 1, j <= N Rows (dts), j++,
insert into (annot_lsm, dts:VISIT [j] || ", " || dts:TRT01A [j]);
);
annot_pv = annot_lsm;
annot_pv = Concat To(annot_pv, {"Estimate","Std Error", "t Ratio", "Prob>|t|", "SS", "Lower 95%", "Upper 95%"});
Close (dts, NoSave);
// END: CAPTURING OUTPUT ANNOTATION TO REBUILD ANNOTATION //
// START: CREATING EMPTY NASTER MATRICES TO HOLD TTHE OUTPUT OF THE FIT MODEL//
nro_l = 1933*6;
nco_l = 4;
nro_p = 1933 * 13;
nco_p = 2;
mtx_lsm = J(nro_l, nco_l);
mtx_pval = J(nro_p, nco_p);
// END: CREATING EMPTY MASTER MATRICES TO HOLD TTHE OUTPUT OF THE FIT MODEL//
//START MAIN LOOP//
For (i = 3921, i<= 5853, i++, //5853
//START LINEAR MODEL WITH CUSTGOMIZED CONTRASTS //
fm = dt << Fit Model(
Y( Column (i) ),
Effects( :VISIT, :TRT01A, :VISIT * :TRT01A, Column (i-1933) ),
Personality( "Standard Least Squares" ),
Emphasis( "Minimal Report" ),
Run(
Column (i) << {Summary of Fit( 1 ), Analysis of Variance( 1 ),
Parameter Estimates( 1 ), Scaled Estimates( 0 ),
Plot Actual by Predicted( 0 ), Plot Regression( 0 ),
Plot Residual by Predicted( 0 ), Plot Studentized Residuals( 0 ),
Plot Effect Leverage( 0 ), Plot Residual by Normal Quantiles( 0 ),
Box Cox Y Transformation( 0 ), {:VISIT * :TRT01A <<
{LSMeans Contrast( [0 0 1 -1 0 0, 0 0 0 0 1 -1] )}}}
)
);
//END LINEAR MODEL WITH CUSTGOMIZED CONTRASTS //
//START CAPTURE ANALYSIS OUTPUTS FOR EACH RUN//
fmr = report (fm);
insert into (met_l, CList [i]); //COLLATING THE NAME OF THE COLUMN FOR EACH RUN//
table_list = fmr << xpath ("//OutlineBox [text() = 'VISIT*TRT01A']//TableBox");
temp_lsm = table_list [1]; //POINTER TO LSMEAN + STDERR TABLE//
temp_pval = table_list [2]; // POINTER TO CONTRAST TABLE //
temp_mtx_lsm = temp_lsm << Get as Matrix; // EXTRACT LSMEAN + STDERR OUTPUT AS A MATRIX //
temp_mtx_pval = temp_pval << Get as Matrix; // EXTRACT CONTRAST OUTPUT AS A MATRIX //
locr1_l = ((i-3921)*6) + 1; //GENERATE THE TOP ROW BLOCK FOR INSERTION OF LSMEAN + STDERR IN TO THE MASTER MATRIX //
locr2_l = ((i-3921)*6) + 6; //GENERATE THE BOTTOM ROW BLOCK FOR INSERTION OF LSMEAN + STDERR IN TO THE MASTER MATRIX //
mtx_lsm [locr1_l::locr2_l, 0] = temp_mtx_lsm [0,0]; //REPLACE PLACEHOLDER VALUES IN MASTER MATRIX WITH LOCAL LSMEAN + STDERR OUTPUT DATA FROM EACH RUN //
locr1_p = ((i-3921)*13) + 1; //GENERATE THE TOP ROW BLOCK FOR INSERTION OF CONTRAST IN TO THE MASTER MATRIX //
locr2_p = ((i-3921)*13) + 13; //GENERATE THE BOTTOM ROW BLOCK FOR INSERTION OF CONTRAST IN TO THE MASTER MATRIX //
mtx_pval [locr1_p::locr2_p, 0] = temp_mtx_pval [0,0]; //REPLACE PLACEHOLDER VALUES IN MASTER MATRIX WITH LOCAL CONTRAST OUTPUT DATA FROM EACH RUN //
fmr << close window;
);
// START CONVERT MASTER MATRICES INTO TABLES//
dtoutl = as Table (mtx_lsm);
dtoutp = as Table (mtx_pval);
// END CONVERT MASTER MATRICES INTO TABLES//
//START REBUILD ANNOTATIONS AND REFORMAT FOR LSMEAN + STDERR TABLE//
dtoutl << new column ("COMP", Character, Nominal);
dtoutl << new column ("MET_ID", Character, Nominal);
dtoutl:Col1 << set name ("LSMEAN");
dtoutl:Col2 << set name ("STDERR");
dtoutl:Col3 << set name ("UPPER CI");
dtoutl:Col4 << set name ("LOWER CI");
dtoutl << Begin Data Update;
For Each Row( dtoutl, :COMP = annot_lsm[Sequence( 1, N Items (annot_lsm), 1, 1 )] );
For each row( dtoutl, :MET_ID = met_l[Sequence (1,N Items (met_l), 1, 6)] );
dtoutl << End Data Update;
dtoutl << New Column ("METAB_ID", Character, Nominal, Formula (Substitute (:MET_ID, "LOG10 FC ", ""))) ;
dtoutl << New Column ("VISIT", Character, Nominal, Formula (Word (1,:COMP, ",")));
dtoutl << New Column ("ARM", Character, Ordinal, Formula (Word (-1, :COMP, ",")));
dtoutl:METAB_ID << Delete Formula;
dtoutl:ARM << Delete Formula;
dtoutl:VISIT << Delete Formula;
//END REBUILD ANNOTATIONS AND REFORMAT FOR LSMEAN + STDERR TABLE//
//START REBUILD ANNOTATIONS AND REFORMAT FOR CONTRAST TABLE//
dtoutp << new column ("LABEL", Character, Nominal);
dtoutp << new column ("MET_ID", Character, Nominal);
dtoutp << Begin Data Update;
For Each Row( dtoutp, :LABEL = annot_pv[Sequence( 1, N Items (annot_pv), 1, 1 )] );
For each row( dtoutp, :MET_ID = met_l[Sequence (1,N items (met_l), 1, 13)] );
dtoutp << End Data Update;
CNAME1 = Column (dtoutp, 3) [3];
CNAME2 = Column (dtoutp, 3) [5];
dtoutp << Select Where (:LABEL == "Prob>|t|");
dtoutp_s = dtoutp << subset (Selected Rows, Output Table Name ("P VAL"));
Close (dtoutp, NoSave);
dtoutp_s << New Column ("METAB_ID", Character, Nominal, Formula (Substitute (:MET_ID, "LOG10 FC ", "")));
dtoutp_s:Col1 << Set Name (CNAME1);
dtoutp_s:Col2 << Set Name (CNAME2);
dtoutp_s_s = dtoutp_s << Stack (Columns (as name(CNAME1), as name (CNAME2)), Output Table Name ("STACK P VAL"));
Close (dtoutp_s, NoSave);
dtoutp_s_s << New Column ("VISIT", Character, Nominal, Formula (Word (1,:Label, ",")));
dtoutp_s_s << New Column ("xARM", Character, Ordinal, Formula (Word (-1, :Label, ",")));
dtoutp_s_s:Data << Set name ("NOM P VAL");
dtoutl << Update(
With( dtoutp_s_s ),
Match Columns( :METAB_ID = :METAB_ID, :VISIT = :VISIT ),
Add Columns from Update Table( :NOM P VAL ),
Replace Columns in Main Table( None )
);
Close (dtoutp_s_s, NoSave);
//END REBUILD ANNOTATIONS AND REFORMAT FOR CONTRAST TABLE//
dtoutl << Save (substitute (lc_path, dt << get name||".jmp", "LINMOD_OUT_")||char(today())); //
et = Today ();
show (Date Difference (st, et, "second"));
一番、
TS
Re: JMP > JSL > 適合モデル (N > 2000) の複数呼び出しのスクリプト アクセラレーション?涼しい! コミュニティは、そこにたどり着くまでにあなたが何をしたか、またはさまざまな変更がどれほど重要であったかを要約したいと考えていると思います。
@ドンマコーマック
Re: JMP > JSL > 適合モデル (N > 2000) の複数呼び出しのスクリプト アクセラレーション?やあ@Craige_Hales 、
提案をありがとう。 あなたが推奨した方法のおかげで、速度がさらに 33% 向上しました。
完璧にする必要がある微調整がまだいくつかありますが、合計実行時間は約 450 秒で開始し、最初の変更で 91 秒に短縮され、現在は 61 秒に短縮されています。
一番
TS
Re: JMP > JSL > 適合モデル (N > 2000) の複数呼び出しのスクリプト アクセラレーション?5X いいですね!
役立つプラットフォームの目に見えないオプションもあるかもしれません。
(JSL プロファイラーを試してみてください。次の提案は的外れかもしれません。 時間の 1% 未満を使用するものを高速化しても意味がありません...)
それでも不十分な場合は、ループ内の最後の 2 つのステートメントを次に調べる必要があります。 あなたのJSLは、次第に大きなサイズで配列を2000回再割り当てしていると思います。 配列を (J(nr,nc,initvalue) 関数を使用して) 事前に割り当て、mtx_lsm[a::b,0] = temp_mtx_lsm[0,0] のようなもので配列に格納できる場合は、時間を節約できます。 .
編集:これは、再割り当てするだけでなく、データもコピーするため、N^2 の問題である可能性があります。 1000 の実行から 2000 の実行に移行すると、データ量の 4 倍 (2 倍ではない) がコピーされます。
Re: JMP > JSL > 適合モデル (N > 2000) の複数呼び出しのスクリプト アクセラレーション?JMP コミュニティの皆様、こんにちは。
私は分析出力テーブルの長いコレクションを集約するためのレセプタクルとして行列を試しましたが、これまでのところ、実行時間を最大 5 倍高速化しました (以下を参照)。 唯一の小さな不都合は、(明らかに) マトリックスがテキストを保持しないため、キャプチャーされた出力テーブルの注釈を再構築しなければならなかったことです。
Names Default to Here (1);
st = Today();
dt = Current Data Table ();
dts = dt << Summary( Group( :VISIT, :TRT01A ), Freq( "None" ), Weight( "None" ), invisible );
annot_lsm = {};
met_l = {};
annot_pv = {};
CList = dt << Get Column Names (string);
For (j = 1, j <= N Rows (dts), j++,
insert into (annot_lsm, dts:VISIT [j] || ", " || dts:TRT01A [j]);
);
annot_pv = annot_lsm;
annot_pv = Concat To(annot_pv, {"Estimate","Std Error", "t Ratio", "Prob>|t|", "SS", "Lower 95%", "Upper 95%"});
Close (dts, NoSave);
mtx_lsm = [];
mtx_pval = [];
For (i = 1, i<= 2000, i++, //2000
fm = dt << Fit Model(
Y( Column (i) ),
Effects( :VISIT, :TRT01A, :VISIT * :TRT01A, Column (i+2000) ),
Personality( "Standard Least Squares" ),
Emphasis( "Minimal Report" ),
Run(
Column (i) << {Summary of Fit( 1 ), Analysis of Variance( 1 ),
Parameter Estimates( 1 ), Scaled Estimates( 0 ),
Plot Actual by Predicted( 0 ), Plot Regression( 0 ),
Plot Residual by Predicted( 0 ), Plot Studentized Residuals( 0 ),
Plot Effect Leverage( 0 ), Plot Residual by Normal Quantiles( 0 ),
Box Cox Y Transformation( 0 ), {:VISIT * :TRT01A <<
{LSMeans Contrast( [0 0 1 -1 0 0, 0 0 0 0 1 -1] )}}}
)
);
fmr = report (fm);
insert into (met_l, CList [i]);
table_list = fmr << xpath ("//OutlineBox [text() = 'VISIT*TRT01A']//TableBox");
temp_lsm = table_list [1];
temp_pval = table_list [2];
temp_mtx_lsm = temp_lsm << Get as Matrix;
temp_mtx_pval = temp_pval << Get as Matrix;
fmr << close window;
mtx_lsm = mtx_lsm |/ temp_mtx_lsm;
mtx_pval = mtx_pval |/ temp_mtx_pval ;
);
dtoutl = as Table (mtx_lsm);
dtoutp = as Table (mtx_pval);
dtoutl << new column ("COMP", Character, Nominal);
dtoutl << new column ("MET_ID", Character, Nominal);
dtoutl:Col1 << set name ("LSMEAN");
dtoutl:Col2 << set name ("STDERR");
dtoutl:Col3 << set name ("UPPER CI");
dtoutl:Col4 << set name ("LOWER CI");
dtoutl << Begin Data Update;
For Each Row( dtoutl, :COMP = annot_lsm[Sequence( 1, N Items (annot_lsm), 1, 1 )] );
For each row( dtoutl, :MET_ID = met_l[Sequence (1,N Items (met_l), 1, 6)] );
dtoutl << End Data Update;
dtoutp << new column ("LABEL", Character, Nominal);
dtoutp << new column ("MET_ID", Character, Nominal);
dtoutp << Begin Data Update;
For Each Row( dtoutp, :LABEL = annot_pv[Sequence( 1, N Items (annot_pv), 1, 1 )] );
For each row( dtoutp, :MET_ID = met_l[Sequence (1,N items (met_l), 1, 13)] );
dtoutp << End Data Update;