Skip to content
Developer Edition runs on one host and does not require a product license file. Need multi-host deployment or performance testing at scale? Explore Enterprise Edition

Cosine Similarity

Algorithm introduction

Cosine similarity computes pairwise similarity scores from vector directions in embedding space.

Compute cosine similarity between two nodes identified by node property id using undirected 1-hop neighborhoods, counting parallel edges as multiplicity in the adjacency vector.

For more information, see Cosine Similarity.

Data model

To implement the Cosine Similarity algorithm in GQL, the following data model is used to create a graph type:

  • Entities are represented by nodes of type Node, with properties id and rating.
  • Relationships are represented by edges of type Link, with property weight.

For the complete definition of the graph type, see Prepare graph data.

Procedure implementation

To compute Cosine Similarity results, a procedure is created.

For more information about the procedure, see Procedure implementation. The following section describes the key components of the procedure and how it works.

The procedure takes the following input parameters:

  • left_id: INT64. ID of the first node to compare.
  • right_id: INT64. ID of the second node to compare.

Additionally, the following variables are defined within the procedure:

Variable name Variable type Description
common_cnt Global SumAgg aggregator value variable Count of common neighbors between the left and right nodes.
left_deg Global SumAgg aggregator value variable Degree of the left query node.
right_deg Global SumAgg aggregator value variable Degree of the right query node.
dot_val Global SumAgg aggregator value variable Dot product of left and right node neighborhood indicator vectors.
left_norm_sq Global SumAgg aggregator value variable Squared L2 norm of the left node's neighborhood vector.
right_norm_sq Global SumAgg aggregator value variable Squared L2 norm of the right node's neighborhood vector.
similarity Primitive value variable Final cosine similarity score between the two nodes.
left_cnt Node-attached SumAgg aggregator value variable Per-node flag/count indicating membership in left node's neighborhood.
right_cnt Node-attached SumAgg aggregator value variable Per-node flag/count indicating membership in right node's neighborhood.

The following steps outline the logic of the procedure:

  1. For the left node, mark all its neighbors with seen_left; for the right node, mark all with seen_right.
  2. Compute dot_val (number of common neighbors), left_norm_sq (left node degree), and right_norm_sq (right node degree).
  3. Compute cosine similarity as dot_val / sqrt(left_norm_sq × right_norm_sq).
  4. Return the similarity score.

Steps

Run the following code blocks in order in the NebulaGraph Studio CONSOLE. For first-time setup, follow Prepare algorithm sample data to check where to run commands and how the directory is mounted.

1. Prepare graph data

  1. Create a graph type that matches your data model.

    '''
    CREATE GRAPH TYPE IF NOT EXISTS cosine_similarity_graph_type AS {
        NODE Node (LABEL Node {id INT PRIMARY KEY, rating INT}),
        EDGE Link (Node)-[LABEL Link {weight INT, MULTIEDGE KEY()}]->(Node)
    }
    '''
    
  2. Download these CSV files and save them with their original names in examples/algorithms/cosine_similarity/ under your deployment directory:

    Preview the CSV files
    cosine_similarity_node.csv
    id,rating
    1,0
    2,2
    3,1
    4,0
    5,0
    6,2
    7,1
    8,2
    9,0
    10,1
    11,0
    12,2
    13,1
    14,1
    15,0
    16,2
    17,0
    18,1
    19,2
    20,0
    21,2
    22,1
    23,0
    24,1
    
    cosine_similarity_edge.csv
    src_id,dst_id,weight
    1,2,4
    1,3,2
    1,4,7
    1,5,9
    2,3,1
    2,4,6
    2,5,5
    2,6,2
    3,4,3
    3,5,4
    3,6,8
    4,6,2
    4,7,6
    4,8,5
    5,6,4
    5,8,7
    5,9,6
    6,8,1
    6,9,5
    6,10,6
    7,9,2
    7,10,9
    8,9,3
    8,11,6
    8,12,4
    9,10,4
    9,12,7
    9,13,2
    10,12,1
    10,13,8
    10,14,4
    11,12,2
    11,14,5
    11,15,7
    12,14,3
    12,15,6
    12,16,5
    13,15,2
    13,16,7
    14,15,4
    14,17,8
    14,18,2
    15,16,1
    15,18,5
    15,19,3
    16,18,3
    16,19,6
    17,18,2
    17,20,7
    17,21,5
    18,19,4
    18,21,9
    18,22,6
    19,21,1
    19,22,5
    20,21,3
    20,23,6
    20,24,8
    21,22,2
    21,23,4
    21,24,7
    22,24,4
    23,24,1
    
  3. Create a temporary graph based on the graph type and load the data files into the temporary graph.

    CREATE TEMPORARY GRAPH IF NOT EXISTS #cosine_similarity_graph TYPED cosine_similarity_graph_type
    
    '''
    USE #cosine_similarity_graph IMPORT INTO GRAPH {
          NODE (v@Node {id: id, rating: rating}) FROM DATAFILE {
              PATH: "file:///examples/algorithms/cosine_similarity/cosine_similarity_node.csv",
              FORMAT: "CSV",
              DELIMITER: ','
          },
          EDGE (id: src_id)-[e@Link {weight: weight}]->(id: dst_id) FROM DATAFILE {
              PATH: "file:///examples/algorithms/cosine_similarity/cosine_similarity_edge.csv",
              FORMAT: "CSV",
              DELIMITER: ','
          }
      }
    '''
    

    After the import succeeds, run this query in the console to check the node count:

    '''
    USE #cosine_similarity_graph
    MATCH (n)
    RETURN count(n) AS node_count
    '''
    

    The expected node_count is 24. If it differs, check the files and import results before continuing.

2. Create a procedure

Create a procedure to implement the Cosine Similarity algorithm. For more information about the procedure, see Procedure implementation.

'''
CREATE OR REPLACE PROCEDURE cosine_similarity_score(left_id INT64, right_id INT64)
RETURNS (
  query_left_id INT64,
  query_right_id INT64,
  left_degree INT64,
  right_degree INT64,
  common_neighbor_count INT64,
  dot_product DOUBLE,
  score DOUBLE
)
COMMENT "Compute cosine similarity between two vertices identified by vertex property id using undirected 1-hop neighborhoods, counting parallel edges as multiplicity in the adjacency vector."
AS {
  VALUE common_cnt SumAgg<INT64> = 0
  VALUE left_deg SumAgg<INT64> = 0
  VALUE right_deg SumAgg<INT64> = 0
  VALUE dot_val SumAgg<DOUBLE> = 0.0
  VALUE left_norm_sq SumAgg<DOUBLE> = 0.0
  VALUE right_norm_sq SumAgg<DOUBLE> = 0.0
  VALUE similarity DOUBLE = 0.0

  NODE VALUE left_cnt SumAgg<INT64> = 0
  NODE VALUE right_cnt SumAgg<INT64> = 0

  MATCH (s)-[e]-(n)
  WHERE s.id = left_id
  PER PATH {
    SET n.@left_cnt += 1
  }

  MATCH (s)-[e]-(n)
  WHERE s.id = right_id
  PER PATH {
    SET n.@right_cnt += 1
  }

  MATCH (n)
  WHERE n.@left_cnt > 0
  PER NODE (n) {
    SET @left_deg += n.@left_cnt
    SET @left_norm_sq += CAST(n.@left_cnt AS DOUBLE) * CAST(n.@left_cnt AS DOUBLE)
  }

  MATCH (n)
  WHERE n.@right_cnt > 0
  PER NODE (n) {
    SET @right_deg += n.@right_cnt
    SET @right_norm_sq += CAST(n.@right_cnt AS DOUBLE) * CAST(n.@right_cnt AS DOUBLE)
  }

  MATCH (n)
  WHERE n.@left_cnt > 0
    AND n.@right_cnt > 0
    AND n.id <> left_id
    AND n.id <> right_id
  PER NODE (n) {
    SET @common_cnt += 1
    SET @dot_val += CAST(n.@left_cnt AS DOUBLE) * CAST(n.@right_cnt AS DOUBLE)
  }

  IF left_id = right_id THEN {
    SET similarity = 1.0
  }
  ELSEIF @left_deg = 0 OR @right_deg = 0 THEN {
    SET similarity = 0.0
  }
  ELSE {
    SET similarity = @dot_val / sqrt(@left_norm_sq * @right_norm_sq)
  }

  RETURN
    left_id AS query_left_id,
    right_id AS query_right_id,
    @left_deg AS left_degree,
    @right_deg AS right_degree,
    @common_cnt AS common_neighbor_count,
    @dot_val AS dot_product,
    similarity AS score
}
'''

3. Call your procedure

Compute cosine similarity between nodes 6 and 9.

USE #cosine_similarity_graph CALL cosine_similarity_score(6, 9) RETURN query_left_id, query_right_id, left_degree, right_degree, common_neighbor_count, dot_product, score

Returns:

+---------------+----------------+-------------+--------------+-----------------------+-------------+---------------------+
| query_left_id | query_right_id | left_degree | right_degree | common_neighbor_count | dot_product | score               |
+---------------+----------------+-------------+--------------+-----------------------+-------------+---------------------+
| 6             | 9              | 7           | 7            | 3                     | 3.0         | 0.42857142857142855 |
+---------------+----------------+-------------+--------------+-----------------------+-------------+---------------------+
Save results to a file or graph

To save the returned results as CSV files or write them to a graph, see EXPORT. Match the exported fields to the returned columns and target properties.