class_docstr: Tests for SkLearnMutualInformationStatsFn.
code: def test_mi_regression_with_int_label_and_categorical_feature(self):
      n = 100
      # Set seed so this test is deterministic
      np.random.seed(0)
  
      # The features have the following labels:
      # Feature | Label
      # -----------------
      # Red     | [0, 1.0)
      # Blue    | [1.0, 2.0)
      # Green   | [2.0, 3.0)
  
      # Create labels where first n items are [0, 1.0),
      # next n items are [1.0, 2.0), and last n items are [2.0, 3.0).
      label = (
          [np.random.rand() for i in range(n)]
          + [np.random.rand() + 1 for i in range(n)]
          + [np.random.rand() + 2 for i in range(n)]
      )
  
      # A categorical feature that maps directly on to the label.
      feat = ["Red"] * n + ["Blue"] * n + ["Green"] * n
  
      # Shuffle the two arrays together (i.e. the table above still holds, but the
      # order of labels are now mixed.)
      # For example:
      # [0.4, 0.1, 1.2, 2.4]            => [1.2, 0.1, 2.4, 0.4]
      # ["Red", "Red", "Blue", "Green"] => ["Blue", "Red", "Green", "Red"]
      zipped_arrays = list(zip(feat, label))
      np.random.shuffle(zipped_arrays)
      feat_array, label_array = zip(*zipped_arrays)
  
      batch = pa.RecordBatch.from_arrays(
          [
              pa.array([[x] for x in label_array]),
              pa.array([[x] for x in feat_array]),
          ],
          ["label_key", "color_feature"],
      )
  
      schema = text_format.Parse(
          """
          feature {
            name: "label_key"
            type: INT
            shape {
              dim {
                size: 1
              }
            }
          }
          feature {
            name: "color_feature"
            type: BYTES
            shape {
              dim {
                size: 1
              }
            }
          }
          """,
          schema_pb2.Schema(),
      )
  
      expected = text_format.Parse(
          """
          features {
            path {
              step: "color_feature"
            }
            custom_stats {
              name: 'sklearn_adjusted_mutual_information'
              num: 1.0798653
            }
            custom_stats {
              name: 'sklearn_mutual_information'
              num: 1.0983102
            }
            custom_stats {
              name: "sklearn_normalized_adjusted_mutual_information"
              num: 0.2438967
            }
          }""",
          statistics_pb2.DatasetFeatureStatistics(),
      )
      self._assert_mi_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
  import numpy
  import pyarrow
  from tensorflow_data_validation import types
  from tensorflow_data_validation.statistics.generators import sklearn_mutual_information
  from google.protobuf import text_format
  from tensorflow.python.util.protobuf import compare
  from tensorflow_metadata.proto.v0 import schema_pb2
  from tensorflow_metadata.proto.v0 import statistics_pb2
label_desc: Use image node_id 4 for calling the SkLearnMutualInformationTest obj's underlying member method code with example usage: obj.test_mi_regression_with_int_label_and_categorical_feature() without return types