Incremental, Data-Parallel Graph Clustering
Abstract
Community extraction has become a fundamental operation in numerous real world applications. We propose a simple modification to the traditional Louvain method [6] that is used for the detection of community structures in large networks. The modification is aimed to enable parallel and incremental processing of network structures, such that the algorithm can be applied in stream processing settings.
Declaration of Authorship
I, Isitha Subasinghe, declare that this thesis titled, ‘Incremental, Data-Parallel Graph Clustering’ and the work presented in it are my own. I confirm that:
-
The thesis comprises only my original work towards the ‘Masters of Information Technology’ except where indicated in the preface;
-
due acknowledgement has been made in the text to all other material used; and
-
the thesis is fewer than the maximum word limit in length, exclusive of tables, maps, bibliographies and appendices as approved by the Research Higher Degrees Committee.
Signed:
Date:
Preface
Acknowledgements
I would like to thank my supervisor, Dr. Shanika Karunasekera for her time, knowledge and help throughout the semester, I am thankful that I was able to have a looser idea of what my research project was, entering the semester and for the suggestions on what topics to avoid. I am also thankful for making the time for a small chat when I needed motivation and providing me more context as to what life in academia was like. I am also grateful for the suggestion to not explore how Differential Dataflow could be used for incremental processing of Conflict-free Replicated Data Types, while this would be an extremely interesting topic, it would also have been much more difficult and deserved more time and attention than the 3 months that I had. I am also grateful to Dr. Frank McSherry for the implementation of Differential Dataflow and answering my various questions regarding its usage although he had no reason to help me.
Chapter 1 Introduction
1.1 Introduction
Real-time processing of large networks and determining their community structures has a wide variety of applications such as finding clusters in social media networks, optimising resource allocation in real time data processing tasks and more. The typical number of new network edges produced on social media platforms now count in the millions while the size of the graphs themselves can be much higher. This explosion in size of networks over the recent years mean that traditional non-incremental graph clustering algorithms cannot be run when new nodes or edges are added and still yield timely information, which is crucial in extremely dynamic social networks. While there exists a large body of research concerning graph partitioning algorithms, unfortunately there has been little research as to how these algorithms could be adopted or used in an online setting. Additionally, the handful of existing literature concerning real time graph partitioning mostly limits itself to using simple, inexpensive heuristics. Incremental computation through techniques such as Differential Dataflow [19] could allow for more advanced and computationally demanding algorithms such as the Louvain [6] modularity optimisation algorithm to be used in online settings.
Contributions: The main contributions of this paper are:
-
•
Introduction of the viability of using the differential dataflow computational model for the purposes of graph processing.
-
•
Demonstrate how incremental computation could be used to significantly speedup traditionally non-incremental algorithms that perform lots of unnecessary work such as the Louvain modularity optimisation algorithm.
-
•
Demonstrate and explore the limitations of parallelising Louvain and provide potential mitigation strategies where appropriate.
1.2 Problem Statement and notation
Let be a graph such that represents the set of vertices and represents the set of edges from one vertex to another. It is important to note that this graph is also undirected, while algorithms have been researched that apply modularity optimisation to directed graphs, we only concern ourselves with undirected graphs for the purposes of this paper. In this graph we allow for edges that connect a vertex to itself and we define this as a “self-loop”, however, multi-edges are prohibited and in the case where the dataset contains multi-edges, these must be first agglomerated into a single edge by simply adding the costs in each multi-edge. A community within a graph represents a set of vertices (possibly empty) such that the edges of these vertices display strong density. In practice however, we only concern ourselves with partitioning the vertex set into some number of disjoint non-empty communities. We will use as notation to indicate the community of a given vertex . We will define the adjacency matrix that defines our graph through , that is represents the weight from vertex to . Let denote the weighted degree of a given vertex , that is and finally we define to be the summation of all the edges present in the graph of interest, that is , note we half the weight as a result of the doubling of weights present when an undirected graph is represented as an adjacency matrix. Finally we can now define modularity as . Note that the is simply the Kronecker delta function.
1.3 Motivation
1.3.1 Differential Dataflow
Differential Dataflow [19] is an incremental computational model that has shown promise in a variety of graph processing tasks. In their paper, they demonstrated that their computational model was able to solve graph algorithms such as PageRank, Strongly Connected Components with a significant increase in performance over a selection of baselines, the speedups ranged from 1.9x to 1899.6x. Given most greedy modularity optimisation methods require multiple iterations over non-changing, already calculated vertices, it therefore makes sense to warrant an investigation on how Differential Dataflow could be used to reduce the cost of these iterations, additionally when we consider a dynamically changing graph we note that the increase in possible community swaps do not immediately increase with respect to the number of vertices but rather with respect to the degree of the inserted edge, although a swap as a result of this insertion may result in a domino effect of changes later on still.
Timely Dataflow
The open source implementation of Differential Dataflow was also a critical advantage when developing with Differential Dataflow, it provided easy access for distributed processing of data or in our case graphs. This ease of access for distributed computations is provided by the underlying dataflow computation engine called ‘Timely Dataflow’ first introduced in Naiad [20] which states that they provide a framework for low-latency cyclic dataflow computations. This engine ensured that our implementation could run on a cluster, a process or multiple processes with relatively little configuration.
1.3.2 Louvain
One criteria for choosing Louvain modularity optimisation as a candidate for our exploration of incremental, data-parallel graph clustering was simply as a result of its usefulness and widespread use in both academia and in industry. Louvain despite its pitfalls has remained the most commonly used graph clustering algorithm with various open source implementations in distributed dataflow processing frameworks such as Apache Spark 111See https://spark.apache.org/. The other criteria for choosing Louvain is simply due to the unnecessary work it performs when iterating over vertices, this provides a place of improvement in terms of performance, additionally as mentioned previously the advantages of incrementally performing Louvain may result in showing that the use of Louvain like methods used for agglomerative clustering could also be used in conjunction with Differential Dataflow.
Chapter 2 Background & Related Work
2.1 Graph Partitioning
The general problem of exact graph partitioning is known to be NP-complete [10], as a result of this severe restriction, the large body of research mostly focuses on approximate solutions to this problem over exact solutions, perhaps the best known one being the Kernighan-Lin algorithm [15]. Most graph clustering algorithms are based upon a few key concepts such as heuristics [15], agglomerative clustering [22, 7] and divisive clustering [21] although other techniques such as spectral clustering, k-means clustering, do exist [14, 4, 16]. The full literature on graph clustering algorithms is extensive and cannot be expressed concisely, however, a large amount of these algorithms have been studied and summarized in various surveys and studies [25, 1, 17]. The specific area concerning real-time graph clustering algorithms mostly consists of simple, computationally inexpensive, heuristic based methods [26] as mentioned previously, although some exotic methods have also been presented [28].
2.2 Incremental Computation
Incremental Computation has been an niche, unique field with relatively few published literature, most published research is based upon Umut Acar’s PhD thesis on "Self Adjusting Computations" [2], later developments such as Adapton [13] build upon this work. The idea behind this class of incremental computation is somewhat simple. Adapton for example performs general purpose incremental computations through building a computation graph, whenever data in this computation graph is changed, the child nodes in this computation graph are “dirtied”, whenever the result of this computation graph is requested by the application, these “dirty” nodes are recomputed. The fundamental difference between Differential Dataflow and Adapton is that Adapton is a general purpose incremental computation framework while Differential Dataflow is optimised for writing dataflow programs and the open source implementation of Differential Dataflow is built on a distributed low latency, cyclic dataflow programming layer called ‘Timely Dataflow’ [20].
2.3 Incremental View Maintenance
Incremental View Maintenance algorithms are of concern when discussing Differential Dataflow as they both aim to perform similar objectives. However, it should be noted that existing IVM techniques either perform too much work, maintain too much state or limit expressiveness. Take for consideration the classic incremental view maintainence algorithm by Gupta [12], this algorithm has some execution such that it over-estimates the number of invalidated tuples and performs a large amount of work to correct this error. Consider Nigam’s work on the extended PSN algorithm [23], this implementation stores tuples along with the full set of tuples used to derive it, this is obviously restrictive on large networks. If we take into account later developments such as DBToaster [3] that has spearheaded IVM algorithm research since 2009, it still suffers from the inability to perform IVM on iterative workloads.
2.4 Incremental Dataflow
While there have been several papers and software solutions to the problem of incrementally processing dataflow programs, they have been mostly simple modifications to existing dataflow systems. Incoop [5], builds upon Acar’s previous work on "Self Adjusting Computations" [2] to bring incremental processing to the MapReduce paradigm, on closer inspection of Incoop, one would notice that the suggested system is not much more than a simple caching and reuse of values. There are plenty of obvious drawbacks when using such a system, such as the inability to process iterative algorithms and the inability to maintain low latency.
2.5 Iterative Dataflow
Various attempts have been made to enhance the MapReduce [8] paradigm to support iterative workloads. The core principle here is to repeatedly apply MapReduce until a defined stopping criteria is met. Apart from the fact that this modification can not deal with incremental workloads, the implementations of iterative MapReduce introduce additional problems regarding data consistency after node failures. Consider for example the instance of a node failure in a MapReduce system where an iterative workload is in the process of being computed, data consistency issues may arise if the nodes execute on data at different iteration points after the restoration of the failed node, these issues can be addressed but introduce additional system complexity and latency.
2.6 Modularity Optimisation
Modularity optimisation was initially proposed by Newman [21], while algorithms like Louvain [6] exist to perform this task, it is important to note that exact modularity optimisation, like graph partitioning is NP-hard. It is because of this fundamental limitation that the algorithms that have been researched and presented in literature are only heuristic based methods that do not aim for optimal modularity optimisation but rather to simply get close to optimal results. Unfortunately, this reliance on a global metric for the computation of modularity is why parallel and dataflow implementations of modularity optimisations are hard to implement and why they suffer from convergence issues, deadlocks and negative gain scenarios.
2.7 The Louvain Algorithm
Louvain [6] is an agglomerative clustering algorithm based upon optimising modularity, the only objective of this algorithm is to optimise . The algorithm is initiated through allocating each node into its own unique community, then two phases are performed in iteration until a fixed point is reached or a defined modularity threshold is not met. The first phase is to simply iterate over the nodes and calculate the gain in modularity by moving the node into the communities of its neighbours, this change in modularity can be calculated through the equation:
. After the completion of this evaluation for a given vertex , a neighbour is chosen such that it represents the maximum modularity gain by moving into the communities of one of its neighbours, in the case where the modularity gain is zero, no community transfers take place. This step is repeated until a fixed point or a defined stopping criteria is met. It is important to note that Louvain does unfortunately evaluate modularity needlessly for certain nodes, contributing to a performance degradation. The second phase of this algorithm is to simply aggregate all nodes within the same community to a new node, as mentioned previously these two phases are repeated until a stopping criteria is met. It is important to note that Louvain [6] is able to offer significantly faster clustering with a runtime complexity of , this proved to be a clear advantage at the time where most algorithms were at least, where was some integer greater than 1. The algorithm however is not without faults, unfortunately one disadvantage of using the above mentioned aggregation step is that it is greedy and only has a limited view into how nodes will be clustered globally and throughout the various iterations, as a result of this it may not yield optimal modularity for the clustered graph. To demonstrate one failing of Louvain, consider the case where it may be beneficial to move a node from a cluster to a newly formed cluster, unfortunately due to the aggregation step, this can never happen. Unfortunately, Louvain has no known upper bound for the number of iterations that have to be performed in order to obtain convergence, this is why simpler methods such as meeting a modularity threshold or even simply capping the number of iterations to some fixed integer is typically used.
2.8 Limits of modularity
It is important to note that optimisation of modularity is not a guarantee of the detection of community structures, this is further explored in [9]. It has been shown that there even exists large values of measures of modularity in completely random graphs [11, 24], this obviously presents a major limitation in evaluating the true community structure through measuring modularity alone. Fortunato notes that this is as a result of random fluctuations in the distribution of edges, he states that these fluctuations determine concentrations of links in subsets of the graph which then falsely may appear to be community structures. As a result of these findings regarding modularity measurement, we cannot definitively state if a measurement of modularity corresponds to some community structure, however Fortunato has determined that a z-score derived from random rewiring of the graph could be used to obtain some probabilistic measure of community detection. To make matters worse, Fortunato has noted a fundemental problem at the core of modularity optimisation techniques and that is the fact that modularity optimisation has a resolution limit. To be more precise, if the maximum modularity produces communities of size or smaller, one cannot know if that particular community is a single community or in fact made up of smaller weakly linked communities. While there have been some attempts to address this issue, our implementation exclusively looked at the modularity definition present in the Louvain method [6], despite its inherent problems simply as a result of that definition of modularity being more commonly used.
Chapter 3 Method
3.1 Parallel Louvain
There has been relatively little work on parallelising Louvain, largely because the algorithm is non trivial to parallelise. Louvain is non trivial to parallelise as a result of the constantly changing parameters used in modularity evaluation, the usage of a lock to safeguard these parameters degrade the algorithm into a potentially slower sequential algorithm. Eventually consistent parameters being used in modularity evaluation still caries the same problems as a parallel version relying on stale data, although to a reduced level. An important parallel enabling modification to Louvain is discussed by Lu in [18], this implementation proves the problem of negative gain and addresses this concern in an effective manner. Importantly, it provides one easy step of parallelisation for us that does not cause negative gain and that is the vertex following heuristic they introduced. The work by Lu proved that not only were they able to obtain significant speedups over the serial algorithm, they were also able to produce communities with higher modularity.
3.1.1 Negative gain scenario
Although the Louvain modulairty algorithm always improves modularity in its serial implementation, this property is not maintained in parallel implementations. Unfortunately this means that it is possible for the parallel implementation to worsen the modularity of a graph and in this case steps must be made to prevent or mitigate this issue. This negative gain scenario present in Parallel Louvain is discussed and proven by Lu [18].
3.2 Dataflow Louvain
As far as the author is aware, this is the only literature present that addresses how the Louvain modularity optimisation algorithm could be modified such that it is capable of running as a dataflow program. The potential pitfalls with parallelising Louvain modularity optimisation is present with an even greater effect when considering a dataflow implementation of the algorithm. This is ultimately due to a simple but obvious limitation of most dataflow programming, dataflow programming pulls in its data and it is unable to push and propagate changes immediately unlike a parallel implementation which could in the very least place a bound on the staleness of the data. This is an area of concern when considering any modularity optimisation algorithm since it requires changing data to update the various parameters used in determining modularity such as , and other variables, this is as a result of these algorithms optimising for a global metric (), a better solution to parallelise graph clustering is to obtain some local metric to optimise, unfortunately, to the authors knowledge, no such method exists in published literature.
3.2.1 Non-termination
Unfortunately as a result of our computations being performed on stale data, it is possible to end up in a deadlock. This case is trivial to demonstrate, consider the simple case where there exists a graph of size two. Let’s state that when performing the version of Louvain without updates and relying on stale data there is a at both vertices, this means that both will perform a move to each others community. Following this move, it becomes clear that the next step could also simply be to repeat this swap, this means that some method is needed to prevent non-termination.
3.2.2 Counterfactual swapping
Given our usage of differential dataflow, we are able to mitigate some non-termination behaviour relatively cheaply. When we are about to make a decision to move to another community, we do this by examining the modularity gain of moving to the vertex of one of our edges. We can simply perform a join to determine where our neighbour would move, but more importantly we are then also able to evaluate the modularity gain for both of these operations and only perform the community transfer which maximises global modularity. While this may seem counter-intuitive since we limit the community transfers made, it mitigates both non-termination negative gain scenarios to a certain extent, unfortunately it does not however prevent non-termination nor negative-gain. The swapping technique above does not prevent non-termination. It is able to mitigate non-termination when considering two vertices however, when the number of vertices that perform cyclic swaps increase, it is obviously unable to account for such a scenario. Consider the case of a set of vertices where each vertex moves in a circular repeating pattern between communities, lets label these vertices as such that and . Consider the case where considers moving to , considers moving to and considers moving to simultaneously. In this case these vertices will see the global modularity as being , and respectively. The critical error here is obvious, these new values of are completely wrong and could potentially lead to non-termination, the real value of is in fact given by . Note how in the above formula a determination of one transfer directly impacts the values used in the computation of in other transfers, this is why Louvain is traditionally a sequential algorithm.
3.2.3 Recognising where deadlocks (non-termination) may occur
Ultimately deadlocks occur when vertices continuously move around its neighbours and are also able to move back to their initial community structure, following this revelation it becomes easy to recognise that this implies that deadlocks occur in connected components although further work should be attempted to prove if this is exactly the case. A simple yet naive approach to this problem could be to simply agglomerate connected components into a single structure, however this is not always a viable approach as there exists graphs with the number of nodes in communities being smaller than the number of nodes in connected components, as a result using this approach would simply break our community detection algorithm for some graphs. As a result of our graph dataset containing graphs such that the size of one of its strongly connected components was the same size of the graph itself, this was obviously not a practical option.
3.2.4 Implementation
Ultimately, our method is not dissimilar to the traditional Louvain [6] algorithm for modularity optimisation. The algorithm is expressed as a dataflow program, however the equation to measure both modularity and modularity gain remains the same as the traditional algorithm. One fundamental restriction that had to be made in our implementation however, is to order our nodes, this was quite simply achieved by assigning an integer to every node, this is ultimately due to implementation details of the open source library that was used to implement our algorithm. Like the initial Louvain algorithm, this modification is able to scale up to networks that measure in the millions of edges and is only limited by the memory it consumed. It is important to note that Differential Dataflow implements logic simply by running it until the output data converges to a fixed point. Our algorithm only computes the first phase and the Louvain algorithm is applied repeatedly until a fixed point is reached, modifications such as custom stopping criteria can still be made through simply applying the identity function to the various mappings to force convergence even when the stopping criteria is probabilistic. The algorithm works by first assigning a unique community to every node in the graph, that is, the number of nodes and communities are equal at the start of the first iteration. For each node in the graph, we consider the neighbours of and obtain the modularity gain () of moving it from its community and to the community of its neighbour, when performing this we need to keep track of the highest gain in modularity. After we have determined the highest gain in modularity, we perform the act of moving the node over to its neighbours community if , otherwise the node remains in its current community.
Justification for not providing agglomeration
As noted previously, we do not perform any agglomeration in our Louvain based method, the reasoning for this is simple, it does not make sense to agglomerate the clusters when using Louvain in a stream-like context. In addition to this, new nodes being added will not carry enough weight to form communities of their own and will simply join existing communities if they have already been agglomerated heavily, this would break our community detection capabilities. We have briefly touched on how agglomerative clustering could be provided in section 6.1.4.
3.2.5 Challenges
Rust
Rust as a language proved to be a challenge when writing our implementation of the Differential Dataflow based Louvain method, this boiled down to the natural complexity that arose from dealing with the borrow checker that enforced affine types in a distributed/parallel setting with shared memory. In order to comply with the borrow checker, unfortunately, extra work was performed, however we used the properties of Differential Dataflow to our advantage here to keep these costs negligible after the initial computation was performed.
Differential Dataflow
Unfortunately, the Rust implementation of Differential Dataflow is still quite undocumented and can be significantly difficult to understand due to the various mathematical abstractions it presents. This complexity contributed towards the difficulty regarding the evaluation of the performance characteristics of an algorithm of interest, while certain operations could be bounded by some algorithmic complexity in the worst case, at least theoretically, there was no realistically accessible method to evaluate the bounds of some such algorithm. In addition to these issues, there was missing documentation regarding the availability of some critical functionality such as the ‘explode’ operator. This operator is crucial for high performance Differential Dataflow code as it typically can be used to replace the computationally expensive ‘reduce’ operator. To understand how expensive the ‘reduce’ operator is, we must first note that the reductions are performed in non-differential (ordinary) rust, resulting on two critical drawbacks, we are unable to incremental compute and our parallelism is limited artificially to the number of keys. While this statement is true, it is important to note that the ‘explode’ operator is not as expressive as the ‘reduce’ operator and for some logic such as reduction based on sorted values the ‘explode’ operator simply is not applicable.
3.2.6 Limitations
Unfortunately as we have mentioned previously, there is no guarantee on convergence of our Louvain based method, in order to artificially induce convergence, we opted for a quick and easy method and that was to simply apply the identity function to a set of node, community pairs in the place where we would normally apply the clustering function. This is provides us with easy termination behaviour.
Chapter 4 Experiments
4.1 Experiment setup
There were multiple implementations of Louvain used in determining the effectiveness of the developed dataflow based Louvain algorithm. The first implementation was through Apache Spark, this implementation was based on an open source implementation of Louvain provided on Github with some modifications made to accommodate fair testing, as a result of us removing the agglomerative step in our Differential Dataflow implementation we did the same in the Apache Spark version.
4.1.1 Justification of Apache Spark based Louvain method for baseline
To our knowledge, there is no other method of combining incremental and iterative computations to dataflow computations with the exception of Differential Dataflow. Apache Spark and the Pregel based abstraction layer exposed via GraphX, isn’t completely at a disadvantage here however, since GraphX does provide incremental view maintenance capability along with other optimisations listed below in section 4.1.2.
4.1.2 Disadvantages impacting Differential Dataflow
Unfortunately, differential dataflow does not have an advantage in some tasks of dataflow computations, largely as a result of the of features present in Spark that Differential Dataflow lacks, at the end of the day, it is important to note that Differential Dataflow is an academia oriented library/framework where Apache Spark has been improved on over several years with major companies in industry using it for their ‘big-data’ processing needs. The lack of these features unfortunately negatively impacts the performance of Differential Dataflow, these potential areas of improvement for Differential Dataflow should be taken into account when comparing results. The list of features available in Apache Spark’s GraphX abstraction are listed below for the purposes of providing more perspective:
-
•
Index Reuse
-
•
Vertex Mirroring
-
•
Multicast join
-
•
Partial Materialisation
-
•
Incremental View Maintenance
-
•
Automatic Join Elimination
-
•
Variable Integer Encoding
More such optimisations and details regarding what these optimisation enable in GraphX are presented in extensive detail in [27]. Note that some of the above optimisations will not necessarily improve performance with Differential Dataflow, for example the Incremental View Maintenance optimisation in GraphX.
4.1.3 Testing Environment
Testing Environment - Rust
-
•
CPU - AMD Ryzen™ 7 3700X @ 3.6-4.4GHz
-
•
#CPUs - 8
-
•
Memory - 32GB DDR4
-
•
Disk - Samsung 970 EVO Plus NVMe M.2 SSD
-
•
Compiler - Rust 1.57.0-nightly
Testing Environment - Spark
-
•
CPU - AMD Ryzen™ 7 3700X @ 3.6-4.4GHz
-
•
#CPUs - 8
-
•
Memory - 32GB DDR4
-
•
Disk - Samsung 970 EVO Plus NVMe M.2 SSD
-
•
Scala - 2.12.0
-
•
Spark - 3.0.2
-
•
Java - Amazon Corretto 1.8.0_320
4.1.4 Datasets
The datasets were obtained from the set of graph databases available from the Stanford large graph database collection 111See https://snap.stanford.edu/data/. These graphs varied in size and included fairly large datasets such as the Amazon product co-purchasing dataset.
| Dataset | Nodes | Edges | Average clustering coefficient | Nodes in largest SCC |
|---|---|---|---|---|
| AS-733 | 6474 | 13895 | 0.2522 | 6474 |
| Amazon | 334863 | 925872 | 0.3967 | 334863 |
| email-Eu-core | 1005 | 25571 | 0.3994 | 803 |
| Wikipedia-Crocodile | 11631 | 170918 | UNSPECIFIED | UNSPECIFIED |
| Wikipedia-Chameleon | 2277 | 31421 | UNSPECIFIED | UNSPECIFIED |
| Wikipedia-Squirrel | 5201 | 198493 | UNSPECIFIED | UNSPECIFIED |
| Malaria-HVR_3 | 36 | 418 | UNSPECIFIED | UNSPECIFIED |
4.1.5 Experimental Process
For both processes we used the maximum number of cores available (8). Although we did test on different number of cores, these did not reveal much insight and therefore were not explored in our results.
Batch Processing
In order to investigate the feasibility of a Differential Dataflow based Louvain method in the context of large batch processing jobs using the map reduce paradigm, we investigated how long it would take a Differential Dataflow based Louvain method to reach some modularity when compared to the previously mentioned Apache Spark based version.
Incremental Processing
In this stage we only consider Differential Dataflow, since GraphX is not capable of providing us with an incremental computational model. The test here is quite simple, we run one single iteration of the Louvain clustering algorithm on some graph and measure the time it takes to compute a modularity for that particular graph, then we perform a single edge insertion and we measure its computation time as well. We define the time to compute the entire graph as the ‘single iteration batch processing time’ while we define the incremental computation time as the ‘incremental adjustment time’.
Chapter 5 Results & Discussion
5.1 Results
5.1.1 Batch Processing of graphs
Here we explore the different results obtained for batch processing of graph data using Apache Spark and Differential Dataflow.
Apache Spark
| Dataset | Nodes | Edges | Time | Modularity |
|---|---|---|---|---|
| AS-733 | 6474 | 13895 | 18.331s | 0.478 |
| Amazon | 334863 | 925872 | 49.869s | 0.621 |
| email-Eu-core | 1005 | 12.655s | 12.656s | 0.412 |
| Wikipedia-Crocodile | 11631 | 170918 | 37.470s | 0.657 |
| Wikipedia-Chameleon | 2277 | 31421 | 13.582s | 0.663 |
| Wikipedia-Squirrel | 5201 | 198493 | 26.122s | 0.397 |
| Malaria-HVR_3 | 36 | 418 | 1.137s | 0.0713 |
Differential Dataflow
| Dataset | Nodes | Edges | Time | Modularity |
|---|---|---|---|---|
| AS-733 | 6474 | 13895 | 0.367s | 0.786 |
| Amazon | 334863 | 925872 | 16.230s | 0.421 |
| email-Eu-core | 1005 | 25571 | 0.378s | 0.727 |
| Wikipedia-Crocodile | 11631 | 170918 | 2.624s | 0.619 |
| Wikipedia-Chameleon | 2277 | 31421 | 2.051s | 0.675 |
| Wikipedia-Squirrel | 5201 | 198493 | 2.220s | 0.621 |
| Malaria-HVR_3 | 36 | 418 | 0.001076s | 0.986 |
5.1.2 Cost of Single Insert
We now would like to measure the cost of a single insert in an already clustered graph, we can simply measure this through evaluating the time taken for a computation to stabilise after an edge pair is inserted to an already clustered graph (to a single iteration). The given table shows the performance for the initial graph clustering and also the cost of a single insertion.
| Dataset | Nodes | Edges | Single Iteration Batch Processing time | Incremental Adjustment time |
|---|---|---|---|---|
| AS-733 | 6474 | 13895 | 0.0027s | 0.0019s |
| Amazon | 334863 | 925872 | 1.143s | 0.778s |
| email-Eu-core | 1005 | 25571 | 0.0023s | 0.000986s |
| Wikipedia-Crocodile | 11631 | 170918 | 0.163s | 0.093s |
| Wikipedia-Chameleon | 2277 | 31421 | 0.035s | 0.019s |
| Wikipedia-Squirrel | 5201 | 198493 | 0.196s | 0.092s |
| Malaria-HVR_3 | 36 | 418 | 0.001052s | 0.0001747s |
5.2 Discussion
As shown in table 5.1 and table 5.2, Differential Dataflow was able to obtain significant speedups over the Apache Spark based version, not only was it able to offer significant speedups, it was also somewhat better than the Apache Spark implementation when it came to the overall modularity as well. Ultimately, this demonstrated that the ability to avoid performing computations where possible through the use of Differential Dataflow will eventually lead to bigger performance gains for most graphs, this may not always be the case and that scenario is discussed in further detail in section 5.2.2.
5.2.1 Modularity
The usage of Differential Dataflow and to be more precise the result of parallelising Louvain in the manner described previously did not for the most part have a significant impact on the modularity value. Although Differential Dataflow did demonstrate a somewhat lower modularity value for the Amazon product co-purchasing network. One possible explanation for this is that these communities aren’t always well defined and can jump from categories quite easily, however, this still wouldn’t explain why the Apache Spark implementation was able to offer a near 50% increase in modularity. It is important to note still that the Differential Dataflow based method was still able to offer a better modularity for five out of the seven graph datasets, showing that a Louvain method based on Differential Dataflow is effective.
5.2.2 Graph Stability
From our results, it seems that there is a certain property of the graphs that seem to impact the overall stability of both the time to terminate and in some cases the modularity itself. Consider for example the AS-733, email-Eu-core and Malaria-HVR_3 datasets which stabilised and terminated competely by themselves without our non-termination prevention technique coming into play. In the case of email-Eu-core, it is not too dissimilar to Wikipedia-Chameleon, in this case we observe that Wikipedia-Chameleon takes about two seconds compared to the fast 378ms runtime of the email-Eu-core graph, while Wikipedia-Chameleon is a bigger dataset, it is not significantly bigger than email-Eu-core, this can be shown in more perspective through contrasting the runtime and size of the Wikipedia-Squirrel dataset with Wikipedia-Chameleon. It is difficult to make a claim regarding what property of a graph is responsible for the stability of the communities, however, one likely heuristic that could be used to determine the graph stability is the edge to node ratio, we would like to make the speculation that a higher edge to node ratio generally reduces the probability of an unstable graph community structure but further research is needed here to provide evidence for this conjecture.
5.2.3 Domino Effect
Unfortunately, one potential pitfall of using Differential Dataflow for the Louvain method is the degradation in performance when the advantages of using Differential Dataflow are not present and our implementation degrades to a slower version of the same algorithm due to us paying the runtime costs of Differential Dataflow. This occurs when there is a large domino effect due to a change in the classification of a vertex, simply put this change may induce another change which may induce another and so on. This is ultimately related to the Graph Stability mentioned in section 5.2.2. This is difficult to prevent as it is difficult to determine if these induced changes contributed to increasing the modularity of our graph in a meaningful way or not.
5.2.4 Usage in real-time systems
From the above results, a Differential Dataflow based Louvain method may be appropriate for some usage in real-time systems for some graph structures, but there may be some graph that has highly unstable community structures which would cause a Differential Dataflow based Louvain method to be far slower than ideal, perhaps even slower than a sequential non-incremental version. Further investigation here is warranted to investigate how to determine what exactly determines the stability properties of a graph’s community structure.
Chapter 6 Conclusion & Further Work
6.1 Future Work
6.1.1 Differential Dataflow
Unfortunately at this stage, we believe that Differential Dataflow is not completely ready yet to be used in general purpose incremental programs without willing to pay a significant software engineering cost as a result of the inherent complexity of using a hardly documented, research piece of software. An interesting approach to solving this problem could be perhaps to expose the ability to perform incremental computations at a higher abstraction layer, this is very much inline with the approach taken by the other ‘Big-Data’ processing frameworks such as Apache Spark. This hypothetical implementation also may gain an advantage due to its incremental computational model relying on a partial ordering of entries, although this should be explored in more detail, the advantage could be the ability to avoid implementing a variant of the Chandy-Lamport algorithm which is needed to ensure recovery from failures.
6.1.2 Differential Dataflow Operators
Unfortunately, even certain trivially incremental operators such as ‘max’ and ‘min’ are not available through the open source implementation, future work could examine how more operators could be added to Differential Dataflow in order to increase its expressive power.
6.1.3 Other Graph Clustering Methods
While we have demonstrated how Differential Dataflow could be used to implement Louvain modularity optimisation, we have not explored the efficacy of other graph clustering methods, it is likely worth the effort to explore how other graph clustering algorithms could be implemented in such a way that it is able to take advantage of incremental computations, it may be the case that some traditionally more costly algorithms end up being significantly cheaper when differential dataflow is used.
6.1.4 Incremental Hierarchical clustering
If we are able to generalise even more on the partial ordering of time implemented in differential dataflow, we could use this to provide movement of already agglomerated vertices between clusters, what this means is that there is potential for modularity greater than what Louvain would normally find. The change here would be to represent time as vector of length three, this is not too different from the existing implementation, the additional entry here would simply represent the number of times a given node has been agglomerated. When new nodes are added, we would be able to examine if a certain vertex belongs in a different community due to this change, when the answer to this question is yes, a certain amount of work would be performed to propagate these changes throughout the hierarchy, the important distinction is that when communities remain the same, this work would be avoided entirely.
6.1.5 Unifying “Self Adjusting Computations”
While “Self Adjusting Computations” are not directly usable for the computation of dataflow programs [19], there is potential for unifying “Self Adjusting Computations” for the purpose of incremental reductions. As mentioned previously the ‘reduce’ operator does not have any incremental properties due to the expressiveness of the operator, using “Self Adjusting Computations” here could prove to be a significant advantage in incrementally performing our reductions, this would reduce our max determination from to in the best case, where is the number of neighbours.
6.2 Conclusion
We have presented how the Louvain modularity optimisation algorithm could be implemented with Differential Dataflow and demonstrated its efficacy in performing incremental adjustments, we believe that this technique makes the act of incremental graph clustering via the Louvain method a viable candidate in some real time applications. Additionally, the implementation of Louvain on top of ‘Timely Dataflow’ through the Differential Dataflow library provides an excellent way to parallelise the method over multiple cores and even multiple machines.
References
- [1] (2018) Streaming graph partitioning: an experimental study. Proceedings of the VLDB Endowment 11 (11), pp. 1590–1603. Cited by: §2.1.
- [2] (2005) Self-adjusting computation. Carnegie Mellon University. Cited by: §2.2, §2.4.
- [3] (2012) DBToaster: higher-order delta processing for dynamic, frequently fresh views. External Links: 1207.0137 Cited by: §2.3.
- [4] (2008) Multiway spectral clustering with out-of-sample extensions through weighted kernel pca. IEEE transactions on pattern analysis and machine intelligence 32 (2), pp. 335–347. Cited by: §2.1.
- [5] (2011) Incoop: mapreduce for incremental computations. In Proceedings of the 2nd ACM Symposium on Cloud Computing, pp. 1–14. Cited by: §2.4.
- [6] (2008) Fast unfolding of communities in large networks. Journal of statistical mechanics: theory and experiment 2008 (10), pp. P10008. Cited by: §1.1, §2.6, §2.7, §2.8, §3.2.4, Incremental, Data-Parallel Graph Clustering.
- [7] (2004) Finding community structure in very large networks. Physical review E 70 (6), pp. 066111. Cited by: §2.1.
- [8] (2004) MapReduce: simplified data processing on large clusters. Cited by: §2.5.
- [9] (2010) Community detection in graphs. Physics reports 486 (3-5), pp. 75–174. Cited by: §2.8.
- [10] (1974) Some simplified np-complete problems. In Proceedings of the sixth annual ACM symposium on Theory of computing, pp. 47–63. Cited by: §2.1.
- [11] (2004) Modularity from fluctuations in random graphs and complex networks. Physical Review E 70 (2), pp. 025101. Cited by: §2.8.
- [12] (1993) Maintaining views incrementally. ACM SIGMOD Record 22 (2), pp. 157–166. Cited by: §2.3.
- [13] (2014-06) Adapton: composable, demand-driven incremental computation. SIGPLAN Not. 49 (6), pp. 156–166. External Links: ISSN 0362-1340, Link, Document Cited by: §2.2.
- [14] (2003) Natural communities in large linked networks. In Proceedings of the Ninth ACM SIGKDD International Conference on Knowledge Discovery and Data Mining, KDD ’03, New York, NY, USA, pp. 541–546. External Links: ISBN 1581137370, Link, Document Cited by: §2.1.
- [15] (1970) An efficient heuristic procedure for partitioning graphs. The Bell system technical journal 49 (2), pp. 291–307. Cited by: §2.1.
- [16] (2004) A flow-based method for improving the expansion or conductance of graph cuts. In International Conference on Integer Programming and Combinatorial Optimization, pp. 325–337. Cited by: §2.1.
- [17] (2010) Empirical comparison of algorithms for network community detection. In Proceedings of the 19th international conference on World wide web, pp. 631–640. Cited by: §2.1.
- [18] (2015) Parallel heuristics for scalable community detection. Parallel Computing 47, pp. 19–37. Cited by: §3.1.1, §3.1.
- [19] (2013) Differential dataflow.. In CIDR, Cited by: §1.1, §1.3.1, §6.1.5.
- [20] (2013) Naiad: a timely dataflow system. In Proceedings of the Twenty-Fourth ACM Symposium on Operating Systems Principles, pp. 439–455. Cited by: §1.3.1, §2.2.
- [21] (2004-02) Finding and evaluating community structure in networks. Physical Review E 69 (2). External Links: ISSN 1550-2376, Link, Document Cited by: §2.1, §2.6.
- [22] (2004-06) Fast algorithm for detecting community structure in networks. Physical Review E 69 (6). External Links: ISSN 1550-2376, Link, Document Cited by: §2.1.
- [23] (2012) Maintaining distributed logic programs incrementally. Computer Languages, Systems & Structures 38 (2), pp. 158–180. Cited by: §2.3.
- [24] (2006) Statistical mechanics of community detection. Physical review E 74 (1), pp. 016110. Cited by: §2.8.
- [25] (2007) Graph clustering. Computer science review 1 (1), pp. 27–64. Cited by: §2.1.
- [26] (2012) Streaming graph partitioning for large distributed graphs. In Proceedings of the 18th ACM SIGKDD international conference on Knowledge discovery and data mining, pp. 1222–1230. Cited by: §2.1.
- [27] (2018) Go with the flow: graphs, streaming and relational computations over distributed dataflow. University of California, Berkeley. Cited by: §4.1.2.
- [28] (2008) Fast online graph clustering via erdős–rényi mixture. Pattern recognition 41 (12), pp. 3592–3599. Cited by: §2.1.