/metrics.py (d0b9c8eb7fcb8180748a37f1759e4e08b3b180fa) (4982 bytes) (mode 100644) (type blob)

#metrics.py
import networkx as nx
import numpy as np

def clustering_coefficient(self,node):
  #in the first run calculate the metric for all nodes at once and save in a hash of the instance to access later
  #NOTE: this should result in a performance gain, but for very large graphs this might be a problem.
  #      in this case, just returning nx.clustering(self.graph, node) might be better
  if not hasattr(self, 'all_clustering_coefficients'):
    self.all_clustering_coefficients = nx.clustering(self.graph)

  #get the actual value from the pre-calculated hash
  return self.all_clustering_coefficients[node]

def degree(self, node):
  return self.graph.degree(node)


def average_neighbor_degree(self,node):
  # same caching technique as in self.clustering_coefficient
  # might also break for very large graphs
  # nx.average_neighbor_degree(self.graph, nodes=node) might be the way to go

  if not hasattr(self, 'all_average_neighbor_degrees'):
    self.all_average_neighbor_degrees = nx.average_neighbor_degree(self.graph)
  return self.all_average_neighbor_degrees[node]

def iterated_average_neighbor_degree(self, node):
  
  first_level_neighbors = self.graph.neighbors(node)
  second_level_neighbors = []

  # get all two-hop nodes
  for first_level_neighbor in first_level_neighbors:
    current_second_level_neighbors = self.graph.neighbors(first_level_neighbor)
    second_level_neighbors.extend(current_second_level_neighbors)

  #remove one-hop nodes and self
  relevant_nodes = set(second_level_neighbors) - set(first_level_neighbors) - set([node])
  
  degree_sum = 0
  for relevant_node in relevant_nodes:
    degree_sum += self.graph.degree(relevant_node)

  return float(degree_sum)/float(len(relevant_nodes))

def betweenness_centrality(self, node):
  if not hasattr(self, 'all_betweenness_centralities'):
    self.all_betweenness_centralities = nx.betweenness_centrality(self.graph)
  return self.all_betweenness_centralities[node]

def eccentricity(self, node):
  if not hasattr(self, 'all_eccentricities'):
    self.all_eccentricities = nx.eccentricity(self.graph)
  return self.all_eccentricities[node]

def average_shortest_path_length(self, node):
  # caching average_shortest_path_length for all nodes at one failed
  # already switched to single calculation

  #get all shortest path lengths
  all_shortest_path_lengths_for_node = nx.shortest_path_length(self.graph, source=node)

  #calculate average
  sum_of_lengths = 0
  for target in all_shortest_path_lengths_for_node:
    sum_of_lengths += all_shortest_path_lengths_for_node[target]
  
  return float(sum_of_lengths)/len(all_shortest_path_lengths_for_node)


#############
# advanced metrics
#############
def correct_clustering_coefficient(self,node):
  clustering_coefficient = float(self.redis.hget(self.node_prefix+str(node),'clustering_coefficient'))
  degree = float(self.redis.hget(self.node_prefix+str(node), 'degree'))
  corrected_cc = clustering_coefficient + (degree * clustering_coefficient) / float(4)
  return corrected_cc

def correct_average_neighbor_degree(self,node):
  avgnd = float(self.redis.hget(self.node_prefix+str(node), 'average_neighbor_degree'))
  
  neighbors = self.graph.neighbors(node)
  number_of_neighbors = float(len(neighbors))
  neighbor_degrees = []
  for neighbor in neighbors:
    neighbor_degrees.append(self.graph.degree(neighbor))

  #using numpy median and standard deviation implementation
  numpy_neighbor_degrees = np.array(neighbor_degrees)
  median = np.median(numpy_neighbor_degrees)
  standard_deviation = np.std(numpy_neighbor_degrees)
  
  if avgnd == 0.0 or number_of_neighbors == 0.0 or standard_deviation == 0.0:
    return avgnd
  else:
    return avgnd + ( ((median - avgnd) / standard_deviation) / number_of_neighbors ) * avgnd


def correct_iterated_average_neighbor_degree(self, node):
  avgnd = float(self.redis.hget(self.node_prefix+str(node), 'iterated_average_neighbor_degree'))

  first_level_neighbors = self.graph.neighbors(node)
  second_level_neighbors = []

  # get all two-hop nodes
  for first_level_neighbor in first_level_neighbors:
    current_second_level_neighbors = self.graph.neighbors(first_level_neighbor)
    second_level_neighbors.extend(current_second_level_neighbors)

  #remove one-hop neighbors and self
  relevant_nodes = set(second_level_neighbors) - set(first_level_neighbors) - set([node])

  number_of_nodes = len(relevant_nodes)
  node_degrees = []
  for rel_node in relevant_nodes:
    node_degrees.append(self.graph.degree(rel_node))

  numpy_node_degrees = np.array(node_degrees)
  median = np.median(numpy_node_degrees)
  standard_deviation = np.std(numpy_node_degrees)

  if avgnd == 0.0 or number_of_nodes == 0.0 or standard_deviation == 0.0:
    return avgnd
  else:
    return avgnd + ( ((median - avgnd) / standard_deviation) / number_of_nodes ) * avgnd
  



Mode Type Size Ref File
100644 blob 103 924a1df9f7338af770d3cf3d4b0ce2673f10d1b0 README.md
100644 blob 0 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 __init__.py
100644 blob 1256 489636a0073e3dfe2bfd04ee893d609d304a8490 advancedscores.py
100644 blob 4684 6632f85e6584f8e4c8a8b634f18abbbbfb3516fb config.py
040000 tree - 1eae5e19b1eff05e464e361e3f50f3df23f1b754 data
100644 blob 662 36006180d2297800e02a403802ba4c69244ef217 file_importer.py
100644 blob 716 359eb7179fa58d67044228556f7d9c38b5caec85 indexing.py
100644 blob 5969 f4b2e6e8daaca0b04b5098b2ef31b0dabde780f4 metric_calculator.py
100644 blob 4982 d0b9c8eb7fcb8180748a37f1759e4e08b3b180fa metrics.py
100644 blob 1665 a959a8cc528f486a80a84e2ab233457870d255a1 normalizations.py
100644 blob 1076 682fdba07b56eac554064508b5b82ca6e4a5a031 start.py
100644 blob 2144 fb03eaa1cd8eb0d6c17b2019fe4c877a32bb7059 statistics.py
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/coria/coria-backend

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/coria/coria-backend

Clone this repository using git:
git clone git://git.rocketgit.com/user/coria/coria-backend

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main