#r "FSharp.FGL"
#r "FSharp.FGL.ArrayAdjacencyGraph"
open FSharp.FGL
open FSharp.FGL.ArrayAdjacencyGraph
open ArrayAdjacencyGraph.Algorithms
The louvain method for communty detection is a easy method to extract the community structure of large networks. It is based on the concept of modularity optimization.
The algorithm is divided into two phases that are repeated iteratively:
- Modularity optimization, in which every vertex is assigned its own community. After that, for each vertex its neighbours are used to calculate the gain of modularity by removing the vertex from its community and placing it in the community of a neighbour. The new commnuity for the vertex is the one with the biggest modularity gain. This is repeated until no furhter changes that increase the overall modularity can be done.
- Community aggregation, in which the communities found are aggregated in order to build a new, reduced network of communities.
These steps are repeated until no further increase of modularity is possible.
The first step of the tutorial is the creation of a graph that Louvain can analyse. In this case the graph was taken from wikipedia.
//Creating a list of labeled vertices
let vertexList : LVertex<int,string> list =
[
for i=0 to 13 do
(i),(sprintf "%i"i)
]
//Creating a list of labeled edges
let edgeList : LEdge<int,float> list =
[
0,1,1.; 0,2,1.; 1,2,1.; 1,3,1.;2,3,1.; 3,4,1.; 3,13,1.; 4,5,1.; 4,8,1.;
5,6,1.; 5,8,1.; 5,7,1.; 6,7,1.; 7,8,1.; 7,10,1.; 8,9,1.; 9,10,1.;
9,12,1.; 9,13,1.; 10,11,1.; 10,13,1.; 11,12,1.; 11,13,1.; 12,13,1.
]
//Creating a graph out of the two lists
let myGraph :ArrayAdjacencyGraph<int,string,float> =
ArrayAdjacencyGraph(vertexList,edgeList)
The application of the louvain algorithm on the example graph would look like this:
//Returns the graph with the louvain calculation on top of it
let myGraphLouvain : ArrayAdjacencyGraph<int,string*int,float> =
Louvain.Louvain.louvain myGraph 0.00001
The visualization of the graph is made possible by means of Cyjs.NET and looks like this.
The different colors each represent their own community.
No value returned by any evaluator
|
Multiple items
Namespace FSharp
--------------------
Namespace Microsoft.FSharp
Namespace FSharp.FGL
Namespace FSharp.FGL.ArrayAdjacencyGraph
Multiple items
Namespace FSharp.FGL.ArrayAdjacencyGraph
--------------------
Namespace ArrayAdjacencyGraph
--------------------
type ArrayAdjacencyGraph<'Vertex,'Label,'Edge (requires equality and equality)> =
private new : vertexEdges:Dictionary<'Vertex,LEdge<'Vertex,'Edge> []> * labels:Dictionary<'Vertex,'Label> -> ArrayAdjacencyGraph<'Vertex,'Label,'Edge> + 2 Überladungen
member AddEdge : LEdge<'Vertex,'Edge> -> ArrayAdjacencyGraph<'Vertex,'Label,'Edge>
member AddManyEdges : edgeArray:seq<LEdge<'Vertex,'Edge>> -> ArrayAdjacencyGraph<'Vertex,'Label,'Edge>
member AddManyVertices : vertices:LVertex<'Vertex,'Label> [] -> ArrayAdjacencyGraph<'Vertex,'Label,'Edge>
member AddVertex : LVertex<'Vertex,'Label> -> ArrayAdjacencyGraph<'Vertex,'Label,'Edge>
member private AdjacencyGraph : unit -> Dictionary<'Vertex,LEdge<'Vertex,'Edge> []>
member ConnectedEdgesEmpty : v:'Vertex -> bool
member ContainsEdge : edge:LEdge<'Vertex,'Edge> -> bool
member ContainsVertex : vertex:'Vertex -> bool
member Copy : unit -> ArrayAdjacencyGraph<'Vertex,'Label,'Edge>
...
--------------------
new : unit -> ArrayAdjacencyGraph<'Vertex,'Label,'Edge>
new : vertices:LVertex<'Vertex,'Label> list * edges:LEdge<'Vertex,'Edge> list -> ArrayAdjacencyGraph<'Vertex,'Label,'Edge>
Namespace ArrayAdjacencyGraph.Algorithms
val vertexList : LVertex<int,string> list
type LVertex<'Vertex,'Label> = 'Vertex * 'Label
Multiple items
val int : value:'T -> int (requires member op_Explicit)
--------------------
[<Struct>]
type int = int32
--------------------
type int<'Measure> =
int
Multiple items
val string : value:'T -> string
--------------------
type string = System.String
type 'T list = List<'T>
val i : int
val sprintf : format:Printf.StringFormat<'T> -> 'T
val edgeList : LEdge<int,float> list
type LEdge<'Vertex,'Edge> = 'Vertex * 'Vertex * 'Edge
Multiple items
val float : value:'T -> float (requires member op_Explicit)
--------------------
[<Struct>]
type float = System.Double
--------------------
type float<'Measure> =
float
val myGraph : ArrayAdjacencyGraph<int,string,float>
val myGraphLouvain : ArrayAdjacencyGraph<int,(string * int),float>
Namespace ArrayAdjacencyGraph.Algorithms.Louvain
Modul Louvain
aus ArrayAdjacencyGraph.Algorithms.Louvain
val louvain : graph:ArrayAdjacencyGraph<'Vertex,'Label,float> -> modularityIncreaseThreshold:float -> ArrayAdjacencyGraph<'Vertex,('Label * int),float> (requires equality)
Namespace Cyjs
Namespace Cyjs.NET
val toCyJS : g:ArrayAdjacencyGraph<int,(string * int),float> -> CyGraph.CyGraph
val g : ArrayAdjacencyGraph<int,(string * int),float>
val vertices : Elements.Node []
Modul Array
aus Microsoft.FSharp.Collections
val map2 : mapping:('T1 -> 'T2 -> 'U) -> array1:'T1 [] -> array2:'T2 [] -> 'U []
val vertex : int
val label : string * int
member ArrayAdjacencyGraph.GetVertices : unit -> 'Vertex []
member ArrayAdjacencyGraph.GetLabels : unit -> 'Label []
val map : mapping:('T -> 'U) -> array:'T [] -> 'U []
val id : int
val ogLabel : string
val newLabel : int
Modul Elements
aus Cyjs.NET
val node : id:string -> dataAttributes:CyParam.CyStyleParam list -> Elements.Node
Modul CyParam
aus Cyjs.NET
val label : v:'a -> CyParam.CyStyleParam
val color : v:'a -> CyParam.CyStyleParam
val edges : Elements.Edge list
Multiple items
Modul List
aus Microsoft.FSharp.Collections
--------------------
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list
interface IReadOnlyList<'T>
interface IReadOnlyCollection<'T>
interface IEnumerable
interface IEnumerable<'T>
member GetReverseIndex : rank:int * offset:int -> int
member GetSlice : startIndex:int option * endIndex:int option -> 'T list
static member Cons : head:'T * tail:'T list -> 'T list
member Head : 'T
member IsEmpty : bool
member Item : index:int -> 'T with get
...
val map : mapping:('T -> 'U) -> list:'T list -> 'U list
val v1 : int
val v2 : int
val weight : float
val edge : id:string -> sourceId:string -> targetId:string -> dataAttributes:CyParam.CyStyleParam list -> Elements.Edge
val weight : v:'a -> CyParam.CyStyleParam
Modul CyGraph
aus Cyjs.NET
val initEmpty : unit -> CytoscapeModel.Cytoscape
val withElements : elems:seq<CytoscapeModel.Element> -> cy:CyGraph.CyGraph -> CyGraph.CyGraph
val withStyle : selector:string -> cyStyles:seq<CyParam.CyStyleParam> -> cy:CyGraph.CyGraph -> CyGraph.CyGraph
val content : v:'a -> CyParam.CyStyleParam
Modul Text
aus Cyjs.NET.CyParam
Modul Outline
aus Cyjs.NET.CyParam.Text
Modul Background
aus Cyjs.NET.CyParam
val withSize : width:int * height:int -> cy:CyGraph.CyGraph -> CyGraph.CyGraph
val withLayout : ly:Layout -> cy:CyGraph.CyGraph -> CyGraph.CyGraph
Multiple items
Modul Layout
aus Cyjs.NET
--------------------
type Layout =
inherit DynamicObj
new : name:string -> Layout
member name : string
--------------------
new : name:string -> Layout
val initCose : applyOption:(Layout -> Layout) -> Layout
val id : x:'T -> 'T
Modul HTML
aus Cyjs.NET
val toEmbeddedHTML : cy:CytoscapeModel.Cytoscape -> string