(nodes,
                              get_leaves_fn,
                              get_lowest_common_ancestor_fn,
                              graph_name=None,
                              num_per_height_to_print=2,
                              num_leaf_pairs=10000,
                              path='longest')
Gather some stats relating to the heights of LCA's of random leaf pairs.

  Args:
    nodes: A set of Synsets.
    get_leaves_fn: A function that returns the set of leaves of a graph defined
      by a given set of nodes, e.g. get_leaves in imagenet_specification.py
    get_lowest_common_ancestor_fn: A function that returns the lowest common
      ancestor node of a given pair of Synsets and its height, e.g. the
      get_lowest_common_ancestor function in imagenet_specification.py.
    graph_name: A name for the graph defined by nodes (for logging).
    num_per_height_to_print: An int. The number of example leaf pairs and
      corresponding lowest common ancestors to print for each height.
    num_leaf_pairs: An int. The number of random leaf pairs to sample.
    path: A str. The 'path' argument of get_lowest_common_ancestor. Can be
      either 'longest' or 'all.
Gather some stats relating to the heights of LCA's of random leaf pairs.
Gather some stats relating to the heights of LCA s of random leaf pairs .
def log_stats_finegrainedness(nodes,
                              get_leaves_fn,
                              get_lowest_common_ancestor_fn,
                              graph_name=None,
                              num_per_height_to_print=2,
                              num_leaf_pairs=10000,
                              path='longest'):
  """Gather some stats relating to the heights of LCA's of random leaf pairs.

  Args:
    nodes: A set of Synsets.
    get_leaves_fn: A function that returns the set of leaves of a graph defined
      by a given set of nodes, e.g. get_leaves in imagenet_specification.py
    get_lowest_common_ancestor_fn: A function that returns the lowest common
      ancestor node of a given pair of Synsets and its height, e.g. the
      get_lowest_common_ancestor function in imagenet_specification.py.
    graph_name: A name for the graph defined by nodes (for logging).
    num_per_height_to_print: An int. The number of example leaf pairs and
      corresponding lowest common ancestors to print for each height.
    num_leaf_pairs: An int. The number of random leaf pairs to sample.
    path: A str. The 'path' argument of get_lowest_common_ancestor. Can be
      either 'longest' or 'all.
  """
  if not nodes:
    # Empty set
    return
  logging.info(
      'Finegrainedness analysis of %s graph using %s paths in '
      'finding the lowest common ancestor.', graph_name, path)
  leaves = get_leaves_fn(nodes)
  # Maps the height of the lowest common ancestor of two leaves to the 'example'
  # in which that height occurred. The example is a tuple of the string words
  # associated with (first leaf, second leaf, lowest common ancestor).
  heights_to_examples = collections.defaultdict(list)
  # Maps the height of the lowest common ancestor of two leaves to the number of
  # leaf pairs whose LCA has that height and is the root.
  heights_to_num_lca_root = collections.defaultdict(int)
  # A list of all observed LCA heights.
  heights = []
  # Sample a number of random pairs of leaves, and compute the height of their
  # lowest common ancestor.
  for _ in range(num_leaf_pairs):
    first_ind = np.random.randint(len(leaves))
    second_ind = np.random.randint(len(leaves))
    while first_ind == second_ind:
      second_ind = np.random.randint(len(leaves))
    leaf_a = leaves[first_ind]
    leaf_b = leaves[second_ind]
    lca, height = get_lowest_common_ancestor_fn(leaf_a, leaf_b, path=path)
    heights.append(height)

    heights_to_examples[height].append((leaf_a.words, leaf_b.words, lca.words))
    if not lca.parents:
      heights_to_num_lca_root[height] += 1

  name_message = ' of the {} graph'.format(
      graph_name) if graph_name is not None else ''
  stats_message = 'mean: {}, median: {}, max: {}, min: {}'.format(
      np.mean(heights), np.median(heights), max(heights), min(heights))
  logging.info(
      'Stats on the height of the Lowest Common Ancestor of random leaf pairs%s'
      ': %s', name_message, stats_message)

  # For each given height, how many pairs of leaves are there?
  heights_to_num_examples = {}
  heights_to_proportion_root = {}
  for h, examples in heights_to_examples.items():
    heights_to_num_examples[h] = len(examples) / num_leaf_pairs
    heights_to_proportion_root[h] = heights_to_num_lca_root[h] / float(
        len(examples))
  logging.info(
      'Proportion of example leaf pairs (out of num_leaf_pairs '
      'random pairs) for each height of the LCA of the leaves: %s',
      heights_to_num_examples)

  # What proportion of those have the root as LCA, for each possible height?
  logging.info(
      'Proportion of example leaf pairs per height whose LCA is the root: %s',
      heights_to_proportion_root)

  logging.info('Examples with different fine-grainedness:\n')
  for height in heights_to_examples.keys():
    # Get representative examples of this height.
    for i, example in enumerate(heights_to_examples[height]):
      if i == num_per_height_to_print:
        break
      logging.info('Examples with height %s:\nleafs: %s and %s. LCA: %s',
                   height, example[0], example[1], example[2])
def log_stats_finegrainedness ( nodes , get_leaves_fn , get_lowest_common_ancestor_fn , graph_name = None , num_per_height_to_print = 2 , num_leaf_pairs = 10000 , path = 'longest' ) : if not nodes : # Empty set return logging . info ( 'Finegrainedness analysis of %s graph using %s paths in ' 'finding the lowest common ancestor.' , graph_name , path ) leaves = get_leaves_fn ( nodes ) # Maps the height of the lowest common ancestor of two leaves to the 'example' # in which that height occurred. The example is a tuple of the string words # associated with (first leaf, second leaf, lowest common ancestor). heights_to_examples = collections . defaultdict ( list ) # Maps the height of the lowest common ancestor of two leaves to the number of # leaf pairs whose LCA has that height and is the root. heights_to_num_lca_root = collections . defaultdict ( int ) # A list of all observed LCA heights. heights = [ ] # Sample a number of random pairs of leaves, and compute the height of their # lowest common ancestor. for _ in range ( num_leaf_pairs ) : first_ind = np . random . randint ( len ( leaves ) ) second_ind = np . random . randint ( len ( leaves ) ) while first_ind == second_ind : second_ind = np . random . randint ( len ( leaves ) ) leaf_a = leaves [ first_ind ] leaf_b = leaves [ second_ind ] lca , height = get_lowest_common_ancestor_fn ( leaf_a , leaf_b , path = path ) heights . append ( height ) heights_to_examples [ height ] . append ( ( leaf_a . words , leaf_b . words , lca . words ) ) if not lca . parents : heights_to_num_lca_root [ height ] += 1 name_message = ' of the {} graph' . format ( graph_name ) if graph_name is not None else '' stats_message = 'mean: {}, median: {}, max: {}, min: {}' . format ( np . mean ( heights ) , np . median ( heights ) , max ( heights ) , min ( heights ) ) logging . info ( 'Stats on the height of the Lowest Common Ancestor of random leaf pairs%s' ': %s' , name_message , stats_message ) # For each given height, how many pairs of leaves are there? heights_to_num_examples = { } heights_to_proportion_root = { } for h , examples in heights_to_examples . items ( ) : heights_to_num_examples [ h ] = len ( examples ) / num_leaf_pairs heights_to_proportion_root [ h ] = heights_to_num_lca_root [ h ] / float ( len ( examples ) ) logging . info ( 'Proportion of example leaf pairs (out of num_leaf_pairs ' 'random pairs) for each height of the LCA of the leaves: %s' , heights_to_num_examples ) # What proportion of those have the root as LCA, for each possible height? logging . info ( 'Proportion of example leaf pairs per height whose LCA is the root: %s' , heights_to_proportion_root ) logging . info ( 'Examples with different fine-grainedness:\n' ) for height in heights_to_examples . keys ( ) : # Get representative examples of this height. for i , example in enumerate ( heights_to_examples [ height ] ) : if i == num_per_height_to_print : break logging . info ( 'Examples with height %s:\nleafs: %s and %s. LCA: %s' , height , example [ 0 ] , example [ 1 ] , example [ 2 ] )