code: def _normalized_mutual_info_score(reference_indices, estimated_indices):
      
      ref_classes = np.unique(reference_indices)
      est_classes = np.unique(estimated_indices)
      # Special limit cases: no clustering since the data is not split.
      # This is a perfect match hence return 1.0.
      if (ref_classes.shape[0] == est_classes.shape[0] == 1 or
              ref_classes.shape[0] == est_classes.shape[0] == 0):
          return 1.0
      contingency = _contingency_matrix(reference_indices,
                                        estimated_indices).astype(float)
      contingency = np.array(contingency, dtype='float')
      # Calculate the MI for the two clusterings
      mi = _mutual_info_score(reference_indices, estimated_indices,
                              contingency=contingency)
      # Calculate the expected value for the mutual information
      # Calculate entropy for each labeling
      h_true, h_pred = _entropy(reference_indices), _entropy(estimated_indices)
      nmi = mi / max(np.sqrt(h_true * h_pred), 1e-10)
      return nmi
docs: Compute the mutual information between two sequence labelings, adjusted for
      chance.
  
      Parameters
      ----------
      reference_indices : np.ndarray
          Array of reference indices
  
      estimated_indices : np.ndarray
          Array of estimated indices
  
      Returns
      -------
      nmi : float <= 1.0
          Normalized mutual information
  
      .. note:: Based on sklearn.metrics.cluster.normalized_mutual_info_score