code: def mutual_info_score(labels_true, labels_pred, contingency=None):
      """Mutual Information between two clusterings.
  
      The Mutual Information is a measure of the similarity between two labels of
      the same data. Where :math:`P(i)` is the probability of a random sample
      occurring in cluster :math:`U_i` and :math:`P'(j)` is the probability of a
      random sample occurring in cluster :math:`V_j`, the Mutual Information
      between clusterings :math:`U` and :math:`V` is given as:
  
      .. math::
  
          MI(U,V)=\sum_{i=1}^R \sum_{j=1}^C P(i,j)\log\\frac{P(i,j)}{P(i)P'(j)}
  
      This is equal to the Kullback-Leibler divergence of the joint distribution
      with the product distribution of the marginals.
  
      This metric is independent of the absolute values of the labels:
      a permutation of the class or cluster label values won't change the
      score value in any way.
  
      This metric is furthermore symmetric: switching ``label_true`` with
      ``label_pred`` will return the same score value. This can be useful to
      measure the agreement of two independent label assignments strategies
      on the same dataset when the real ground truth is not known.
  
      Read more in the :ref:`User Guide <mutual_info_score>`.
  
      Parameters
      ----------
      labels_true : int array, shape = [n_samples]
          A clustering of the data into disjoint subsets.
  
      labels_pred : array, shape = [n_samples]
          A clustering of the data into disjoint subsets.
  
      contingency : {None, array, sparse matrix},
                    shape = [n_classes_true, n_classes_pred]
          A contingency matrix given by the :func:`contingency_matrix` function.
          If value is ``None``, it will be computed, otherwise the given value is
          used, with ``labels_true`` and ``labels_pred`` ignored.
  
      Returns
      -------
      mi : float
         Mutual information, a non-negative value
  
      See also
      --------
      adjusted_mutual_info_score: Adjusted against chance Mutual Information
      normalized_mutual_info_score: Normalized Mutual Information
      """
      if contingency is None:
          labels_true, labels_pred = check_clusterings(
              labels_true, labels_pred
          )
          contingency = contingency_matrix(
              labels_true, labels_pred, sparse=True
          )
      else:
          contingency = check_array(
              contingency,
              accept_sparse=["csr", "csc", "coo"],
              dtype=[int, np.int32, np.int64],
          )
  
      if isinstance(contingency, np.ndarray):
          # For an array
          nzx, nzy = np.nonzero(contingency)
          nz_val = contingency[nzx, nzy]
      elif sp.issparse(contingency):
          # For a sparse matrix
          nzx, nzy, nz_val = sp.find(contingency)
      else:
          raise ValueError(
              "Unsupported type for 'contingency': %s"
              % type(contingency)
          )
  
      contingency_sum = contingency.sum()
      pi = np.ravel(contingency.sum(axis=1))
      pj = np.ravel(contingency.sum(axis=0))
      log_contingency_nm = np.log(nz_val)
      contingency_nm = nz_val / contingency_sum
      # Don't need to calculate the full outer product, just for non-zeroes
      outer = pi.take(nzx) * pj.take(nzy)
      log_outer = -np.log(outer) + log(pi.sum()) + log(pj.sum())
      mi = (
          contingency_nm * (log_contingency_nm - log(contingency_sum))
          + contingency_nm * log_outer
      )
      return mi.sum()
  
imports: from __future__ import division
  from math import log
  import numpy
  from scipy.misc import comb
  from scipy import sparse
  from .expected_mutual_info_fast import expected_mutual_information
  from ...utils.fixes import bincount
  from ...utils.validation import check_array
label_desc: Use image node_id 9 for calling a global function with example usage: mutual_info_score(labels_true, labels_pred, contingency) and returns: mi