Cálculo de la media de los vecinos cercanosHola a todos,
Tengo que calcular la media de los troqueles/componentes vecinos en una oblea microelectrónica, por ejemplo, en una caja de 3x3 como esa:

El componente de referencia está en el centro de un cuadro y, por lo tanto, rodeado por 8 componentes cuya media quiero calcular, para cada fila de la tabla de datos (luego calcule lo mismo para un cuadro de 5x5 y 16 vecinos...)
Se utilizará como una nueva función para el aprendizaje automático.
mi código es:
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
);¿Alguien tiene una forma inteligente de hacer ese cálculo de manera más eficiente?
¡gracias!
secuencias de comandosRe: Cálculo de la media de los vecinos cercanosGracias por todo esto, voy a profundizar más en ello.
Re: Cálculo de la media de los vecinos cercanosHola @Franck_R ,
Quizás esto también te pueda ayudar: Complemento: análisis de datos espaciales
Si lo que buscas es la correlación espacial, el I de Moran es quizás el concepto más básico.
Ron
Re: Cálculo de la media de los vecinos cercanosPuede rellenar suficientes filas y columnas de valores faltantes, izquierda, derecha, arriba, abajo.Dependiendo de qué tan lejos llegue con la extensión del vecindario, es posible que tenga 8 obleas completas de valores faltantes que rodean la oblea real.
Hay otra forma de hacer esto, que también requiere las filas y columnas ficticias, que será muy rápida:
Las matrices JMP 2D se pueden indexar como matrices lineales 1D.
[ 1 2,
3 4,
5 6 ] (3 filas, 2 columnas)
también parece
[ 1,
2,
3,
4,
5,
6] (6 filas, 1 columna cuando se usa un subíndice)
Si la oblea es NRows x NCols, colóquela en medio de una matriz de 3NRows x 3NCols (lo llamaré M3).
Puede hacer una matriz de subíndices 1D para indexar M3 agregando 1 para moverse horizontalmente y agregando 3NCols para moverse verticalmente. Para extraer una submatriz de 3x3 de M3, use la matriz de índice y la función shape().
algo como esto:
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 ., . .]
Es posible que también necesites esto: Uso de Loc con una matriz 2D
Puede hacer indexer3x3, etc. y simplemente reutilizar el M3 para cada nivel. el ciclo for x=3, x<=5 necesita ir un poco más lejos cada vez.
editar: la función de forma puede ser innecesaria si solo está obteniendo la media de los elementos indexados, pero ayuda a mostrar lo que sucedió arriba. más: las matrices JSL tienen un comportamiento especial cuando el índice es menor que 1 y no obtendrá el mensaje de error que podría esperar. si el indexador contiene un cero (o -1, etc.) parecerá muy extraño.
Re: Cálculo de la media de los vecinos cercanospor otro lado, me doy cuenta de que la solución del límite del radio no es perfecta porque todavía tomamos un elemento adicional en la matriz
por ejemplo, un radio de 1,5 contiene un valor de 2 porque este es el valor que detiene la búsqueda de vecinos... Entonces no me da exactamente lo que quiero, ¡tendré que buscar un poco más!
Re: Cálculo de la media de los vecinos cercanosMuchas gracias es muy interesante!
A veces uso "iniciar actualización de datos", pero no lo pensé aquí: buen punto. Con eso, la solución Loc() es en realidad un poco más lenta que knearestrows() si agrega la actualización de inicio que encuentro para 20,000 líneas:
script antiguo sin actualización de inicio: 116s!
knearestrows() con actualización de inicio: 5s
Loc() con inicio de actualización: 14s
pero para los knearestrows tuve que cambiar la forma en que calculo la media, ya que ya no podemos usar las filas seleccionadas con la actualización de inicio/finalización.
Para los bordes tienes toda la razón, había pensado en poner:
neighbors = table << Knearestrows( {8, 1.5}, i );
Para evitar este problema usando un radio limitado
¡Gracias de nuevo!
Re: Cálculo de la media de los vecinos cercanosEstoy bastante seguro de que el tamaño del problema determinará si el enfoque kdtable() o loc() es mejor. Supongo que loc() ganará para una matriz de 10x10 o más pequeña, y kdtable para 100x100 o más grande.
El punto de Xan sobre los bordes es importante. Loc() podría ser la forma más fácil de obtener la respuesta correcta.
Re: Cálculo de la media de los vecinos cercanosNo estoy seguro de cómo se compara la eficiencia, pero aquí hay una alternativa para que pruebe.
- El uso de la actualización de datos de inicio/finalización () ayudará con cualquier método
- Usar Nearest Neighbor es inteligente (y tal vez incluso más eficiente), pero tenga en cuenta que siempre devolverá los 8 más cercanos, incluso en los bordes de la oblea donde todos los vecinos estarán en un lado.
- El subíndice de matriz puede ser más eficiente que 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();