近傍平均の計算やあみんな、
たとえば、次のような3x3ボックスで、マイクロエレクトロニクスウェーハ上の隣接ダイ/コンポーネントの平均を計算する必要があります。

参照コンポーネントはボックスの中央にあるため、データ テーブルの各行について平均値を計算したい 8 つのコンポーネントに囲まれています (次に、5x5 ボックスと 16 個の隣接コンポーネントについて同じことを計算します...)
機械学習の新機能として利用されます。
私のコードは次のとおりです。
dt = current data table();
<BR />// building the KD table
matrice = (dt:row << getvalues) || (dt:col << getvalues);
table = KDTable(matrice);
for( i=1, i<=nrows(dt),i++,
// get the 3x3 neighbors
neighbors = table << Knearestrows(8,i);
neighbors_number = neighbors[1,1];
// Select the neighbors and get their metrics values and calculate the mean<BR /> dt << select rows (neighbors_number );
mean_selection = Col Mean( If( Selected(), :metric, . ) );
:mean_metric[i] = mean_selection;
dt << clear select
);その計算をより効率的に行うスマートな方法はありますか?
ありがとう!
スクリプティングRe: 近傍平均の計算このすべてに感謝します、私はそれをより深く掘り下げるつもりです
Re: 近傍平均の計算やあ@フランク_R 、
おそらくこれもあなたを助けることができます:アドイン: 空間データ分析
探しているのが空間相関である場合、モランの I はおそらく最も基本的な概念です。
ロン
Re: 近傍平均の計算左、右、上、下の欠損値の行と列を十分に埋めることができます。近傍をどこまで拡張するかによって、実際のウエハーの周囲に 8 つの完全な欠損値ウエハーが存在する可能性があります。
これを行う別の方法があり、ダミーの行と列も必要です。これは非常に高速です。
JMP 2D 行列は、1D 線形行列として索引付けできます。
[ 1 2,
3 4、
5 6 ] (3 行 2 列)
のようにも見える
[ 1,
2、
3、
4、
5,
6] (添字が1つの場合は6行1列)
ウェーハが NRows x NCols の場合、それを 3NRows x 3NCols 行列の中央に置きます (M3 と呼びます)。
1 を追加して水平方向に移動し、3NCols を追加して垂直方向に移動することにより、インデックス M3 に 1D 添字の行列を作成できます。 M3 から 3x3 サブマトリックスを抽出するには、インデックス マトリックスと shape() 関数を使用します。
このようなもの:
M3 = [. . . . . . . . .,
. . . . . . . . .,
. . . . . . . . .,
. . . 1 2 3 . . .,
. . . 4 5 6 . . .,
. . . 7 8 9 . . .,
. . . . . . . . .,
. . . . . . . . .,
. . . . . . . . .];
indexer2x2 = [1 2 10 11]; // top left 2x2 sub-matrix
For( x = 2, x <= 5, x += 1,
For( y = 2, y <= 5, y += 1,
Write( "\!n ", x, " ", y, " ", Shape( M3[indexer2x2 + x + y * 9], 2 ) );
)
);
2 2 [。 ., . 1]
2 3 [。 1、。 4]
2 4 [。 4、。 7]
2 5 [。 7、 。 .]
3 2 [。 ., 1 2]
3 3 [1 2, 4 5]
3 4 [4 5, 7 8]
3 5 [7 8, . .]
4 2 [。 ., 2 3]
4 3 [2 3, 5 6]
4 4 [5 6, 8 9]
4 5 [8 9, . .]
5 2 [。 ., 3 .]
5 3 [3 ., 6 .]
5 4 [6 ., 9 .]
5 5 [9 ., . .]
これも必要かもしれません: 2D マトリックスでの Loc の使用
indexer3x3 などを作成して、各レベルで M3 を再利用するだけです。 for ループ x=3, x<=5 は、毎回少し先に進む必要があります。
編集: インデックス付き要素の平均を取得するだけの場合、形状関数は不要かもしれませんが、上記で何が起こったかを示すのに役立ちます。詳細: インデックスが 1 未満の場合、JSL 行列は特別な動作をし、期待するエラー メッセージが表示されません。インデクサーにゼロ (または -1 など) が含まれていると、非常に奇妙に見えます。
Re: 近傍平均の計算一方、配列に余分な要素をまだ取っているため、半径制限の解決策は完全ではないことに気付きました
たとえば、半径 1.5 には値 2 が含まれます。これは、近隣検索を停止する値であるためです... だから、私が欲しいものを正確に与えてくれないので、もう少し検索する必要があります!
Re: 近傍平均の計算とても面白いですありがとうございます!
「データ更新の開始」を時々使用しますが、ここでは考えていませんでした: 良い点です。 これにより、20,000 行で見つかった begin update を追加すると、Loc() ソリューションは実際には knearestrows() よりも少し遅くなります。
更新を開始しない古いスクリプト: 116s !
knearestrows() と begin update: 5 秒
更新を開始する Loc(): 14 秒
しかし、knearestrow については、begin/end update で選択行を使用できなくなったため、平均の計算方法を変更する必要がありました。
あなたが完全に正しいエッジについては、次のものを入れることを考えていました:
neighbors = table << Knearestrows( {8, 1.5}, i );
限られた半径を使用してこの問題を回避するには
再度、感謝します!
Re: 近傍平均の計算kdtable() または loc() アプローチのどちらが優れているかは、問題の大きさによって決まると確信しています。 loc() は 10x10 以下の行列で、kdtable は 100x100 以上で勝つと思います。
エッジに関する Xan の指摘は重要です。 Loc() は、正しい答えを得る最も簡単な方法かもしれません。
Re: 近傍平均の計算効率がどのように比較されるかはわかりませんが、試してみるための代替手段を次に示します。
- begin/end data update() を使用すると、どのメソッドでも役立ちます
- Nearest Neighbor を使用するのは賢い (そしておそらくもっと効率的) ですが、隣人がすべて片側にあるウェーハの端であっても、常に最も近い 8 つを返すことに注意してください。
- 行列の添え字は、Col Mean() よりも効率的です。
dt = current data table();
metrics = dt[0, "metric"];
rows = dt[0, "row"];
cols = dt[0, "col"];
d = 1; // 1 => 3x3, 2 => 5x5
dt << Begin Data Update();
For Each Row(
neighbors = Loc( :col - d <= cols <= :col + d & :row - d <= rows <= :row + d );
mean all = Mean( metrics[neighbors] );
nn = N Rows( neighbors );
mean without center = (mean all * nn - :metric) / (nn - 1);
:mm = mean without center;
);
dt << End Data Update();