최근접 이웃 알고리즘: 최적화 도움말 필요안녕하세요 여러분,
다음 스크립트를 만들었습니다. 이는 각 행이 웨이퍼의 칩에 해당하고 각 행에 좌표(x,y)와 일부 매개변수가 있는 데이터 테이블을 분석하기 위한 것입니다. 스크립트는 각 행을 살펴보고 이 다이의 "이웃"인 다이에 해당하는 다른 행을 찾고 해당 이웃에 대한 일부 매개변수의 중앙값과 표준 편차를 계산합니다.
여기서 문제는 작동은 하면서도 수만 행의 데이터 세트를 분석할 때 실행 시간이 오래 걸린다는 점이다.
계산 시간을 줄이기 위해 스크립트를 최적화하는 방법에 대해 누구든지 조언을 해주시면 정말 감사하겠습니다.
아래 코드:
dt0 = current data table();
dt0 << new column("NN_median");
dt0 << new column("NN_stdev");
for ( i = 1, i <= N Rows(dt0), i++,
//Find rows corresponding to neighboring dies
m = dt0[0,{"x", "y"}];
v = ( abs( m[0,1] - :x[i] ) <= 2 )
&
( abs( m[0,2] - :y[i] ) <= 2 );
rows = loc(v);
// Create new DT of neighborhood
dt1 = dt0 << subset( Rows(rows), Columns(:param), invisible );
//Calculate Median and Std Dev
tb = Tabulate(
Add Table(
Column Table( Statistics( Median, Std Dev ) ),
Row Table( Analysis Columns( column("param") ) )
)
);
dt2 = tb << make into data table( invisible );
tb << close window;
current data table(dt2);
placeholder_median = :Median[1];
placeholder_stdev = :Std Dev[1];
close(dt2, no save);
close(dt1, no save);
current data table(dt0);
:NN_median[i] = placeholder_median;
:NN_stdev[i] = placeholder_stdev;
);고급 통계 모델링자동화 및 스크립팅소비자 및 시장 조사대량 맞춤화품질 및 프로세스 엔지니어링답변: 최근접 이웃 알고리즘: 최적화 도움이 필요합니다감사해요! 진행하면서 JMP 스크립트 구문을 배우고 있습니다. 귀하의 코드는 확실히 몇 가지 불필요한 작업을 우회합니다.
답변: 최근접 이웃 알고리즘: 최적화 도움이 필요합니다벤치마킹을 수행하지는 않았지만 더 크고 일반적인 문제에는 'KDTable()'을 사용하는 것이 좋을 것으로 예상할 수 있습니다.
Names Default To Here( 1 );
n = 100; // Size of square
// Make a table of x and y locations
dtx = AsTable((1::n)`, << Invisible);
dty = AsTable((1::n)`, << Invisible);
dt = dty << Join( With( dtx ), Cartesian Join );
Close(dtx, NoSave);
Close(dty, NoSave);
Column(dt, 1) << setName("x");
Column(dt, 2) << setName("y");
dt << deleteProperty("Source");
dt << setName("xy Locations");
// Put these locations into a matrix
mat = dt << getAsMatrix;
tbl = KDTable( mat );
// Pick a point in the interior, so we don't need to decide on any boundary conditions
myX = RandomInteger(2, n-1);
myY = RandomInteger(2, n-1);
myRow = Loc(mat[0, 1] == myX & mat[0, 2] == myY);
myRow = myRow[1];
// Find the 8 nearest neighbours to the chosen point
{rows, dist} = tbl << K nearest rows( 8, myRow );
Show( myRow, rows );
// Check it worked
myXvals = Column(dt, "x")[myRow];
myYvals = Column(dt, "y")[myRow];
dt << NewColumn("Distance", Numeric, Continuous, Formula(sqrt((:x - myXvals)^2 +(:y - myYvals)^2)));
dt << selectRows(VConcat(myRow, rows`));
gb = dt << Graph Builder(
Size( 529, 453 ),
Show Control Panel( 0 ),
Variables( X( :x ), Y( :y ), Color( :Distance ) ),
Elements( Points( X, Y, Legend( 5 ) ) )
);
답변: 최근접 이웃 알고리즘: 최적화 도움이 필요합니다다음을 사용하여 11초 만에 동일한 결과를 얻었습니다.
dt0 = Current Data Table();
dt0 << New Column( "NN_median" );
dt0 << New Column( "NN_stdev" );
m = dt0[0, {"x", "y"}];
For( i = 1, i <= N Rows( dt0 ), i++,
//Find rows corresponding to neighboring dies
v = (Abs( m[0, 1] - :x[i] ) <= 2) & (Abs( m[0, 2] - :y[i] ) <= 2);
rows = Loc( v );
dt0:NN_stdev[i] = Std Dev( dt0:param[rows] );
dt0:NN_median[i] = Quantile( .5, dt0:param[rows] );
);
코드가 13분 이상 걸리는 동안
답변: 최근접 이웃 알고리즘: 최적화 도움이 필요합니다샘플 데이터 세트 *)를 가져와 벤치마킹을 수행해 보겠습니다.
- 어떻게 하면 안 되는지 예부터 시작해 보겠습니다.
*) 실제 사용 사례는 ~ 500 x 500개의 다이와 수백 개의 웨이퍼입니다.
Names Default To Here( 1 );
dt0 = Open( "$SAMPLE_DATA/Wafer Stacked.jmp" );
wait(0);
t0 = hptime();
dt0 << New Column( "row", set each value( Row() ) );
max dist = 1; // just keep the direct neighbors
// create a lookup table
dtx = As Table( (-21 :: 21)`, <<INVISIBLE></INVISIBLE>
답변: 최근접 이웃 알고리즘: 최적화 도움이 필요합니다Names Default To Here( 1 );
dt0 = Open( "$SAMPLE_DATA/Wafer Stacked.jmp" );
wait(0);
t0 = hptime();
// get the coordinates
dtLookup = dt0 << Summary(Group( :X_Die, :Y_Die ),output table name( "xyLocations" ), Private);
dtLookup << Delete Columns( :N Rows );
dt0 << New Column( "row", set each value( Row() ) );
max dist = 1; // just keep the direct neighbors
// create the KDTable
mat = dtLookup << getAsMatrix;
tbl = KDTable( mat );
dtLookup << New Column( "row_lookup", set each value( Row() ) );
// add column with neighboring rows
Eval (Eval Expr(dtLookup << New Column( "neighbors",Vector,
Expression,
set each value(
{neighbors, dist} = tbl << K nearest rows( 100, Row() );
neighbors[Where( dist <= Expr(max dist) )];
)
)));
// map the neighbors to the main table
dt0 << Update(
With( dtLookup ),
Match Columns( :X_Die = :X_Die, :Y_Die = :Y_Die ),
Add Columns from Update Table( :row_lookup, :neighbors ),
Replace Columns in Main Table( None )
);
Close(dtLookup, noSave);
wait(0);
t1=hptime();
//map the rows from the lookup table to the correct rows
// split the table to find the rows faster
// to speed things up, one could do the neighbours averaging here, but that's not the target
mySubsets = dt0 << Subset( By( :Lot, :Wafer ), All rows, Selected columns only( 0 ), Private( 1 ) );
For Each( {myTable}, mySubsets,
// so complicated ?!?!
dthelp= new table("help", add rows(col maximum(myTable:row_lookup)), new column("row_lookup",set each value(row())), private(1));
dthelp << Update(
With( myTable ),
Match Columns( :row_lookup = :row_lookup ),
Add Columns from Update Table( :row ),
Replace Columns in Main Table( None )
);
myTable:neighbors << set each value(
input = :neighbors; // take the neighbors from the lookup table
Transform each({row},input, dthelp[row,"row"]);
);
close(dthelp, noSave)
);
//merge the subsets and map the neighbors back to the main table
tmp = mySubsets[1] << Concatenate( mySubsets[2 :: N Items( mySubsets )], Private() );
For Each( {myTable}, mySubsets, Close( myTable, noSave ) );
dt0 << Delete Columns( :neighbors );
dt0 << Update(
With( tmp ),
Match Columns( :Lot = :Lot, :Wafer = :Wafer, :X_Die = :X_Die, :Y_Die = :Y_Die ),
Add Columns from Update Table( :neighbors ),
Replace Columns in Main Table( None )
);
Close( tmp, noSave );
wait(0);
t2= hptime();
// now use the cool new column
dt0 << New Column( "Defects average", Formula( Mean( :Defects[:neighbors] ) ) );
wait(0);
t3=hptime();
print("create lookup", (t1-t0)/1000000);
print("correct the rows", (t2-t1)/1000000);
print("calculate neighbor average", (t3-t2)/1000000);