Cálculo medio de vecinos cercanosHola a todos,
Tengo que calcular la media de las matrices / 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 una caja 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 una caja de 5x5 y 15 vecinos ...)
Se utilizará como una nueva función para el aprendizaje automático.
Mi codigo 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!
ScriptingRe: vecino cercano significa cálculoNo estoy seguro de cómo se compara la eficiencia, pero aquí hay una alternativa para que pruebes.
- El uso de la actualización de datos de inicio / fin () ayudará con cualquier método
- Usar el vecino más cercano es inteligente (y tal vez incluso más eficiente) pero tenga en cuenta que siempre devolverá el 8 más cercano, incluso en los bordes de la oblea donde los vecinos estarán todos 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();
Re: vecino cercano significa cálculoEstoy 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.
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: vecino cercano significa cálculo¡Muchas gracias, es muy interesante!
A veces utilizo "iniciar actualización de datos" pero no pensé en ello aquí: buen punto. Con eso, la solución Loc () es en realidad un poco más lenta que knearestrows () si agrega la actualización inicial que encuentro para 20,000 líneas:
antiguo script sin actualización inicial: 116s!
knearestrows () con begin update: 5s
Loc () con inicio de actualización: 14 s
pero para los knearestrows tuve que cambiar la forma en que calculo la media ya que ya no podemos usar filas seleccionadas con la actualización de inicio / fin.
Para los bordes tienes toda la razón, había pensado en poner:
vecinos = tabla << Knearestrows ({8,1.5}, i);
Para evitar este problema usando un radio limitado
¡Gracias de nuevo!
Re: vecino cercano significa cálculopor otro lado, me doy cuenta de que la solución del límite de 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 ... Así que no me da exactamente lo que quiero, ¡tendré que buscar un poco más!
Re: vecino cercano significa cálculoPuede rellenar suficientes filas y columnas de valores faltantes, izquierda, derecha, arriba, abajo.Dependiendo de lo lejos que vaya con la extensión del vecindario, es posible que tenga 8 obleas de valor faltantes completas alrededor de la oblea real.
Hay otra forma de hacer esto, que también requiere filas y columnas ficticias, que serán muy rápidas:
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 el medio de una matriz de 3NRows x 3NCols (la 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 necesite esto: Usar 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 allá 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ó anteriormente. 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: vecino cercano significa cálculoHola @Franck_R ,
Quizás esto también pueda ayudarte: Complemento: análisis de datos espaciales
Si lo que buscas es la correlación espacial, la I de Moran es quizás el concepto más básico.
Ron
Re: vecino cercano significa cálculoGracias por todo esto, voy a profundizar más en ello.