class_docstr: Tests that MutualInformation returns the correct AMI value.
class_docstr_tok: ["Tests","that","MutualInformation","returns","the","correct","AMI","value","."]
code: def test_categorical_univalent_feature_large(self):
      labels = ["Red"] * 50 + ["Blue"] * 50
  
      # Here is the exact mutual information for the almost perfect feature:
      # P(Red, Red) = P(Red|Red) * P(Red) = 49/50 * 1/2 = 49/100 = P(Blue, Blue)
      # P(Red, Blue) = P(Red|Blue) * P(Blue) = 1/50 * 1/2 = 1/100 = P(Blue, Red)
      # MI(X,Y) = 0.47571829 * 2 + -0.04643856 * 2 = 0.85855945
      # Since this generator calculates AMI = MI(X,Y) - Shuffle_MI(X,Y),
      # We should expect the results to be a bit less than 0.85855945
      near_perfect_feature = (
          ["Red"] * 49 + ["Blue"] + ["Red"] + ["Blue"] * 49
      )
  
      # The feature is perfectly uncorrelated. The mutual information is:
      # P(Red, Red) = 0 = P(Blue, Blue)
      # P(Red, Blue) = 1 = P(Blue, Red)
      # MI(X,Y) = 0 + 0 + 1*log(1/4) * 2 = -4
      # AMI will thus be floored at 0.
      terrible_feature = (["Red"] * 25 + ["Blue"] * 25) * 2
  
      batch = pa.RecordBatch.from_arrays(
          [
              pa.array([[x] for x in labels]),
              pa.array([[x] for x in near_perfect_feature]),
              pa.array([[x] for x in terrible_feature]),
          ],
          ["label_key", "near_perfect_feature", "terrible_feature"],
      )
  
      schema = text_format.Parse(
          """
          feature {
            name: "label_key"
            type: BYTES
            shape {
              dim {
                size: 1
              }
            }
          }
          feature {
            name: "near_perfect_feature"
            type: BYTES
            shape {
              dim {
                size: 1
              }
            }
          }
          feature {
            name: "terrible_feature"
            type: BYTES
            shape {
              dim {
                size: 1
              }
            }
          }
          """,
          schema_pb2.Schema(),
      )
  
      expected = text_format.Parse(
          """
          features {
            path {
              step: "terrible_feature"
            }
            custom_stats {
              name: 'adjusted_mutual_information'
              num: 0
            }
          }
          features {
            path {
              step: "near_perfect_feature"
            }
            custom_stats {
              name: 'adjusted_mutual_information'
              num: 0.8400134
            }
          }""",
          statistics_pb2.DatasetFeatureStatistics(),
      )
      self._assert_ami_output_equal(
          batch, expected, schema, types.FeaturePath(["label_key"])
      )
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  from absl.testing import absltest
  from absl.testing import parameterized
  import apache_beam
  from apache_beam.testing import util
  import numpy
  import pyarrow
  from tensorflow_data_validation import types
  from tensorflow_data_validation.statistics.generators import mutual_information
  from tensorflow_data_validation.statistics.generators import partitioned_stats_generator
  from tensorflow_data_validation.utils import test_util
  from tfx_bsl.arrow import table_util
  from google.protobuf import text_format
  from tensorflow_metadata.proto.v0 import schema_pb2
  from tensorflow_metadata.proto.v0 import statistics_pb2
label_desc: Use image node_id 15 for calling the MutualInformationTest obj's underlying member method code with example usage: obj.test_categorical_univalent_feature_large() without return types