UltipaDocs
Try Playground
  • Introduction
  • Managing HDC Graphs
  • Managing Distributed Projections
  • Installing Algorithms
  • Running Algorithms
    • Degree Centrality
    • Closeness Centrality
    • Harmonic Centrality
    • Graph Centrality
    • Betweenness Centrality
    • Eigenvector Centrality
    • Katz Centrality
    • CELF
    • PageRank
    • ArticleRank
    • TextRank
    • HITS
    • SybilRank
    • Jaccard Similarity
    • Overlap Similarity
    • Cosine Similarity
    • Pearson Correlation Coefficient
    • Euclidean Distance
    • K-Hop All
    • Bipartite Graph
    • HyperANF
    • Connected Component
    • Triangle Counting
    • Induced Subgraph
    • k-Core
    • k-Truss
    • p-Cohesion
    • k-Edge Connected Components
    • Local Clustering Coefficient
    • Topological Sort
    • Schema Overview
    • Dijkstra's Single-Source Shortest Path
    • Delta-Stepping Single-Source Shortest Path
    • Shortest Path Faster Algorithm (SPFA)
    • Minimum Spanning Tree
    • Breadth-First Search (BFS)
    • Depth-First Search (DFS)
    • Adamic-Adar Index
    • Common Neighbors
    • Preferential Attachment
    • Resource Allocation
    • Total Neighbors
    • Louvain
    • Leiden
    • Label Propagation
    • HANP
    • k-Means
    • kNN (k-Nearest Neighbors)
    • K-1 Coloring
    • Conductance
      • Random Walk
      • Node2Vec Walk
      • Node2Vec
      • Struc2Vec Walk
      • Struc2Vec
      • LINE
      • Fast Random Projection
      • Summary of Graph Embedding
      • Gradient Descent
      • Backpropagation
      • Skip-gram
      • Skip-gram Optimization
  1. Docs
  2. /
  3. Graph Analytics & Algorithms
  4. /
  5. Centrality

CELF

HDC

Overview

The CELF (Cost Effective Lazy Forward) algorithm selects seed nodes in a network to act as propagation sources and maximize the number of influenced nodes. This is known as Influence Maximization (IM), where 'influence' represents anything that can be spread across the network, such as contamination, information, disease, etc.

CELF was proposed by Jure Leskovec et al. in 2007, it improves the traditional Greedy algorithm based on the IC model by taking advantage of the submodularity. It only calculates the spread score for all nodes only at the initial stage and does not recalculate for all nodes afterwards, hence cost-effective.

Related materials of the algorithm:

  • J. Leskovec, A. Krause, C. Guestrin, C. Faloutsos, J. VanBriesen, N. Glance, Cost-effective Outbreak Detection in Networks (2007)
  • D. Kempe, J. Kleinberg, E. Tardos, Maximizing the Spread of Influence through a Social Network (2003)

A typical application of the algorithm is to prevent epidemic outbreak by selecting a small group of people to monitor, so that any disease can be detected in an early stage.

Concepts

Spread Function - Independent Cascade

This algorithm uses the Independent Cascade (IC) model to simulate influence propagation in the network. IC is a probabilistic model, it starts with a set of active seed nodes, and in step k:

  • For each node that becomes active in step k-1, it has a single chance to activate each inactive outgoing neighbor with a success probability.
  • The process runs until no more activations are possible.

The spread of a given seed set is measured by the number of active nodes in the graph at the end of the process. This process is repeated many times (using Monte Carlo simulations), and the average spread is calculated.

Submodularity

The spread function IC() is called submodular as the marginal gain of a single node v is diminishing as the seed set S grows:

where the seed set |Sk+1| > |Sk|, S ∪ {v} means to add node v into the seed set.

Submodularity of the spread function is the key property exploited by CELF. CELF significantly improves the traditional Greedy algorithm that is used to solve the influence maximization problem, it runs a lot faster while achieving near optimal results.

Lazy Forward

At initialization, CELF, like the Greedy algorithm, computes the spread for each node and stores them in a list sorted by descending spread. As the seed set is empty now, the spread for each node can be viewed as its initial marginal gain.

In the first iteration, the top node is moved from the list to the seed set.

In the next iteration, only the marginal gain of the current top-ranked node is recalculated. After sorting, if that node remains at top, move it to the seed set; if not, repeat the process for the new top node.

Unlike Greedy, CELF avoids calculating marginal gain for all the rest nodes in each iteration, this is where the submodularity of the spread function is considered - the marginal gain of every node in this round is always lower than the previous round. So if the top node remains at top, we can put it into the seed set directly without calculating for other nodes.

The algorithm terminates when the seed set reaches the specified size.

Example Graph

Run the following statements on an empty graph to define its structure and insert data:

ALTER GRAPH CURRENT_GRAPH ADD NODE {
  account ({createdOn datetime})
};
ALTER GRAPH CURRENT_GRAPH ADD EDGE {
  follow ()-[]->()
};
INSERT (A:account {_id:"A", createdOn: "2016-12-3"}),
       (B:account {_id:"B", createdOn:"2022-1-30"}),
       (C:account {_id:"C", createdOn: "2019-11-8"}),
       (D:account {_id:"D", createdOn: "2019-1-16"}),
       (E:account {_id:"E", createdOn: "2016-3-4"}),
       (F:account {_id:"F", createdOn: "2019-11-10"}),
       (G:account {_id:"G", createdOn: "2019-7-26"}),
       (H:account {_id:"H", createdOn: "2016-7-11"}),
       (I:account {_id:"I", createdOn: "2018-12-13"}),
       (J:account {_id:"J", createdOn: "2018-3-21"}),
       (A)-[:follow]->(B),
       (A)-[:follow]->(G),
       (B)-[:follow]->(F),
       (C)-[:follow]->(B),
       (C)-[:follow]->(J),
       (D)-[:follow]->(J),
       (E)-[:follow]->(A),
       (F)-[:follow]->(C),
       (F)-[:follow]->(G),
       (G)-[:follow]->(H),
       (H)-[:follow]->(C),
       (H)-[:follow]->(E),
       (H)-[:follow]->(J),
       (I)-[:follow]->(B);

Creating HDC Graph

To load the entire graph to the HDC server hdc-server-1 as my_hdc_graph:

CREATE HDC GRAPH my_hdc_graph ON "hdc-server-1" OPTIONS {
  nodes: {"*": ["*"]},
  edges: {"*": ["*"]},
  direction: "undirected",
  load_id: true,
  update: "static"
}

Parameters

Algorithm name: celf

Name
Type
Spec
Default
Optional
Description
seedSetSizeInteger>01YesThe size of the seed set.
monteCarloSimulationsInteger>01000YesThe number of Monte Carlo simulations.
propagationProbability Float(0,1)0.1YesThe probability that a node with activation capability successfully activates each of its outgoing neighbors in a given round.
return_id_uuidStringuuid, id, bothuuidYesIncludes _uuid, _id, or both values to represent nodes in the results.

File Writeback

algo(celf).params({
  projection: "my_hdc_graph",
  return_id_uuid: "id",
  seedSetSize: 3,
  monteCarloSimulations: 1000,
  propagationProbability: 0.5
}).write({
  file: {
    filename: "seeds"
  }
})

Result:

File: seeds
_id,spread
H,3.613
I,1.646
A,1.34

Full Return

exec{
  algo(celf).params({
    return_id_uuid: "id",    
    seedSetSize: 2,
    monteCarloSimulations: 1000,
    propagationProbability: 0.6
  }) as seeds
  return seeds
} on my_hdc_graph

Result:

_idspread
H4.504
I1.678

Stream Return

exec{
  algo(celf).params({
    return_id_uuid: "id",
    seedSetSize: 3,
    monteCarloSimulations: 1000,
    propagationProbability: 0.6 
  }).stream() as seeds
  find().nodes({_id == seeds._id}) as nodes
  return nodes._id, nodes.createdOn, seeds.spread
} on my_hdc_graph

Result:

nodes._idnodes.createdOnseeds.spread
H2016-07-11 00:00:004.504
I2018-12-13 00:00:001.678
A2016-12-03 00:00:001.126