def test_binary_partition_tree_exponential_linkage_equiv(self):
        np.random.seed(10)

        g = hg.get_4_adjacency_graph((10, 10))
        edge_weights = np.random.rand(g.num_edges())
        edge_weight_weights = np.random.randint(1, 10, g.num_edges())

        tree, altitudes = hg.binary_partition_tree_exponential_linkage(
            g, edge_weights, 0, edge_weight_weights)
        t_ref, alt_ref = hg.binary_partition_tree_average_linkage(
            g, edge_weights, edge_weight_weights)
        self.assertTrue(np.all(tree.parents() == t_ref.parents()))
        self.assertTrue(np.allclose(altitudes, alt_ref))

        tree, altitudes = hg.binary_partition_tree_exponential_linkage(
            g, edge_weights, float('inf'), edge_weight_weights)
        t_ref, alt_ref = hg.binary_partition_tree_complete_linkage(
            g, edge_weights)
        self.assertTrue(np.all(tree.parents() == t_ref.parents()))
        self.assertTrue(np.allclose(altitudes, alt_ref))

        tree, altitudes = hg.binary_partition_tree_exponential_linkage(
            g, edge_weights, float('-inf'), edge_weight_weights)
        t_ref, alt_ref = hg.binary_partition_tree_single_linkage(
            g, edge_weights)
        self.assertTrue(np.all(tree.parents() == t_ref.parents()))
        self.assertTrue(np.allclose(altitudes, alt_ref))
示例#2
0
def binary_partition_tree_exponential_linkage(graph,
                                              edge_weights,
                                              alpha,
                                              edge_weight_weights=None):
    """
    Binary partition tree with exponential linkage distance.

    Given a graph :math:`G=(V, E)`, with initial edge weights :math:`w` with associated weights :math:`w_2`,
    the distance :math:`d(X,Y)` between any two clusters :math:`X` and :math:`Y` is

    .. math::

         d(X,Y) = \\frac{1}{Z} \sum_{x \in X, y \in Y, \{x,y\} in E} w_2(\{x,y\}) \\times \exp(\\alpha * w(\{x,y\})) \\times w(\{x,y\})

    with :math:`Z = \sum_{x \in X, y \in Y, \{x,y\} \in E} w_2(\{x,y\}) \\times \exp(\\alpha * w(\{x,y\}))`.

    :See:

         Nishant Yadav, Ari Kobren, Nicholas Monath, Andrew Mccallum.
         `Supervised Hierarchical Clustering with Exponential Linkage <http://proceedings.mlr.press/v97/yadav19a.html>`_
         Proceedings of the 36th International Conference on Machine Learning, PMLR 97:6973-6983, 2019.

    :param graph: input graph
    :param edge_weights: edge weights of the input graph
    :param alpha: exponential parameter
    :param edge_weight_weights: weighting of edge weights of the input graph (default to an array of ones)
    :return: a tree (Concept :class:`~higra.CptHierarchy`) and its node altitudes
    """

    alpha = float(alpha)

    if edge_weight_weights is None:
        edge_weight_weights = np.ones_like(edge_weights)
    else:
        edge_weights, edge_weight_weights = hg.cast_to_common_type(
            edge_weights, edge_weight_weights)

    # special cases: improve efficiency and avoid numerical issues
    if alpha == 0:
        tree, altitudes = hg.binary_partition_tree_average_linkage(
            graph, edge_weights, edge_weight_weights)
    elif alpha == float('-inf'):
        tree, altitudes = hg.binary_partition_tree_single_linkage(
            graph, edge_weights)
    elif alpha == float('inf'):
        tree, altitudes = hg.binary_partition_tree_complete_linkage(
            graph, edge_weights)
    else:
        res = hg.cpp._binary_partition_tree_exponential_linkage(
            graph, edge_weights, alpha, edge_weight_weights)
        tree = res.tree()
        altitudes = res.altitudes()

    hg.CptHierarchy.link(tree, graph)

    return tree, altitudes
    def test_binary_partition_tree_complete_linkage(self):
        graph = hg.get_4_adjacency_graph((3, 3))
        edge_weights = np.asarray((1, 8, 2, 10, 15, 3, 11, 4, 12, 13, 5, 6),
                                  np.float32)
        tree, levels = hg.binary_partition_tree_complete_linkage(
            graph, edge_weights)

        expected_parents = np.asarray(
            (9, 9, 10, 11, 11, 12, 13, 13, 14, 10, 16, 12, 15, 14, 15, 16, 16),
            np.uint32)
        expected_levels = np.asarray(
            (0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 13, 15), np.float32)

        self.assertTrue(np.all(expected_parents == tree.parents()))
        self.assertTrue(np.all(expected_levels == levels))
示例#4
0
def CLINK(G):
  return hg.binary_partition_tree_complete_linkage(G[0], G[1])