class_docstr: Quantitative Testing with Concept Activation Vectors (TCAV).
  
  TCAV is an interpretability method which allows users to define a concept
  by selecting a set of representative examples and trains a classifier at
  different model layers to determine whether that concept has any influence
  over the predictions of the model (https://arxiv.org/pdf/1711.11279.pdf).
  If so, it can be measured as an aggregate score, and also individual points
  can be measured by how much of that concept they contain, at a given layer.
  
  The original implementation can be found at:
  https://github.com/tensorflow/tcav
  
  This component requires that the following fields in the model spec. Field
  names like `layer` are placeholders; you can call them whatever you like,
  and as with other LIT components multiple segments are supported.
    Output:
      - Embeddings (`emb_layer`) to return the input embeddings
          for a layer
      - Gradients (`grad_layer`) to return the gradients w.r.t.
          `emb_layer`
      - Gradients class (`grad_class`) to return the label that gradients
        were computed for. This is usually a CategoryLabel, but can be anything
        since it will just be fed back into the model.
      - MulticlassPreds (`probas`)
  
  **Note: TCAV calls the model multiple times. It is _strongly_ recommended that
  you use a caching model (i.e., wrap your model in a `CachingModelWrapper`) to
  optimize performance.**
code: def _run_relative_tcav(
      self,
      grad_layer,
      emb_layer,
      grad_class_key,
      positive_outputs,
      negative_outputs,
      dataset_outputs,
      config,
  ):
      # Ideally, for relative TCAV, users would test concepts with at least ~100
      # examples each so we can perform ~15 runs on unique subsets.
      # In practice, users may not pass in this many examples, so to accommodate
      # this, we use a cross-validation approach, where we will try different
      # subset split sizes, and return one with a statistically significant
      # result.
      splits = RELATIVE_TCAV_SPLITS
      min_length = min(len(positive_outputs), len(negative_outputs))
  
      # We set the minimum number of examples to run TCAV at 3 examples, and
      # need at least 2 runs for statistical testing. If there are too few
      # examples for this, we will perform 1 run of size
      # min(concept set length, negative set length), and return the result
      # without statistical testing.
      if (
          len(positive_outputs) < MIN_SPLIT_SIZE * MIN_SPLITS
          or len(negative_outputs) < MIN_SPLIT_SIZE * MIN_SPLITS
      ):
          splits = [min_length]
  
      results = []
      for split in splits:
          num_runs = math.floor(min_length / split)
  
          # Exit if there are not enough examples for a run of this split size.
          if num_runs < 1:
              break
  
          concept_results = []
          # The i-th run will use the i-th (non-overlapping) subset of this split
          # size of examples.
          for i in range(num_runs):
              positive_split_outputs = positive_outputs[
                  i * split : (i + 1) * split
              ]
              negative_split_outputs = negative_outputs[
                  i * split : (i + 1) * split
              ]
              concept_results.append(
                  self._run_tcav(
                      positive_split_outputs,
                      negative_split_outputs,
                      dataset_outputs,
                      config.class_to_explain,
                      emb_layer,
                      grad_layer,
                      grad_class_key,
                      config.test_size,
                      config.random_state,
                  )
              )
  
          random_results = []
          # Get tcav scores on random splits.
          for _ in range(num_runs):
              positive_split_outputs = self._subsample(
                  dataset_outputs, split
              )
              negative_split_outputs = self._subsample(
                  dataset_outputs, split
              )
              random_results.append(
                  self._run_tcav(
                      positive_split_outputs,
                      negative_split_outputs,
                      dataset_outputs,
                      config.class_to_explain,
                      emb_layer,
                      grad_layer,
                      grad_class_key,
                      config.test_size,
                      config.random_state,
                  )
              )
  
          cav_scores = [res["score"] for res in concept_results]
          random_scores = [res["score"] for res in random_results]
          p_val = None
          if num_runs > 1:
              p_val = self.hyp_test(cav_scores, random_scores)
  
          random_mean = np.mean(random_scores)
  
          # Get index of CAV result with the highest accuracy.
          accuracies = [res["accuracy"] for res in concept_results]
          index = np.argmax(accuracies)
  
          # Many CAVS are trained and checked for statistical testing to calculate
          # the p-value. The values of the CAV with the highest accuracy for this
          # split is appended to the results.
          results.append(
              {
                  "result": concept_results[index],
                  "p_val": p_val,
                  "random_mean": random_mean,
                  "split_size": split,
                  "num_runs": num_runs,
              }
          )
  
      tested_results = [
          result for result in results if result["p_val"] is not None
      ]
      # If there weren't enough runs for any t-testing, just return non-t-tested
      # results.
      if not tested_results:
          return results
  
      significant_tested_results = [
          result for result in tested_results if result["p_val"] < 0.05
      ]
  
      # If there were statistically significant results, return results from those
      # runs; otherwise, just return the (non-significant) t-tested results.
      if significant_tested_results:
          return significant_tested_results
      else:
          return tested_results
  
imports: from collections.abc import Sequence
  import dataclasses
  import math
  import random
  from typing import Any, Optional, cast
  from lit_nlp.api import components
  from lit_nlp.api import dataset
  from lit_nlp.api import model
  from lit_nlp.api import types
  from lit_nlp.lib import utils
  import numpy
  import scipy.stats
  import sklearn.linear_model
  import sklearn.model_selection
label_desc: Use image node_id 7 for calling the TCAV obj's underlying member method code with example usage: obj._run_relative_tcav(grad_layer, emb_layer, grad_class_key, positive_outputs, negative_outputs, dataset_outputs, config) and returns: results, significant_tested_results, tested_results