Network Characteristics

要求及数据集:hw1.pdfCA-GrQc.txt

代码:

  1. ################################################################################
  2. # CS 224W (Fall 2019) - HW1
  3. # Starter code for Question 1
  4. # Last Updated: Sep 25, 2019
  5. ################################################################################
  6. import snap
  7. import numpy as np
  8. import matplotlib.pyplot as plt
  9. import random
  10. # Setup
  11. erdosRenyi = None
  12. smallWorld = None
  13. collabNet = None
  14. # Problem 1.1
  15. def genErdosRenyi(N=5242, E=14484):
  16. """
  17. :param - N: number of nodes
  18. :param - E: number of edges
  19. return type: snap.PUNGraph
  20. return: Erdos-Renyi graph with N nodes and E edges
  21. """
  22. ############################################################################
  23. # TODO: Your code here!
  24. Graph = snap.TUNGraph().New()
  25. for i in range(N):
  26. Graph.AddNode(i + 1)
  27. for i in range(E):
  28. a, b = random.randint(1, N), random.randint(1, N)
  29. while a == b:
  30. a, b = random.randint(1, N), random.randint(1, N)
  31. Graph.AddEdge(a, b)
  32. ############################################################################
  33. return Graph
  34. def genCircle(N=5242):
  35. """
  36. :param - N: number of nodes
  37. return type: snap.PUNGraph
  38. return: Circle graph with N nodes and N edges. Imagine the nodes form a
  39. circle and each node is connected to its two direct neighbors.
  40. """
  41. ############################################################################
  42. # TODO: Your code here!
  43. # Graph = snap.TUNGraph()
  44. Graph = snap.TUNGraph().New()
  45. for i in range(N):
  46. Graph.AddNode(i + 1)
  47. ############################################################################
  48. return Graph
  49. def connectNbrOfNbr(Graph, N=5242):
  50. """
  51. :param - Graph: snap.PUNGraph object representing a circle graph on N nodes
  52. :param - N: number of nodes
  53. return type: snap.PUNGraph
  54. return: Graph object with additional N edges added by connecting each node
  55. to the neighbors of its neighbors
  56. """
  57. ############################################################################
  58. # TODO: Your code here!
  59. for i in range(N - 2):
  60. if not i:
  61. Graph.AddEdge(i + 1, N)
  62. Graph.AddEdge(i + 1, N - 1)
  63. Graph.AddEdge(i + 2, N)
  64. Graph.AddEdge(N - 1, N)
  65. Graph.AddEdge(i + 1, i + 2)
  66. Graph.AddEdge(i + 1, i + 3)
  67. ############################################################################
  68. return Graph
  69. def connectRandomNodes(Graph, M=4000):
  70. """
  71. :param - Graph: snap.PUNGraph object representing an undirected graph
  72. :param - M: number of edges to be added
  73. return type: snap.PUNGraph
  74. return: Graph object with additional M edges added by connecting M randomly
  75. selected pairs of nodes not already connected.
  76. """
  77. ############################################################################
  78. # TODO: Your code here!
  79. for i in range(M):
  80. a, b = random.randint(1, Graph.GetNodes()), random.randint(1, Graph.GetNodes())
  81. while a == b or Graph.IsEdge(a, b):
  82. a, b = random.randint(1, Graph.GetNodes()), random.randint(1, Graph.GetNodes())
  83. Graph.AddEdge(a, b)
  84. ############################################################################
  85. return Graph
  86. def genSmallWorld(N=5242, E=14484):
  87. """
  88. :param - N: number of nodes
  89. :param - E: number of edges
  90. return type: snap.PUNGraph
  91. return: Small-World graph with N nodes and E edges
  92. """
  93. Graph = genCircle(N)
  94. Graph = connectNbrOfNbr(Graph, N)
  95. Graph = connectRandomNodes(Graph, 4000)
  96. return Graph
  97. def loadCollabNet(path):
  98. """
  99. :param - path: path to edge list file
  100. return type: snap.PUNGraph
  101. return: Graph loaded from edge list at `path and self edges removed
  102. Do not forget to remove the self edges!
  103. """
  104. ############################################################################
  105. # TODO: Your code here!
  106. Graph = snap.LoadEdgeList(snap.TUNGraph, path)
  107. for edge in Graph.Edges():
  108. if edge.GetSrcNId() == edge.GetDstNId:
  109. Graph.DelEdge(edge.GetSrcNId(), edge.GetDstNId)
  110. ############################################################################
  111. return Graph
  112. def getDataPointsToPlot(Graph):
  113. """
  114. :param - Graph: snap.PUNGraph object representing an undirected graph
  115. return values:
  116. X: list of degrees
  117. Y: list of frequencies: Y[i] = fraction of nodes with degree X[i]
  118. """
  119. ############################################################################
  120. # TODO: Your code here!
  121. X, Y = [], []
  122. map = {}
  123. for node in Graph.Nodes():
  124. out_deg = node.GetOutDeg()
  125. if out_deg not in map:
  126. map[out_deg] = 1
  127. else:
  128. map[out_deg] += 1
  129. X = [item for item in map.keys()]
  130. X.sort()
  131. Y = [map[x] for x in X]
  132. ############################################################################
  133. return X, Y
  134. def Q1_1():
  135. """
  136. Code for HW1 Q1.1
  137. """
  138. global erdosRenyi, smallWorld, collabNet
  139. erdosRenyi = genErdosRenyi(5242, 14484)
  140. smallWorld = genSmallWorld(5242, 14484)
  141. collabNet = loadCollabNet("ca-GrQc.txt")
  142. x_erdosRenyi, y_erdosRenyi = getDataPointsToPlot(erdosRenyi)
  143. plt.loglog(x_erdosRenyi, y_erdosRenyi, color='y', label='Erdos Renyi Network')
  144. x_smallWorld, y_smallWorld = getDataPointsToPlot(smallWorld)
  145. plt.loglog(x_smallWorld, y_smallWorld, linestyle='dashed', color='r', label='Small World Network')
  146. x_collabNet, y_collabNet = getDataPointsToPlot(collabNet)
  147. plt.loglog(x_collabNet, y_collabNet, linestyle='dotted', color='b', label='Collaboration Network')
  148. plt.xlabel('Node Degree (log)')
  149. plt.ylabel('Proportion of Nodes with a Given Degree (log)')
  150. plt.title('Degree Distribution of Erdos Renyi, Small World, and Collaboration Networks')
  151. plt.legend()
  152. plt.show()
  153. # Execute code for Q1.1
  154. Q1_1()
  155. # Problem 1.2 - Clustering Coefficient
  156. def calcClusteringCoefficientSingleNode(Node, Graph):
  157. """
  158. :param - Node: node from snap.PUNGraph object. Graph.Nodes() will give an
  159. iterable of nodes in a graph
  160. :param - Graph: snap.PUNGraph object representing an undirected graph
  161. return type: float
  162. returns: local clustering coeffient of Node
  163. """
  164. ############################################################################
  165. # TODO: Your code here!
  166. C = 0.0
  167. k = Node.GetOutDeg()
  168. if k == 0 or k == 1:
  169. return C
  170. neighbours = []
  171. for i in range(k):
  172. neighbours.append(Node.GetOutNId(i))
  173. exc = 0
  174. degs = 0
  175. for node in neighbours:
  176. deg = Graph.GetNI(node).GetOutDeg()
  177. degs += deg
  178. for i in range(deg):
  179. if Graph.GetNI(node).GetOutNId(i) not in neighbours:
  180. exc += 1
  181. e = (degs - exc) / 2
  182. C = float(2 * e) / float(k * (k - 1))
  183. ############################################################################
  184. return C
  185. def calcClusteringCoefficient(Graph):
  186. """
  187. :param - Graph: snap.PUNGraph object representing an undirected graph
  188. return type: float
  189. returns: clustering coeffient of Graph
  190. """
  191. ############################################################################
  192. # TODO: Your code here! If you filled out calcClusteringCoefficientSingleNode,
  193. # you'll probably want to call it in a loop here
  194. C = 0.0
  195. for node in Graph.Nodes():
  196. C += calcClusteringCoefficientSingleNode(node, Graph)
  197. C /= float(Graph.GetNodes())
  198. ############################################################################
  199. return C
  200. def Q1_2():
  201. """
  202. Code for Q1.2
  203. """
  204. C_erdosRenyi = calcClusteringCoefficient(erdosRenyi)
  205. C_smallWorld = calcClusteringCoefficient(smallWorld)
  206. C_collabNet = calcClusteringCoefficient(collabNet)
  207. print('Clustering Coefficient for Erdos Renyi Network: %f' % C_erdosRenyi)
  208. print('Clustering Coefficient for Small World Network: %f' % C_smallWorld)
  209. print('Clustering Coefficient for Collaboration Network: %f' % C_collabNet)
  210. # Execute code for Q1.2
  211. Q1_2()

结果:
我画出来是这样的,不知道对不对:
image.png

  1. Clustering Coefficient for Erdos Renyi Network: 0.001620
  2. Clustering Coefficient for Small World Network: 0.283908
  3. Clustering Coefficient for Collaboration Network: 0.532029

Structural Roles: Rolx and ReFex

数据集:hw1-q2.zip

代码:

  1. import snap
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. def take_first(item):
  5. return item[0]
  6. def basic_features(j):
  7. G = snap.TUNGraph.Load(snap.TFIn("hw1-q2.graph"))
  8. x = calculate_basic_feature(G, j)
  9. similarity = []
  10. for i in range(G.GetMxNId() - 1):
  11. if i + 1 == j:
  12. continue
  13. y = calculate_basic_feature(G, i + 1)
  14. if not np.linalg.norm(x) or not np.linalg.norm(y):
  15. sim = 0
  16. else:
  17. sim = np.dot(x, y) / (np.linalg.norm(x) * np.linalg.norm(y))
  18. similarity.append((sim, i + 1))
  19. similarity.sort(key=take_first, reverse=True)
  20. print(similarity[0], similarity[1], similarity[2])
  21. def calculate_basic_feature(graph, nid):
  22. node = graph.GetNI(nid)
  23. degree = node.GetOutDeg()
  24. neighbours = []
  25. for i in range(degree):
  26. neighbours.append(node.GetOutNId(i))
  27. exc = 0
  28. degs = 0
  29. for id in neighbours:
  30. deg = graph.GetNI(id).GetOutDeg()
  31. degs += deg
  32. for i in range(deg):
  33. if graph.GetNI(id).GetOutNId(i) not in neighbours:
  34. exc += 1
  35. edges = float(degs - exc) / 2.0 + degree
  36. return np.array([degree, edges, exc]).astype(np.float64)
  37. def generate_initial_matrix(G):
  38. matrix = np.array([])
  39. for i in range(G.GetMxNId() - 1):
  40. x = calculate_basic_feature(G, i + 1)
  41. matrix = np.append(matrix, x)
  42. return matrix.reshape(G.GetMxNId() - 1, -1)
  43. def recursive_features(G, features):
  44. matrix = np.array([])
  45. length = features.shape[1]
  46. for i in range(G.GetMxNId() - 1):
  47. sum = np.zeros(length)
  48. node = G.GetNI(i + 1)
  49. for i in range(node.GetOutDeg()):
  50. sum += features[node.GetOutNId(i) - 1]
  51. if not node.GetOutDeg():
  52. mean = np.zeros(length)
  53. else:
  54. mean = sum / float(node.GetOutDeg())
  55. new_feature = np.concatenate([mean, sum])
  56. matrix = np.append(matrix, new_feature)
  57. matrix = matrix.reshape(G.GetMxNId() - 1, -1)
  58. matrix = np.append(features, matrix, axis=1)
  59. return matrix
  60. def top_5(features, k):
  61. size = features.shape[0]
  62. similarity = []
  63. x = features[k - 1]
  64. for i in range(size):
  65. if i == k - 1:
  66. continue
  67. y = features[i]
  68. if not np.linalg.norm(x) or not np.linalg.norm(y):
  69. sim = 0
  70. else:
  71. sim = np.dot(x, y) / (np.linalg.norm(x) * np.linalg.norm(y))
  72. similarity.append((sim, i + 1))
  73. similarity.sort(key=take_first, reverse=True)
  74. for i in range(5):
  75. print(similarity[i])
  76. plot_role(similarity)
  77. def plot_role(similarity):
  78. similarity = [item[0] for item in similarity]
  79. plt.hist(similarity, bins=100)
  80. plt.xlabel('cosine similarity with node 9')
  81. plt.ylabel('number of nodes')
  82. plt.title('role discovery')
  83. plt.show()
  84. if __name__ == '__main__':
  85. # basic_features(9)
  86. G = snap.TUNGraph.Load(snap.TFIn("hw1-q2.graph"))
  87. feature = generate_initial_matrix(G)
  88. feature = recursive_features(G, feature)
  89. feature = recursive_features(G, feature)
  90. top_5(feature, 9)

结果:
还是不知道对不对
image.png

  1. (0.9996996545960188, 415) (0.9985681322700889, 496) (0.9985681322700888, 16)
  2. (0.9979737326427643, 973)
  3. (0.99665936768074, 415)
  4. (0.9944804316381064, 537)
  5. (0.9942402370209513, 496)
  6. (0.9934389028651474, 24)