tutorial sheet español downloads cheat neo4j cypher

sheet - Cómo usar la función promedio en neo4j con colección



neo4j tutorial (4)

¿Cómo se llega a las colecciones A y B ? La función avg es una función de agregación y no se puede usar en el contexto REDUCE ni se puede aplicar a colecciones. Debe calcular su promedio antes de llegar a ese punto, pero exactamente cómo hacerlo mejor depende de cómo llegue a las dos colecciones de valores. Si se encuentra en un punto en el que tiene elementos de resultados individuales que luego collect para obtener A y B , ese es el punto en el que podría usar avg . Por ejemplo:

WITH [1, 2, 3, 4] AS aa UNWIND aa AS a WITH collect(a) AS aa, avg(a) AS aAvg RETURN aa, aAvg

y para ambas colecciones

WITH [1, 2, 3, 4] AS aColl UNWIND aColl AS a WITH collect(a) AS aColl, avg(a) AS aAvg WITH aColl, aAvg,[5, 6, 7, 8] AS bColl UNWIND bColl AS b WITH aColl, aAvg, collect(b) AS bColl, avg(b) AS bAvg RETURN aColl, aAvg, bColl, bAvg

Una vez que tenga los dos promedios, llamémoslos aAvg y bAvg , y las dos colecciones, aColl y bColl , puede hacer

RETURN REDUCE(x = 0.0, i IN range(0, size(aColl) - 1) | x + ((aColl[i] - aAvg) * (bColl[i] - bAvg))) / (size(aColl) - 1) AS covariance

Quiero calcular la covarianza de dos vectores como colección A = [1, 2, 3, 4] B = [5, 6, 7, 8]

Cov (A, B) = Sigma [(ai-AVGa) * (bi-AVGb)] / (n-1)

Mi problema para el cómputo de covarianza es:

1) No puedo tener una función agregada anidada cuando escribo

SUM((ai-avg(a)) * (bi-avg(b)))

2) O en otra forma, ¿cómo puedo extraer dos colecciones con una reducción como:

REDUCE(x= 0.0, ai IN COLLECT(a) | bi IN COLLECT(b) | x + (ai-avg(a))*(bi-avg(b)))

3) si no es posible extraer dos colecciones en o, reducir la forma en que es posible relacionar su valor para calcular la covarianza cuando están separadas

REDUCE(x= 0.0, ai IN COLLECT(a) | x + (ai-avg(a))) REDUCE(y= 0.0, bi IN COLLECT(b) | y + (bi-avg(b)))

Quiero decir que puedo escribir anidado reducir?

4) ¿Hay alguna forma de "desenrollar", "extraer"

Gracias de antemano por cualquier ayuda.


Muchas gracias, Dears, sin embargo, me pregunto cuál es más eficiente

1) Desenrollado anidado y rango dentro de reducir -> @cybersam

2) anidado Reducir -> @Nicole White

3) Anidado con (reiniciar consulta por) -> @jjaderberg

PERO el problema importante es:

Por qué hay un error y una diferencia entre sus cálculos y los cálculos reales y reales.

Quiero decir que su covarianza es igual a = 1.6666666666666667

Pero en el mundo real la covarianza es igual a = 1.25

Por favor, consulte: https://www.easycalculation.com/statistics/covariance.php

Vector X: [1, 2, 3, 4] Vector Y: [5, 6, 7, 8]

Creo que esta diferencia se debe a que algunos cálculos no tienen en cuenta (n-1) como divisores y en lugar de (n-1), simplemente usan n. Por lo tanto, cuando aumentamos el divisor de n-1 a n, el resultado disminuirá de 1.6 a 1.25.


[EDITADO]

Esto debería calcular la covarianza (de acuerdo con su fórmula), dadas las entradas de muestra:

WITH [1,2,3,4] AS aa, [5,6,7,8] AS bb UNWIND aa AS a UNWIND bb AS b WITH aa, bb, SIZE(aa) AS n, AVG(a) AS avgA, AVG(b) AS avgB RETURN REDUCE(s = 0, i IN RANGE(0,n-1)| s +((aa[i]-avgA)*(bb[i]-avgB)))/(n-1) AS covariance;

Este enfoque está bien cuando n es pequeño, como es el caso con los datos de muestra originales.

Sin embargo, como señalan @NicoleWhite y @jjaderberg, cuando n no es pequeño, este enfoque será ineficiente. La respuesta de @NicoleWhite es una elegante solución general.


La respuesta de Cybersam es totalmente correcta, pero si desea evitar el producto cartesiano n^2 que resulta del doble UNWIND, puede hacerlo en su lugar:

WITH [1,2,3,4] AS a, [5,6,7,8] AS b WITH REDUCE(s = 0.0, x IN a | s + x) / SIZE(a) AS e_a, REDUCE(s = 0.0, x IN b | s + x) / SIZE(b) AS e_b, SIZE(a) AS n, a, b RETURN REDUCE(s = 0.0, i IN RANGE(0, n - 1) | s + ((a[i] - e_a) * (b[i] - e_b))) / (n - 1) AS cov;

Editar:

No llamo a nadie, pero permítanme dar más detalles sobre por qué querría evitar el doble UNWIND en https://.com/a/34423783/2848578 . Como dije a continuación, UNWINDing k length-n colecciones en Cypher da como resultado n^k filas. Así que tomemos dos colecciones de longitud-3 sobre las cuales desea calcular la covarianza.

> WITH [1,2,3] AS a, [4,5,6] AS b UNWIND a AS aa UNWIND b AS bb RETURN aa, bb; | aa | bb ---+----+---- 1 | 1 | 4 2 | 1 | 5 3 | 1 | 6 4 | 2 | 4 5 | 2 | 5 6 | 2 | 6 7 | 3 | 4 8 | 3 | 5 9 | 3 | 6

Ahora tenemos n^k = 3^2 = 9 filas. En este punto, tomar el promedio de estos identificadores significa que estamos tomando el promedio de 9 valores.

> WITH [1,2,3] AS a, [4,5,6] AS b UNWIND a AS aa UNWIND b AS bb RETURN AVG(aa), AVG(bb); | AVG(aa) | AVG(bb) ---+---------+--------- 1 | 2.0 | 5.0

Además, como dije a continuación, esto no afecta la respuesta porque el promedio de un vector repetitivo de números siempre será el mismo. Por ejemplo, el promedio de {1,2,3} es igual al promedio de {1,2,3,1,2,3}. Es probable que no tenga importancia para valores pequeños de n , pero cuando comienzas a obtener valores más grandes de n , comenzarás a ver una disminución en el rendimiento.

Digamos que tienes dos vectores de longitud-1000. Calculando el promedio de cada uno con un doble UNWIND:

> WITH RANGE(0, 1000) AS a, RANGE(1000, 2000) AS b UNWIND a AS aa UNWIND b AS bb RETURN AVG(aa), AVG(bb); | AVG(aa) | AVG(bb) ---+---------+--------- 1 | 500.0 | 1500.0

714 ms

Es significativamente más lento que con REDUCE:

> WITH RANGE(0, 1000) AS a, RANGE(1000, 2000) AS b RETURN REDUCE(s = 0.0, x IN a | s + x) / SIZE(a) AS e_a, REDUCE(s = 0.0, x IN b | s + x) / SIZE(b) AS e_b; | e_a | e_b ---+-------+-------- 1 | 500.0 | 1500.0

4 ms

Para unir todo, compararé las dos consultas completas en vectores de longitud-1000:

> WITH RANGE(0, 1000) AS aa, RANGE(1000, 2000) AS bb UNWIND aa AS a UNWIND bb AS b WITH aa, bb, SIZE(aa) AS n, AVG(a) AS avgA, AVG(b) AS avgB RETURN REDUCE(s = 0, i IN RANGE(0,n-1)| s +((aa[i]-avgA)*(bb[i]-avgB)))/(n-1) AS covariance; | covariance ---+------------ 1 | 83583.5

9105 ms

> WITH RANGE(0, 1000) AS a, RANGE(1000, 2000) AS b WITH REDUCE(s = 0.0, x IN a | s + x) / SIZE(a) AS e_a, REDUCE(s = 0.0, x IN b | s + x) / SIZE(b) AS e_b, SIZE(a) AS n, a, b RETURN REDUCE(s = 0.0, i IN RANGE(0, n - 1) | s + ((a[i] - e_a) * (b[i ] - e_b))) / (n - 1) AS cov; | cov ---+--------- 1 | 83583.5

33 ms