Метрики и графики анализа модели Tensorflow

Обзор

TFMA поддерживает следующие показатели и графики:

  • Стандартное keras метрика ( tf.keras.metrics.* )
    • Обратите внимание, что для использования показателей keras вам не нужна модель keras. Метрики вычисляются вне графика в луче с использованием классов метрик напрямую.
  • Стандартный TFMA метрика и участки ( tfma.metrics.* )

  • Таможенные keras метрики (метрики , полученные из tf.keras.metrics.Metric )

  • Пользовательские метрики TFMA (метрики , полученные из tfma.metrics.Metric ) с использованием сумматоров пользовательских луча или метрик , полученные из других метрик).

TFMA также предоставляет встроенную поддержку преобразования метрик двоичной классификации для использования с задачами с несколькими классами и метками:

  • Бинаризация на основе идентификатора класса, вершины K и т. Д.
  • Агрегированные показатели на основе микро усреднения, макро усреднения и т. Д.

TFMA также обеспечивает встроенную поддержку метрик на основе запросов / ранжирования, где примеры автоматически группируются по ключу запроса в конвейере.

В совокупности доступно более 50 стандартных показателей и графиков для различных задач, включая регрессию, двоичную классификацию, многоклассовую / многоклассовую классификацию, ранжирование и т. Д.

Конфигурация

Есть два способа метрик конфигурационных в TFMA: (1) с использованием tfma.MetricsSpec или (2) путем создания экземпляров tf.keras.metrics.* и / или tfma.metrics.* Классы в Python и с помощью tfma.metrics.specs_from_metrics , чтобы преобразовать их в список tfma.MetricsSpec .

В следующих разделах описываются примеры конфигураций для различных типов задач машинного обучения.

Метрики регрессии

Ниже приведен пример настройки конфигурации для проблемы регрессии. Проконсультироваться с tf.keras.metrics.* И tfma.metrics.* Модули для возможных дополнительных метрик поддерживается.

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    metrics { class_name: "ExampleCount" }
    metrics { class_name: "MeanSquaredError" }
    metrics { class_name: "Accuracy" }
    metrics { class_name: "MeanLabel" }
    metrics { class_name: "MeanPrediction" }
    metrics { class_name: "Calibration" }
    metrics {
      class_name: "CalibrationPlot"
      config: '"min_value": 0, "max_value": 10'
    }
  }
""", tfma.EvalConfig()).metrics_specs

Эту же настройку можно создать с помощью следующего кода Python:

metrics = [
    tfma.metrics.ExampleCount(name='example_count'),
    tf.keras.metrics.MeanSquaredError(name='mse'),
    tf.keras.metrics.Accuracy(name='accuracy'),
    tfma.metrics.MeanLabel(name='mean_label'),
    tfma.metrics.MeanPrediction(name='mean_prediction'),
    tfma.metrics.Calibration(name='calibration'),
    tfma.metrics.CalibrationPlot(
        name='calibration', min_value=0, max_value=10)
]
metrics_specs = tfma.metrics.specs_from_metrics(metrics)

Обратите внимание , что эта установка также доступно по телефону tfma.metrics.default_regression_specs .

Метрики двоичной классификации

Ниже приведен пример настройки конфигурации для задачи двоичной классификации. Проконсультироваться с tf.keras.metrics.* И tfma.metrics.* Модули для возможных дополнительных метрик поддерживается.

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    metrics { class_name: "ExampleCount" }
    metrics { class_name: "BinaryCrossentropy" }
    metrics { class_name: "BinaryAccuracy" }
    metrics { class_name: "AUC" }
    metrics { class_name: "AUCPrecisionRecall" }
    metrics { class_name: "MeanLabel" }
    metrics { class_name: "MeanPrediction" }
    metrics { class_name: "Calibration" }
    metrics { class_name: "ConfusionMatrixPlot" }
    metrics { class_name: "CalibrationPlot" }
  }
""", tfma.EvalConfig()).metrics_specs

Эту же настройку можно создать с помощью следующего кода Python:

metrics = [
    tfma.metrics.ExampleCount(name='example_count'),
    tf.keras.metrics.BinaryCrossentropy(name='binary_crossentropy'),
    tf.keras.metrics.BinaryAccuracy(name='accuracy'),
    tf.keras.metrics.AUC(name='auc', num_thresholds=10000),
    tf.keras.metrics.AUC(
        name='auc_precision_recall', curve='PR', num_thresholds=10000),
    tf.keras.metrics.Precision(name='precision'),
    tf.keras.metrics.Recall(name='recall'),
    tfma.metrics.MeanLabel(name='mean_label'),
    tfma.metrics.MeanPrediction(name='mean_prediction'),
    tfma.metrics.Calibration(name='calibration'),
    tfma.metrics.ConfusionMatrixPlot(name='confusion_matrix_plot'),
    tfma.metrics.CalibrationPlot(name='calibration_plot')
]
metrics_specs = tfma.metrics.specs_from_metrics(metrics)

Обратите внимание , что эта установка также доступно по телефону tfma.metrics.default_binary_classification_specs .

Метрики многоклассовой / многоклассовой классификации

Ниже приведен пример настройки конфигурации для задачи классификации нескольких классов. Проконсультироваться с tf.keras.metrics.* И tfma.metrics.* Модули для возможных дополнительных метрик поддерживается.

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    metrics { class_name: "ExampleCount" }
    metrics { class_name: "SparseCategoricalCrossentropy" }
    metrics { class_name: "SparseCategoricalAccuracy" }
    metrics { class_name: "Precision" config: '"top_k": 1' }
    metrics { class_name: "Precision" config: '"top_k": 3' }
    metrics { class_name: "Recall" config: '"top_k": 1' }
    metrics { class_name: "Recall" config: '"top_k": 3' }
    metrics { class_name: "MultiClassConfusionMatrixPlot" }
  }
""", tfma.EvalConfig()).metrics_specs

Эту же настройку можно создать с помощью следующего кода Python:

metrics = [
    tfma.metrics.ExampleCount(name='example_count'),
    tf.keras.metrics.SparseCategoricalCrossentropy(
        name='sparse_categorical_crossentropy'),
    tf.keras.metrics.SparseCategoricalAccuracy(name='accuracy'),
    tf.keras.metrics.Precision(name='precision', top_k=1),
    tf.keras.metrics.Precision(name='precision', top_k=3),
    tf.keras.metrics.Recall(name='recall', top_k=1),
    tf.keras.metrics.Recall(name='recall', top_k=3),
    tfma.metrics.MultiClassConfusionMatrixPlot(
        name='multi_class_confusion_matrix_plot'),
]
metrics_specs = tfma.metrics.specs_from_metrics(metrics)

Обратите внимание , что эта установка также доступно по телефону tfma.metrics.default_multi_class_classification_specs .

Бинаризованные метрики с несколькими классами и метками

Метрики Мультиклассовые / мульти-метка может быть бинаризуется дл получени метрики в каждом классе, за top_k, и т.д. , используя tfma.BinarizationOptions . Например:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    binarize: { class_ids: { values: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] } }
    // Metrics to binarize
    metrics { class_name: "AUC" }
    ...
  }
""", tfma.EvalConfig()).metrics_specs

Эту же настройку можно создать с помощью следующего кода Python:

metrics = [
    // Metrics to binarize
    tf.keras.metrics.AUC(name='auc', num_thresholds=10000),
    ...
]
metrics_specs = tfma.metrics.specs_from_metrics(
    metrics, binarize=tfma.BinarizationOptions(
        class_ids={'values': [0,1,2,3,4,5,6,7,8,9]}))

Мультиклассовые / многокомпонентные агрегированные показатели

Показатели Мульти-класс / мульти-метка могут быть объединены для получения единого агрегированного значения для бинарной классификации с помощью метрики tfma.AggregationOptions .

Обратите внимание , что параметры агрегации не зависит от бинаризации настроек , так что вы можете использовать как tfma.AggregationOptions и tfma.BinarizationOptions одновременно.

Микро-средний

Micro усреднение может быть выполнено с помощью micro_average опции в пределах tfma.AggregationOptions . Например:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    aggregate: { micro_average: true }
    // Metrics to aggregate
    metrics { class_name: "AUC" }
    ...
  }
""", tfma.EvalConfig()).metrics_specs

Эту же настройку можно создать с помощью следующего кода Python:

metrics = [
    // Metrics to aggregate
    tf.keras.metrics.AUC(name='auc', num_thresholds=10000),
    ...
]
metrics_specs = tfma.metrics.specs_from_metrics(
    metrics, aggregate=tfma.AggregationOptions(micro_average=True))

Micro усреднения также поддерживает настройки top_k где только верхние значения K используются в вычислении. Например:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    aggregate: {
      micro_average: true
      top_k_list: { values: [1, 3] }
    }
    // Metrics to aggregate
    metrics { class_name: "AUC" }
    ...
  }
""", tfma.EvalConfig()).metrics_specs

Эту же настройку можно создать с помощью следующего кода Python:

metrics = [
    // Metrics to aggregate
    tf.keras.metrics.AUC(name='auc', num_thresholds=10000),
    ...
]
metrics_specs = tfma.metrics.specs_from_metrics(
    metrics,
    aggregate=tfma.AggregationOptions(micro_average=True,
                                      top_k_list={'values': [1, 3]}))

Макро / взвешенное макро-среднее

Macro усреднение может быть выполнено с помощью macro_average или weighted_macro_average варианты в tfma.AggregationOptions . Если top_k не используются настройки, макро требует установки class_weights для того , чтобы знать , какие классы , чтобы вычислить среднее значение для. Если class_weight не предусмотрено , то предполагается , 0.0. Например:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    aggregate: {
      macro_average: true
      class_weights: { key: 0 value: 1.0 }
      class_weights: { key: 1 value: 1.0 }
      class_weights: { key: 2 value: 1.0 }
      class_weights: { key: 3 value: 1.0 }
      class_weights: { key: 4 value: 1.0 }
      class_weights: { key: 5 value: 1.0 }
      class_weights: { key: 6 value: 1.0 }
      class_weights: { key: 7 value: 1.0 }
      class_weights: { key: 8 value: 1.0 }
      class_weights: { key: 9 value: 1.0 }
    }
    // Metrics to aggregate
    metrics { class_name: "AUC" }
    ...
  }
""", tfma.EvalConfig()).metrics_specs

Эту же настройку можно создать с помощью следующего кода Python:

metrics = [
    // Metrics to aggregate
    tf.keras.metrics.AUC(name='auc', num_thresholds=10000),
    ...
]
metrics_specs = tfma.metrics.specs_from_metrics(
    metrics,
    aggregate=tfma.AggregationOptions(
        macro_average=True, class_weights={i: 1.0 for i in range(10)}))

Как микро усреднения, макро усреднения также поддерживает настройки top_k где только верхние значения K используются в вычислении. Например:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    aggregate: {
      macro_average: true
      top_k_list: { values: [1, 3] }
    }
    // Metrics to aggregate
    metrics { class_name: "AUC" }
    ...
  }
""", tfma.EvalConfig()).metrics_specs

Эту же настройку можно создать с помощью следующего кода Python:

metrics = [
    // Metrics to aggregate
    tf.keras.metrics.AUC(name='auc', num_thresholds=10000),
    ...
]
metrics_specs = tfma.metrics.specs_from_metrics(
    metrics,
    aggregate=tfma.AggregationOptions(macro_average=True,
                                      top_k_list={'values': [1, 3]}))

Показатели на основе запросов / ранжирования

Query / ранжирования на основе метрик включены путем указания query_key опции в метриках спецификации. Например:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    query_key: "doc_id"
    metrics {
      class_name: "NDCG"
      config: '"gain_key": "gain", "top_k_list": [1, 2]'
    }
    metrics { class_name: "MinLabelPosition" }
  }
""", tfma.EvalConfig()).metrics_specs

Эту же настройку можно создать с помощью следующего кода Python:

metrics = [
    tfma.metrics.NDCG(name='ndcg', gain_key='gain', top_k_list=[1, 2]),
    tfma.metrics.MinLabelPosition(name='min_label_position')
]
metrics_specs = tfma.metrics.specs_from_metrics(metrics, query_key='doc_id')

Метрики оценки нескольких моделей

TFMA поддерживает одновременную оценку нескольких моделей. Когда выполняется многомодельная оценка, метрики будут рассчитываться для каждой модели. Например:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    # no model_names means all models
    ...
  }
""", tfma.EvalConfig()).metrics_specs

Если показатели должны быть вычислены для подмножества моделей, установите model_names в metric_specs . Например:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    model_names: ["my-model1"]
    ...
  }
""", tfma.EvalConfig()).metrics_specs

specs_from_metrics API также поддерживает прохождение названия модели:

metrics = [
    ...
]
metrics_specs = tfma.metrics.specs_from_metrics(
    metrics, model_names=['my-model1'])

Метрики сравнения моделей

TFMA поддерживает оценку показателей сравнения модели-кандидата с базовой моделью. Простой способ настроить пару кандидата и базовой модели - передать eval_shared_model с соответствующими именами модели (tfma.BASELINE_KEY и tfma.CANDIDATE_KEY):


eval_config = text_format.Parse("""
  model_specs {
    # ... model_spec without names ...
  }
  metrics_spec {
    # ... metrics ...
  }
""", tfma.EvalConfig())

eval_shared_models = [
  tfma.default_eval_shared_model(
      model_name=tfma.CANDIDATE_KEY,
      eval_saved_model_path='/path/to/saved/candidate/model',
      eval_config=eval_config),
  tfma.default_eval_shared_model(
      model_name=tfma.BASELINE_KEY,
      eval_saved_model_path='/path/to/saved/baseline/model',
      eval_config=eval_config),
]

eval_result = tfma.run_model_analysis(
    eval_shared_models,
    eval_config=eval_config,
    # This assumes your data is a TFRecords file containing records in the
    # tf.train.Example format.
    data_location="/path/to/file/containing/tfrecords",
    output_path="/path/for/output")

Метрики сравнения вычисляются автоматически для всех сравниваемых метрик (в настоящее время только метрики скалярных значений, такие как точность и AUC).

Метрики модели с несколькими выходами

TFMA поддерживает оценку метрик на моделях с разными выходными данными. Модели с несколькими выходами хранят свои прогнозы выходных данных в форме словаря с ключом по имени выхода. Когда мульти-вывода модели, используются, имена выходов , связанных с набором метрик должны быть определены в output_names секции MetricsSpec. Например:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    output_names: ["my-output"]
    ...
  }
""", tfma.EvalConfig()).metrics_specs

specs_from_metrics API также поддерживает прохождение имен выходных:

metrics = [
    ...
]
metrics_specs = tfma.metrics.specs_from_metrics(
    metrics, output_names=['my-output'])

Настройка параметров метрики

TFMA позволяет настраивать параметры, которые используются с различными метриками. Например , вы можете захотеть изменить название, установленные пороговые значения и т.д. Это делается путем добавления config раздела в метрическую конфигурацию. Конфигурации задаются с использованием строки версии JSON параметров , которые будут переданы в метрике __init__ методы (для простоты использования ведущего и задняя «{» и «}» скобки могут быть опущены). Например:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    metrics {
      class_name: "ConfusionMatrixAtThresholds"
      config: '"thresholds": [0.3, 0.5, 0.8]'
    }
  }
""", tfma.MetricsSpec()).metrics_specs

Эта настройка, конечно, также поддерживается напрямую:

metrics = [
   tfma.metrics.ConfusionMatrixAtThresholds(thresholds=[0.3, 0.5, 0.8]),
]
metrics_specs = tfma.metrics.specs_from_metrics(metrics)

Выходы

Результатом оценки метрики является серия ключей / значений показателей и / или ключей / значений графика в зависимости от используемой конфигурации.

Метрические ключи

MetricKeys определяются с использованием структурированного типа ключа. Этот ключ однозначно определяет каждый из следующих аспектов метрики:

  • Метрика имя ( auc , mean_label и т.д.)
  • Название модели (используется только при оценке нескольких моделей)
  • Имя выхода (используется только при оценке моделей с несколькими выходами)
  • Подключ (например, идентификатор класса, если модель мультикласса преобразована в двоичную форму)

Значение показателя

MetricValues определяются с использованием прото , что encapulates различных типов значений , поддерживаемых различными метриками (например , в double , ConfusionMatrixAtThresholds и т.д.).

Ниже перечислены поддерживаемые типы значений показателей:

  • double_value - обертка для двойного типа.
  • bytes_value - это байты значения.
  • bounded_value - представляет собой реальное значение , которое может представлять собой оценку точечно, необязательно с приближенными границами некоторого вида. Имеет свойство value , lower_bound и upper_bound .
  • value_at_cutoffs - Значение в обрезаний (например , точность @ K, напомним @ K). Имеет свойство values , каждое из которых имеет свойства cutoff и value .
  • confusion_matrix_at_thresholds - Замешательство матрица на порогах. Имеет свойство matrices , каждые из которых имеет свойство для threshold , precision , recall , и значения матрицы путаницы , такие как false_negatives .
  • array_value - Для метрик , которые возвращают массив значений.

Ключи к сюжету

PlotKeys похожи на метрические ключи исключением того, что по историческим причинам все значения участки сохраняются в одном прото так ключевой сюжет не имеет названия.

Стоимость участка

Все поддерживаемые участки хранятся в одном прото называется PlotData .

EvalResult

Возвращение из прогона оценки является tfma.EvalResult . Эта запись содержит slicing_metrics , которые кодируют метрический ключ как Dict многоуровневого где уровни соответствуют имя выходного, идентификатор класса, метрический имя и значение метрики соответственно. Это предназначено для использования для отображения пользовательского интерфейса в записной книжке Jupiter. Если доступ к нижележащим данным , необходимые в metrics результате файл должен быть использован вместо (см metrics_for_slice.proto ).

Настройка

В дополнение к настраиваемым метрикам, которые добавляются как часть сохраненных керасов (или устаревшей модели EvalSavedModel). Существует два способа настройки метрик в пост-сохранении TFMA: (1) путем определения пользовательского класса метрик keras и (2) путем определения пользовательского класса метрик TFMA, поддерживаемого объединителем лучей.

В обоих случаях метрики настраиваются путем указания имени класса метрики и связанного модуля. Например:

from google.protobuf import text_format

metrics_specs = text_format.Parse("""
  metrics_specs {
    metrics { class_name: "MyMetric" module: "my.module"}
  }
""", tfma.EvalConfig()).metrics_specs

Пользовательские метрики Keras

Для создания пользовательского keras метрики, пользователи должны расширить tf.keras.metrics.Metric с их реализацией , а затем убедитесь , что модуль Метрики доступен во время оценки.

Обратите внимание , что для метрик , добавленных после сохранения модели, TFMA поддерживает только показатели , которые имеют метку (т.е. y_true), прогнозирование (y_pred), и пример вес (sample_weight) в качестве параметров update_state метода.

Пример метрики Кераса

Ниже приведен пример настраиваемой метрики keras:

class MyMetric(tf.keras.metrics.Mean):

  def __init__(self, name='my_metric', dtype=None):
    super(MyMetric, self).__init__(name=name, dtype=dtype)

  def update_state(self, y_true, y_pred, sample_weight=None):
    return super(MyMetric, self).update_state(
        y_pred, sample_weight=sample_weight)

Пользовательские метрики TFMA

Для создания пользовательского TFMA метрики, пользователи должны расширить tfma.metrics.Metric с их реализацией , а затем убедитесь , что модуль Метрики доступен во время оценки.

Метрическая

tfma.metrics.Metric реализация состоит из множества kwargs , которые определяют конфигурацию метрики вместе с функцией для создания вычислений (возможно , несколько) , необходимых для calcuate значения метрики. Есть два основных типа вычислений , которые могут быть использованы: tfma.metrics.MetricComputation и tfma.metrics.DerivedMetricComputation , которые описаны в разделах ниже. В функцию, которая создает эти вычисления, будут переданы следующие параметры в качестве входных данных:

  • eval_config: tfam.EvalConfig
    • Конфигурация eval, переданная оценщику (полезна для поиска параметров спецификации модели, таких как ключ прогнозирования и т. Д.).
  • model_names: List[Text]
    • Список названий моделей, для которых рассчитываются метрики (нет, если для одной модели)
  • output_names: List[Text] .
    • Список имен выходных данных для вычисления метрик (нет, если для одной модели)
  • sub_keys: List[tfma.SubKey] .
    • Список подключей (идентификатор класса, верхний K и т. Д.) Для вычисления метрик (или нет)
  • aggregation_type: tfma.AggregationType
    • Тип агрегирования при вычислении метрики агрегирования.
  • class_weights: Dict[int, float] .
    • Веса классов, используемые при вычислении показателя агрегирования.
  • query_key: Text
    • Ключ запроса, используемый при вычислении метрики на основе запроса / ранжирования.

Если метрика не связана с одним или несколькими из этих параметров, она может не включать эти параметры в определение сигнатуры.

Если метрика вычисляется так же , как для каждой модели, выходной, и к югу от ключа, то утилита tfma.metrics.merge_per_key_computations может быть использован для выполнения тех же вычисления для каждого из этих входов отдельно.

Метрические вычисления

MetricComputation состоит из комбинации preprocessor и combiner . preprocessor является beam.DoFn , который принимает экстракты в качестве входных данных и выводит начальное состояние , которое будет использоваться в объединитель (см архитектуры для получения дополнительной информации о том , что выдержки). Если preprocessor не определен, то сумматор будет передан StandardMetricInputs (стандартные метрические входы содержат метки, предсказание, и example_weights). combiner является beam.CombineFn , который принимает кортеж (ключ среза, выходной Препроцессор) в качестве входных данных и выводит кортеж (slice_key, метрические результаты Dict) в качестве результата.

Обратите внимание , что разрезание происходит между preprocessor и combiner .

Замечу , что если вычисление метрики хочет использовать оба стандартных метрические входы, но увеличить его с некоторыми из особенностей от features экстрактов, то специальный FeaturePreprocessor может быть использован , который будет объединять запрашиваемые функции из нескольких комбайнеров в единый общее значение StandardMetricsInputs, которое передается всем комбайнерам (комбайнеры несут ответственность за чтение интересующих их функций и игнорирование остальных).

Пример

Ниже приведен очень простой пример определения метрики TFMA для вычисления ExampleCount:

class ExampleCount(tfma.metrics.Metric):

  def __init__(self, name: Text = 'example_count'):
    super(ExampleCount, self).__init__(_example_count, name=name)


def _example_count(
    name: Text = 'example_count') -> tfma.metrics.MetricComputations:
  key = tfma.metrics.MetricKey(name=name)
  return [
      tfma.metrics.MetricComputation(
          keys=[key],
          preprocessor=_ExampleCountPreprocessor(),
          combiner=_ExampleCountCombiner(key))
  ]


class _ExampleCountPreprocessor(beam.DoFn):

  def process(self, extracts: tfma.Extracts) -> Iterable[int]:
    yield 1


class _ExampleCountCombiner(beam.CombineFn):

  def __init__(self, metric_key: tfma.metrics.MetricKey):
    self._metric_key = metric_key

  def create_accumulator(self) -> int:
    return 0

  def add_input(self, accumulator: int, state: int) -> int:
    return accumulator + state

  def merge_accumulators(self, accumulators: Iterable[int]) -> int:
    accumulators = iter(accumulators)
    result = next(accumulator)
    for accumulator in accumulators:
      result += accumulator
    return result

  def extract_output(self,
                     accumulator: int) -> Dict[tfma.metrics.MetricKey, int]:
    return {self._metric_key: accumulator}

DerivedMetricComputation

DerivedMetricComputation состоит из функции результата , который используется для вычисления значений метрик , основанных на выходе других метрических вычислений. Функция результата принимает в качестве входных данных список вычисленных значений и выводит список дополнительных результатов метрики.

Обратите внимание, что допустимо (рекомендуется) включать вычисления, от которых зависит производное вычисление, в список вычислений, созданных метрикой. Это позволяет избежать предварительного создания и передачи вычислений, которые совместно используются несколькими метриками. Оценщик автоматически устранит дублирование вычислений с таким же определением, поэтому фактически выполняется только одно вычисление.

Пример

В метриках TJUR обеспечивает хороший пример полученных метрик.