code: def _mutual_info_score(reference_indices, estimated_indices, contingency=None):
      
      if contingency is None:
          contingency = _contingency_matrix(reference_indices,
                                            estimated_indices).astype(float)
      contingency_sum = np.sum(contingency)
      pi = np.sum(contingency, axis=1)
      pj = np.sum(contingency, axis=0)
      outer = np.outer(pi, pj)
      nnz = contingency != 0.0
      # normalized contingency
      contingency_nm = contingency[nnz]
      log_contingency_nm = np.log(contingency_nm)
      contingency_nm /= contingency_sum
      # log(a / b) should be calculated as log(a) - log(b) for
      # possible loss of precision
      log_outer = -np.log(outer[nnz]) + np.log(pi.sum()) + np.log(pj.sum())
      mi = (contingency_nm * (log_contingency_nm - np.log(contingency_sum)) +
            contingency_nm * log_outer)
      return mi.sum()
docs: Compute the mutual information between two sequence labelings.
  
      Parameters
      ----------
      reference_indices : np.ndarray
          Array of reference indices
      estimated_indices : np.ndarray
          Array of estimated indices
      contingency : np.ndarray
          Pre-computed contingency matrix.  If None, one will be computed.
          (Default value = None)
  
      Returns
      -------
      mi : float
          Mutual information
  
      .. note:: Based on sklearn.metrics.cluster.mutual_info_score