El algoritmo de similitud de coseno es una herramienta interesante que podemos utilizar en el análisis de grafos. Este se encarga de conocer el ángulo entre dos vectores n-dimensionales en un espacio n-dimensional. Esto siginifica que el resultado que obtenemos es el producto escalar de los dos vectores dividido por el producto de las longitudes o magnitudes de los dos vectores. A continuación profundizaremos un poco más sobre el uso y cálculo de este algoritmo para comprender su funcionalidad y tendrás a tu disposición algunos ejemplos prácticos desarrollados en Neo4j.
¿Qué es la similitud de coseno?
La similitud del coseno es una medida de similitud que se calcula entre dos vectores distintos de cero dentro del espacio interno del producto que mide el coseno del ángulo entre ellos. El coseno de 0° es 1, y es menor que uno para cualquier ángulo que se encuentre en el intervalo (0, π] radianes. Así que este caso se trata de un calculo que da origen a un juicio de orientación y no de magnitud.
Dentro de la similitud de coseno dos vectores con la misma orientación tienen una similitud de coseno de 1 , dos vectores orientados a 90 ° entre sí tienen una similitud de 0, y dos vectores diametralmente opuestos tienen una similitud de -1, independientemente de su magnitud.
Es vital comprender a profundidad el concepto de la similitud de coseno para entender su utilidad para nuestros proyectos. Esta se usa particularmente en un espacio positivo donde el resultado esta claramente delimitado en [0,1]} [0,1].
Dentro de los datos más resaltantes que posee el cálculo de la similitud de coseno es que su nombre proviene del término «coseno de dirección» en este caso, los vectores unitarios cumplen con la condición de ser máximamente «similares» si son paralelos y en el caso de que sean máximamente diferentes, deben ser ortogonales o perpendiculares entre si. Esto es similar a los valores que podemos encontrar en el coseno donde la unidad de valor máximo se encuentra cuando los segmentos tienen un ángulo cero y cero sin presentar alguna correlación, cuando los segmentos son totalmente perpendiculares.
Casos de uso de la similitud de coseno
Este importante cálculo se realiza en espacios positivos de alta dimensión. Esto es de gran utilidad en la recuperación de información valiosa y minería de textos. Para utilizarlo de forma eficiente a cada término se le asigna una dimensión diferente y al documento se le caracteriza por vectores. En cada uno de los vectores se asigna un valor para que corresponda con la dimensión en igual cantidad de veces. Así podemos detectar cuantas veces aparece un termino o un valor en un documento, ya que ejecutando el algoritmo obtenemos un conteo preciso de la información que buscamos. También puede ser utilizado para medir la cohesión de los grupos entre datos.
En Neo4j encontramos procedimientos para calcular la similaridad utilizando la similitud del coseno en conjuntos grandes de datos y para elementos más pequelos podemos aplicar las funciones. Veamos a continuación ejemplos desarrollados en Cypher para comprender mejor su aplicación.
Ejemplos de aplicación:
Para comprender el funcionamiento básico de este algoritmo introduciremos dos listas de números y aplicaremos la función de similitud de coseno para evaluar su indice de similaridad.
En primer lugar pedimos que nos devuelva la similaridad de las listas de números que introducimos:
RETURN algo.similarity.cosine([3,8,7,5,2,9], [10,8,6,6,4,5]) AS similarity
Al ejecutarse el calculo tenemos que la similaridad de las dos listas de números es la siguiente:
similarity |
0.8638935626791596 |
Ahora, veamos algo un poco más complejo utilizando un grafo construido en Cypher. Creamos una lista compleja etiquetada en la que determinamos nacionalidades, personas y puntuaciones de preferencias para cada una de las personas de la lista.
MERGE (french:Cuisine {name:'French'}) MERGE (italian:Cuisine {name:'Italian'}) MERGE (indian:Cuisine {name:'Indian'}) MERGE (lebanese:Cuisine {name:'Lebanese'}) MERGE (portuguese:Cuisine {name:'Portuguese'}) MERGE (british:Cuisine {name:'British'}) MERGE (mauritian:Cuisine {name:'Mauritian'}) MERGE (zhen:Person {name: "Zhen"}) MERGE (praveena:Person {name: "Praveena"}) MERGE (michael:Person {name: "Michael"}) MERGE (arya:Person {name: "Arya"}) MERGE (karin:Person {name: "Karin"}) MERGE (praveena)-[:LIKES {score: 9}]->(indian) MERGE (praveena)-[:LIKES {score: 7}]->(portuguese) MERGE (praveena)-[:LIKES {score: 8}]->(british) MERGE (praveena)-[:LIKES {score: 1}]->(mauritian) MERGE (zhen)-[:LIKES {score: 10}]->(french) MERGE (zhen)-[:LIKES {score: 6}]->(indian) MERGE (zhen)-[:LIKES {score: 2}]->(british) MERGE (michael)-[:LIKES {score: 8}]->(french) MERGE (michael)-[:LIKES {score: 7}]->(italian) MERGE (michael)-[:LIKES {score: 9}]->(indian) MERGE (michael)-[:LIKES {score: 3}]->(portuguese) MERGE (arya)-[:LIKES {score: 10}]->(lebanese) MERGE (arya)-[:LIKES {score: 10}]->(italian) MERGE (arya)-[:LIKES {score: 7}]->(portuguese) MERGE (arya)-[:LIKES {score: 9}]->(mauritian) MERGE (karin)-[:LIKES {score: 9}]->(lebanese) MERGE (karin)-[:LIKES {score: 7}]->(italian) MERGE (karin)-[:LIKES {score: 10}]->(portuguese)
Posteriormente indicamos que nos devuelva la similaridad especifica de dos de las personas representadas en vértices dentro del grafo.
MATCH (p1:Person {name: 'Michael'})-[likes1:LIKES]->(cuisine) MATCH (p2:Person {name: "Arya"})-[likes2:LIKES]->(cuisine) RETURN p1.name AS from, p2.name AS to, algo.similarity.cosine(collect(likes1.score), collect(likes2.score)) AS similarity
Al ejecutar el algoritmo de forma especifica obtenemos los siguientes resultados.
Table 7.98. Results | ||
from | to | similarity |
"Michael" | "Arya" | 0.9788908326303921 |
Ahora bien, si queremos comparar la similaridad de uno de los vértices del grafo con todos los demás, podemos realizarlo de la siguiente forma:
MATCH (p1:Person {name: 'Michael'})-[likes1:LIKES]->(cuisine) MATCH (p2:Person)-[likes2:LIKES]->(cuisine) WHERE p2 <> p1 RETURN p1.name AS from, p2.name AS to, algo.similarity.cosine(collect(likes1.score), collect(likes2.score)) AS similarity ORDER BY similarity DESC
Obteniendo los siguientes resultados:
Resultados | ||
from | to | similarity |
"Michael" | "Arya" | 0.9788908326303921 |
"Michael" | "Zhen" | 0.9542262139256075 |
"Michael" | "Praveena" | 0.9429903335828894 |
"Michael" | "Karin" | 0.8498063272285821 |
Esperamos que esta información sirva para comprender la utilidad del algoritmo de similitud de coseno.
Visita más de Grapheverywhere para descubrir todo lo que necesitas sobre los algoritmos de grafos.