def testChangeInQSlow(self): self.logger.info("BEGIN") n0 = Node(clusterId="c1", nodeId=0) n1 = Node(clusterId="c1", nodeId=1) n3 = Node(clusterId="c1", nodeId=3) e1 = Edge(weight=1.0, srcId=0, targetId=1) n0._addEdge(e1) e2 = Edge(weight=1.0, srcId=0, targetId=2) n0._addEdge(e2) e3 = Edge(weight=1.0, srcId=0, targetId=3) n0._addEdge(e3) e4 = Edge(weight=1.0, srcId=1, targetId=0) n1._addEdge(e4) e5 = Edge(weight=1.0, srcId=3, targetId=0) n3._addEdge(e5) cluster1 = Cluster(clusterId="1", nodeList=[n0, n1, n3]) n2 = Node(clusterId="c2", nodeId=2) e6 = Edge(weight=1.0, srcId=2, targetId=0) n2._addEdge(e6) n4 = Node(clusterId="c2", nodeId=4) n5 = Node(clusterId="c2", nodeId=5) e7 = Edge(weight=1.0, srcId=4, targetId=5) n4._addEdge(e7) e8 = Edge(weight=1.0, srcId=5, targetId=4) n5._addEdge(e8) e9 = Edge(weight=1.0, srcId=4, targetId=2) n4._addEdge(e9) e10 = Edge(weight=1.0, srcId=2, targetId=4) n2._addEdge(e10) cluster2 = Cluster(clusterId="2", nodeList=[n2, n4, n5]) louvain1 = Louvain("changeInQ1", [cluster1, cluster2]) # calculate modularity of original graph self.logger.info("louvain1._Q:{}".format(louvain1._Q)) self.assertEqual(louvain1._Q, 0.5599999999999999) # move node 2 from cluster 2 to cluster 1 n2._clusterId = "c1" cluster1 = Cluster(clusterId="1", nodeList=[n0, n1, n2, n3]) cluster2 = Cluster(clusterId="2", nodeList=[n4, n5]) # calculate modularity louvain2 = Louvain("changeInQ2", [cluster1, cluster2]) self.logger.info("louvain2._Q:{}".format(louvain2._Q)) self.assertEqual(louvain2._Q, 0.5199999999999999) self.logger.info("change in modularity:{}".format(louvain1._Q - louvain2._Q))
def testQ(self): self.logger.info("BEGIN") # test modularity calculation ret = self.createSimpleGraph() clusterList = ret[1] self.logger.info("clusterList:\n{}".format(clusterList)) level0 = Louvain("testQ", clusterList) self.assertEqual(5, level0._getM()) self.logger.info("level0._Q:{}".format(level0._Q)) self.assertAlmostEqual(level0._Q, 0.44) self.logger.info("END\n")
def testGetClusterAssigments(self): self.logger.info("BEGIN") # build lovain level tree listOfEdges = [(0, 1), (1, 0), (0, 2), (2, 0), (1, 2), (2, 1), (0, 3), (0, 6), (0, 7), (3, 4), (4, 3), (3, 5), (5, 3), (3, 0), (6, 7), (7, 6), (6, 8), (8, 6), (6, 9), (9, 6), (8, 9), (9, 8), (9, 7), (7, 9), (6, 0), (7, 0)] listOfWeight = [1 for i in listOfEdges] # build out init graph and calculate Q louvainLevel0 = Louvain.buildGraph("level0", listOfEdges, listOfWeight) louvainLevel0._calculateQ() # run phase I: find best cluster assignments numRows = 10 # number of nodes louvainLevel0._phaseI(numRows, isLouvainInit=True) ll_0_ClusterAssigments = louvainLevel0.getClusterAssigments() self.logger.info( "level0 cluster assignments:\n{}".format(ll_0_ClusterAssigments)) # create next level and run phaseII # phase II consolidates clusters found in previous level louvainLevel1 = Louvain.buildLouvain("level1", louvainLevel0) louvainLevel1._phaseII() louvainLevel1._calculateQ() # lets assume this is the top level. louvainLevel1._phaseI(numRows) ll_1_ClusterAssigments = louvainLevel1.getClusterAssigments() self.logger.info( "level1 cluster assignments:\n{}".format(ll_1_ClusterAssigments)) self.logger.info( "**************** check for side effects output should be same as above" ) ll_0_ClusterAssigments = louvainLevel0.getClusterAssigments() # self.assertEqual(ll_0_ClusterAssigments, {5: [0, 1, 2, 3, 4, 5], 9: [9, 6, 7, 8]}) # this looks possible but not what I expected self.assertEqual(ll_0_ClusterAssigments, { 5: [9, 8], 9: [6, 7, 0, 1, 2, 3, 4, 5] }) ll_1_ClusterAssigments = louvainLevel1.getClusterAssigments() self.assertEqual(ll_1_ClusterAssigments, {9: [9, 8, 6, 7, 0, 1, 2, 3, 4, 5]}) self.logger.info("END\n")
def testSimplePhaseI(self): self.logger.info("BEGIN") # create a trival graph. listOfEdges = [(0,1), (1,2)] listOfWeight = [1 for i in listOfEdges] louvainLevel0 = Louvain.buildGraph("trival graph", listOfEdges, listOfWeight) louvainLevel0._calculateQ() numRows = 3 # number of nodes louvainLevel0._phaseI(numRows, isLouvainInit=True) for clusterId, cluster in louvainLevel0._clusters.items(): print() self.logger.info("cluserId:{}".format(clusterId)) self.logger.info(cluster) expected = { 0 : {'clusterId':0, 'numNodes':0, 'weightsInsideCluster':0, 'totalWeight':0}, 1 : {'clusterId':1, 'numNodes':3, 'weightsInsideCluster':4, 'totalWeight':4}, 2 : {'clusterId':2, 'numNodes':0, 'weightsInsideCluster':0, 'totalWeight':0} } self.checkClusters(expected, louvainLevel0._clusters) self.assertEqual(louvainLevel0._Q, 0.5) self.logger.info("END\n")
def testIGraphModularity(self): self.logger.info("BEGIN") #g.community_multilevel() g = self.createSimpleIGraph() # modularity membership is a list with length = number of nodes # the value in the list corresponds to the cluster the node is ml = [i for i in range(g.vcount())] self.logger.info("membership:{}".format(ml)) expectedModularity = g.modularity(ml) self.logger.info("iGraph Modularity:{}".format(expectedModularity)) self.logger.warning( "iGraph Modularity can not be used to test bootstrap") self.logger.warning( "the cluster only have a single node. no edge is inside how come modularity is not 0" ) # test out code listOfEdges = [e.tuple for e in g.es] self.logger.info("listOfEdges:\n{}".format(listOfEdges)) listOfWeight = list(g.es['weight']) #[e['weights'] for e in g.es] self.logger.info("listOfWeight:\n{}".format(listOfWeight)) # louvainLevel0 = Louvain(None) # louvainLevel0.bootStrapInit(listOfEdges, listOfWeight) louvainLevel0 = Louvain.buildGraph("testBootStrapModularity", listOfEdges, listOfWeight) self.logger.info("Q:{}".format(louvainLevel0._Q)) self.logger.info("END\n")
def testAdata(self): ''' The real deal ''' self.logger.info("BEGIN") anndata = sc.read("../PBMC.merged.h5ad") xxx = anndata.uns['neighbors']['connectivities'] # anndata.uns['neighbors']['connectivities'] csr_matrix # shape <class 'tuple'>: (15476, 15476) # # adata.obs['louvain'] # Series: index # data_3p-AAACCTGAGCATCATC-0 9 # data_3p-AAACCTGAGCTAGTGG-0 5 # <class 'tuple'>: (15476,) #knn takes about 3 or 4 min # run our implementation of nearest neighboors and update anndata # todo try running with out knng maybe adata has values already save time KnnG(anndata, n_neighbors=12, runPCA=True, nPC=50) self.logger.info("begin Louvain.runWithAdata") start = timer() root = Louvain.runWithAdata(anndata) end = timer() self.logger.info("Louvain.runWithAdata execution time:{}"\ .format(timedelta(seconds=end-start))) self.logger.info("END\n")
def testChangeInModulartiyTrivalGraph(self): self.logger.info("BEGIN") # create a trival graph. listOfEdges = [(0, 1), (1, 2)] listOfWeight = [1 for i in listOfEdges] louvainLevel0 = Louvain.buildGraph("trival graph", listOfEdges, listOfWeight) louvainLevel0._calculateQ() self.logger.info("louvainLevel0:{}".format(louvainLevel0)) # make sure graph is set u as expected for nid, node in louvainLevel0._nodeLookup.items(): for eid, edge in node._edgesDict.items(): self.logger.info(edge) print() # check modularity before move beforeMoveQ = louvainLevel0._Q self.assertEqual(beforeMoveQ, 0.0) n1 = louvainLevel0._nodeLookup[1] fromCluster = louvainLevel0._clusters[1] targetCluster = louvainLevel0._clusters[2] predictedChangeInQ = louvainLevel0.modularityGainIfMove( fromCluster, targetCluster, n1) self.logger.info("predicted changeInQ:{}".format(predictedChangeInQ)) self.assertAlmostEqual(predictedChangeInQ, 0.25) # move fromCluster.moveNode(targetCluster, n1, louvainLevel0._nodeLookup, isLouvainInit=True) # calculate Q louvainLevel0._calculateQ() afterMoveQ = louvainLevel0._Q self.assertAlmostEqual(afterMoveQ, 0.25) expectedChangeInQ = afterMoveQ - beforeMoveQ self.logger.info("expectedChangeInQ:{} afterMoveQ:{} before:{}"\ .format(expectedChangeInQ, afterMoveQ, beforeMoveQ)) self.logger.info("predicted changeInQ:{}".format(predictedChangeInQ)) self.logger.info("modularityGainIfMove:{} expected:{}"\ .format(predictedChangeInQ, expectedChangeInQ)) self.assertEqual(predictedChangeInQ, expectedChangeInQ) self.logger.info("END\n")
def testRun(self): self.logger.info("BEGIN") # build lovain level tree listOfEdges = [(0, 1), (1, 0), (0, 2), (2, 0), (1, 2), (2, 1), (0, 3), (0, 6), (0, 7), (3, 4), (4, 3), (3, 5), (5, 3), (3, 0), (6, 7), (7, 6), (6, 8), (8, 6), (6, 9), (9, 6), (8, 9), (9, 8), (9, 7), (7, 9), (6, 0), (7, 0)] listOfWeight = [1 for i in listOfEdges] numRows = 10 # number of nodes root = Louvain.run(listOfEdges, listOfWeight, numRows) rootClusterAssigments = root.getClusterAssigments() self.logger.info("louvainId: {} root cluster assigments:\n{}".format( root._louvainId, rootClusterAssigments)) self.assertEqual(rootClusterAssigments, {9: [9, 8, 6, 7, 0, 1, 2, 3, 4, 5]})
def testPhaseI(self): self.logger.info("BEGIN") listOfEdges = [(0,1), (1,0), (0,2), (2,0), (0,3), (3,0), (1,2), (2,1), (3,4), (4,3) ] listOfWeight = [1 for i in listOfEdges] louvainLevel0 = Louvain.buildGraph("testPhaseI graph", listOfEdges, listOfWeight) louvainLevel0._calculateQ() numRows = 5 # number of nodes louvainLevel0._phaseI(numRows, isLouvainInit=True) for clusterId, cluster in louvainLevel0._clusters.items(): print('') self.logger.info("cluserId:{}".format(clusterId)) self.logger.info(cluster) expected = { 0 : {'clusterId':0, 'numNodes':0, 'weightsInsideCluster':0, 'totalWeight':0}, 1 : {'clusterId':1, 'numNodes':0, 'weightsInsideCluster':0, 'totalWeight':0}, 2 : {'clusterId':2, 'numNodes':0, 'weightsInsideCluster':0, 'totalWeight':0}, 3 : {'clusterId':3, 'numNodes':3, 'weightsInsideCluster':8, 'totalWeight':7}, 4 : {'clusterId':4, 'numNodes':2, 'weightsInsideCluster':2, 'totalWeight':3} } self.checkClusters(expected, louvainLevel0._clusters) c3 = louvainLevel0._clusters[3] for n in c3._nodeList: self.logger.info("clusterId:{}, nodeId:{}".format(c3._clusterId, n._nodeId)) print('') c4 = louvainLevel0._clusters[4] for n in c4._nodeList: self.logger.info("clusterId:{}, nodeId:{}".format(c4._clusterId, n._nodeId)) expectedNodesInCluster = { 3: [0,1,2], 4: [3,4] } for clusterId in expectedNodesInCluster.keys(): c = louvainLevel0._clusters[clusterId] nodeIds = [n._nodeId for n in c._nodeList] self.assertEqual(sorted(nodeIds), sorted(expectedNodesInCluster[clusterId])) self.logger.info("END\n")
def main(): nodes = {} # dictionary of integers edges = [] # list of ((node, node), weight) def sort_graph(nodes, edges): # sort based on node ids nodes = list(nodes.keys()) nodes.sort() sorted_nodes = [] sorted_edges = [] i = 0 a = {} for node in nodes: sorted_nodes.append(i) a[node] = i i += 1 for edge in edges: sorted_edges.append(((a[edge[0][0]], a[edge[0][1]]), edge[1])) return (sorted_nodes, sorted_edges) f = open("data/wi2007.txt", 'r') lines = list(f) for line in lines: # each line in our dataset is in the format below # first_node second_node node_list = line.split() nodes[node_list[0]] = 1 nodes[node_list[1]] = 1 weight = 1 edges.append(((node_list[0], node_list[1]), weight)) sorted_nodes, sorted_edges = sort_graph(nodes, edges) print("Nodes: %d, Edges: %d" % (len(sorted_nodes), len(sorted_edges))) partition, modularity = Louvain(sorted_nodes, sorted_edges).apply_louvain()
def makeSampleGraph(): g = nx.Graph() g.add_edge("a", "b", weight=1.) g.add_edge("a", "c", weight=1.) g.add_edge("a", "d", weight=1.) g.add_edge("b", "d", weight=1.) g.add_edge("c", "d", weight=1.) g.add_edge("b", "g", weight=1.) g.add_edge("e", "f", weight=1.) g.add_edge("e", "g", weight=1.) g.add_edge("e", "h", weight=1.) g.add_edge("f", "h", weight=1.) g.add_edge("g", "h", weight=1.) return g if __name__ == "__main__": sample_graph = makeSampleGraph() louvain = Louvain() partition = louvain.getBestPartition(sample_graph) p = defaultdict(list) for node, com_id in partition.items(): p[com_id].append(node) for com, nodes in p.items(): print(com, nodes)
def createChangeQGraph(self): # create cluster 0 n0 = Node(clusterId="c0", nodeId=0) n1 = Node(clusterId="c0", nodeId=1) n2 = Node(clusterId="c0", nodeId=2) n3 = Node(clusterId="c1", nodeId=3) n4 = Node(clusterId="c1", nodeId=4) # 0 - 1 e0 = Edge(weight=1.0, srcId=0, targetId=1) n0._addEdge(e0) e1 = Edge(weight=1.0, srcId=1, targetId=0) n1._addEdge(e1) # 0 - 2 e2 = Edge(weight=1.0, srcId=0, targetId=2) n0._addEdge(e2) e3 = Edge(weight=1.0, srcId=2, targetId=0) n2._addEdge(e3) # 0 - 3 # edge between clusters e4 = Edge(weight=1.0, srcId=0, targetId=3) n0._addEdge(e4) e5 = Edge(weight=1.0, srcId=3, targetId=0) n3._addEdge(e5) cluster0 = Cluster(clusterId="c0", nodeList=[n0, n1, n2]) # creat cluster 1 #n5 = Node(clusterId="c1", nodeId=5) # 4 - 3 e6 = Edge(weight=1.0, srcId=4, targetId=3) n4._addEdge(e6) e7 = Edge(weight=1.0, srcId=3, targetId=4) n3._addEdge(e7) cluster1 = Cluster(clusterId="c1", nodeList=[n3, n4]) clusters = [cluster0, cluster1] e8 = Edge(weight=1.0, srcId=2, targetId=1) n2._addEdge(e8) e9 = Edge(weight=1.0, srcId=1, targetId=2) n1._addEdge(e9) edgeList = [e0, e1, e2, e3, e4, e5, e6, e7, e8, e9] i = 1 for e in edgeList: if i % 2: print() i += 1 self.logger.info(e) print() nodeList = [n0, n1, n2, n3, n4] graphNodesLookup = {n._nodeId: n for n in nodeList} for n in nodeList: # because we used _addEdge() instead of addEdges() # we need to make sure cache is set up n._initKiinCache(graphNodesLookup) self.logger.debug("") for n in nodeList: # for lazy evaluation to run n.getSumAdjWeights() n.getSumOfWeightsInsideCluster(n._clusterId, graphNodesLookup) self.logger.debug("node:{}".format(n)) self.logger.debug("") for c in clusters: # run lazy eval c.getSumOfWeights() c.getSumOfWeightsInsideCluster(graphNodesLookup) self.logger.info("cluster:{}".format(c)) level0 = Louvain("changeQGraph", [cluster0, cluster1]) ret = (level0, clusters, nodeList, edgeList, graphNodesLookup) self.logger.info("END\n") return (ret)
def createSimpleGraph(self): ''' creates two disjoint graphs, one is a triangle, the other is a pair of nodes connected by a single edge creates two cluster. one for each of the disjoint graphs all edge weights are 1 returns (level0Louvain, [cluster0, cluster1], [n0, n1, n2, n3, n4], [e0, e1, e2, e3, e4, e5, e6]) ''' self.logger.info("BEGIN") n0 = Node(clusterId="c0", nodeId=0) n1 = Node(clusterId="c0", nodeId=1) n2 = Node(clusterId="c0", nodeId=2) # undirected triangle graph e0 = Edge(weight=1.0, srcId=0, targetId=1) n0._addEdge(e0) e1 = Edge(weight=1.0, srcId=1, targetId=0) n1._addEdge(e1) e2 = Edge(weight=1.0, srcId=0, targetId=2) n0._addEdge(e2) e3 = Edge(weight=1.0, srcId=2, targetId=0) n2._addEdge(e3) e4 = Edge(weight=1.0, srcId=1, targetId=2) n1._addEdge(e4) e5 = Edge(weight=1.0, srcId=2, targetId=1) n2._addEdge(e5) # create second cluster graph n3 = Node(clusterId="c1", nodeId=3) e6 = Edge(weight=1.0, srcId=3, targetId=4) n3._addEdge(e6) n4 = Node(clusterId="c1", nodeId=4) e6 = Edge(weight=1.0, srcId=4, targetId=3) n4._addEdge(e6) # you can not move a node to a cluster if the node is not # connected to something in the cluster # there would not gain in Q # create and edge between a node in c0 and c2 ea = Edge(weight=1.0, srcId=n0._nodeId, targetId=n3._nodeId) eb = Edge(weight=1.0, srcId=n3._nodeId, targetId=n0._nodeId) n0._addEdge(ea) n3._addEdge(eb) nodeList = [n0, n1, n2, n3, n4] graphNodesLookup = {n._nodeId: n for n in nodeList} # create clusters cluster0 = Cluster(clusterId="c0", nodeList=[n0, n1, n2]) cluster1 = Cluster(clusterId="c1", nodeList=[n3, n4]) clusters = [cluster0, cluster1] # self.createSimpleGraphStage2Init(nodeList, clusters, graphNodesLookup) level0 = Louvain("simple", [cluster0, cluster1]) self.logger.info("END\n") # for n in nodeList: # # because we used _addEdge() instead of addEdges() # # we need to make sure cache is set up # n._initKiinCache(graphNodesLookup) ret = (level0, clusters, nodeList, [e0, e1, e2, e3, e4, e5, e6], graphNodesLookup) return (ret)
def testNode(self): self.logger.info("BEGIN") n0 = Node(clusterId="c0", nodeId=0) n1 = Node(clusterId="c0", nodeId=1) n2 = Node(clusterId="c0", nodeId=2) # undirected triangle graph e0 = Edge(weight=1.0, srcId=0, targetId=1) n0._addEdge(e0) e1 = Edge(weight=1.0, srcId=1, targetId=0) n1._addEdge(e1) self.assertEqual(1, n0.getSumAdjWeights()) self.assertEqual(1, n1.getSumAdjWeights()) e2 = Edge(weight=1.0, srcId=0, targetId=2) n0._addEdge(e2) e3 = Edge(weight=1.0, srcId=2, targetId=0) n2._addEdge(e3) # test print functions self.logger.info("e3:{}".format(e3)) self.assertEqual(2, n0.getSumAdjWeights()) self.assertEqual(1, n2.getSumAdjWeights()) # test print functions self.logger.info("n2:{}".format(n2)) e4 = Edge(weight=1.0, srcId=1, targetId=2) n1._addEdge(e4) e5 = Edge(weight=1.0, srcId=2, targetId=1) n2._addEdge(e5) self.assertEqual(2, n1.getSumAdjWeights()) self.assertEqual(2, n2.getSumAdjWeights()) # create cluster0 cluster0 = Cluster(clusterId="c0", nodeList=[n0, n1, n2]) self.assertEqual(3, cluster0._getM()) # test print functions self.logger.info("cluster0:{}".format(cluster0)) # create disjoint graph n3 = Node(clusterId="c1", nodeId=3) e6 = Edge(weight=1.0, srcId=3, targetId=4) n3._addEdge(e6) n4 = Node(clusterId="c1", nodeId=4) e6 = Edge(weight=1.0, srcId=4, targetId=3) n4._addEdge(e6) cluster1 = Cluster(clusterId="c1", nodeList=[n3, n4]) self.assertEqual(1, cluster1._getM()) # test modularity calculation level0 = Louvain("testNode", [cluster0, cluster1]) self.assertEqual(4, level0._getM()) self.logger.info("level0._Q:{}".format(level0._Q)) self.assertEqual(level0._Q, 0.59375) # test self.logger.info("END\n")
def testPhaseII(self): self.logger.info("BEGIN") listOfEdges = [(0,1), (1,0), (0,2), (2,0), (1,2), (2,1), (0,3), (0,6), (0,7), (3,4), (4,3), (3,5), (5,3), (3,0), (6,7),(7,6), (6,8), (8,6), (6,9), (9,6), (8,9), (9,8), (9,7), (7,9), (6,0), (7,0) ] listOfWeight = [1 for i in listOfEdges] louvainLevel0 = Louvain.buildGraph("testPhaseII graph level0", listOfEdges, listOfWeight) louvainLevel0._calculateQ() numRows = 10 # the number of nodes louvainLevel0._phaseI(numRows, isLouvainInit=True) expectedAfterPhaseL0_I = { 0:{'custerId': 0, 'numNodes':0 , 'weightsInsideCluster': 0, 'totalWeight': 0}, 1:{'cluserId': 1, 'numNodes':0 , 'weightsInsideCluster': 0, 'totalWeight': 0}, 2:{'cluserId': 2, 'numNodes':0 , 'weightsInsideCluster': 0, 'totalWeight': 0}, 3:{'cluserId': 3, 'numNodes':0 , 'weightsInsideCluster': 0, 'totalWeight': 0}, 4:{'cluserId': 4, 'numNodes':0 , 'weightsInsideCluster': 0, 'totalWeight': 0}, 5:{'cluserId': 5, 'numNodes':6 , 'weightsInsideCluster':14, 'totalWeight':14}, 6:{'cluserId': 6, 'numNodes':0 , 'weightsInsideCluster': 0, 'totalWeight': 0}, 7:{'cluserId': 7, 'numNodes':0 , 'weightsInsideCluster': 0, 'totalWeight': 0}, 8:{'cluserId': 8, 'numNodes':0 , 'weightsInsideCluster': 0, 'totalWeight': 0}, 9:{'cluserId': 9, 'numNodes':4 , 'weightsInsideCluster':10, 'totalWeight': 12} } self.logger.info("TODO: empty clusters should be pruned, notice") self.checkClusters(expectedAfterPhaseL0_I, louvainLevel0._clusters) for cId in [5, 9]: nodeIdList = sorted([n._nodeId for n in louvainLevel0._clusters[cId]._nodeList]) self.logger.info("clusterId:{} nodeList[{}]".format(cId, nodeIdList)) # check phase II louvainLevel1 = Louvain.buildLouvain("testPhaseII graph level1", louvainLevel0) louvainLevel1._phaseII() print('') self.logger.info("************ check L1 phase II") for clusterId, cluster in louvainLevel1._clusters.items(): self.logger.info("clusterId:{} cluster:{}".format(clusterId,cluster)) expectedAfterPhaseL1_II = { 5 : {'cluster':5, 'numNodes':1, 'weightsInsideCluster':0, 'totalWeight':2}, 9 : {'cluster':9, 'numNodes':1, 'weightsInsideCluster':0, 'totalWeight':2}, } self.checkClusters(expectedAfterPhaseL1_II, louvainLevel1._clusters) # check the node caches are set up correctl for clusterId, cluster in louvainLevel1._clusters.items(): for node in cluster._nodeList: self.logger.info("clusterId:{} nodeId:{} _weightsInClusterDict:{}"\ .format(clusterId, node._nodeId, node._weightsInClusterDict)) self.logger.info("clusterId:{} nodeId:{} _nodesInClusterDict:{}"\ .format(clusterId, node._nodeId, node._nodesInClusterDict)) # test Louvain algo would run Phase I on louvainLevel2 # we have to calculate Q before phaseI louvainLevel1._calculateQ() numRows = 10 # number of nodes louvainLevel1._phaseI(numRows) print('') self.logger.info("************ check L1 after phase I") for clusterId, cluster in louvainLevel1._clusters.items(): self.logger.info("clusterId:{} cluster:{}".format(clusterId,cluster)) self.logger.info("END\n")
import numpy as np import os, sys import pdb from louvain import Louvain X = np.array([[0,1,1,0,0],[1,0,1,0,0],[1,1,0,0,0],[0,0,0,0,1],[0,0,0,1,0]]) louv = Louvain() cluster = louv.fit(X) print(cluster)
def testDJGraph(self): self.logger.info("BEGIN") listOfEdges = [(0, 1), (1, 0), (2, 3), (3, 2)] # all other test assume weights are 1. set to a big number # that will make it easy to spot bugs in summary stats. listOfWeight = [5, 5, 10, 10] numRows = 4 # number of nodes louvainLevel0 = Louvain.buildGraph("level 0", listOfEdges, listOfWeight) # check Q louvainLevel0._calculateQ() self.logger.info("after buildGraph() louvainLevel0._Q:{}".format( louvainLevel0._Q)) self.assertAlmostEqual(louvainLevel0._Q, 0) # check is initialization of graph correct print() for cluster in louvainLevel0._clusters.values(): self.logger.info("{}".format(cluster)) print() for node in louvainLevel0._nodeLookup.values(): self.logger.info("\nnode {}".format(node)) print() expectedNodeConfigDict = { 0: "clusterId:0 nodeId:0 numEdges:1 adjEdgeWeights:10 _weightsInClusterDict{1: 10} _edgesDict{1: srcId:0 targetId:1 weight:10}", 1: "clusterId:1 nodeId:1 numEdges:1 adjEdgeWeights:10 _weightsInClusterDict{0: 10} _edgesDict{0: srcId:1 targetId:0 weight:10}", 2: "clusterId:2 nodeId:2 numEdges:1 adjEdgeWeights:10 _weightsInClusterDict{3: 10} _edgesDict{3: srcId:2 targetId:3 weight:10}", 3: "nodeId:3 numEdges:1 adjEdgeWeights:10 _weightsInClusterDict{2: 10} _edgesDict{2: srcId:3 targetId:2 weight:10}" } # check kiin for node in louvainLevel0._nodeLookup.values(): self.logger.info("nodeId:{} _weightsInClusterDict:{}".format( node._nodeId, node._weightsInClusterDict)) # run phase I louvainLevel0._phaseI( numRows, isLouvainInit=True) # TODO: can probably get rid of isLouvainInit self.logger.info( "after phase I() louvainLevel0:\n{}".format(louvainLevel0)) l0Assignments = louvainLevel0.getClusterAssigments() self.logger.info( "l0Assigments cluster assignments:\n{}".format(l0Assignments)) # check Q louvainLevel0._calculateQ() self.logger.info("after phase I louvainLevel0._Q:{}".format( louvainLevel0._Q)) self.assertAlmostEqual(louvainLevel0._Q, 0.7222222222222221) # build next level louvainLevel1 = Louvain.buildLouvain("level 1 ", louvainLevel0) self.logger.info( "after buildLouvain louvainLevel1\n{}".format(louvainLevel1)) # phase II louvainLevel1._phaseII( isLouvainInit=False ) # TODO: can probably get rid of isLouvainInit) self.logger.info( "after phaseII() louvainLevel1 this log line looks funnny:\n{}". format(louvainLevel1)) l1Assignments = louvainLevel1.getClusterAssigments() self.logger.info( "louvainLevel1 cluster assignments:\n{}".format(l1Assignments)) self.logger.info("END\n")