Spec-Zone.ru › Elasticsearch 8
›Elasticsearch Guide [8.17] ›Агрегирования ›Агрегирования метрик

Агрегирование t-теста

Агрегирование метрик t_test, выполняющее статистическую гипотезу, в которой тестовая статистика следует распределению Стьюдента при нулевой гипотезе на числовых значениях, извлечённых из агрегированных документов. На практике это позволит узнать, является ли различие между двумя средними значениями генеральных совокупностей статистически значимым и не произошло ли оно случайно.

Синтаксис

Агрегирование t_test выглядит следующим образом:

{
  "t_test": {
    "a": "value_before",
    "b": "value_after",
    "type": "paired"
  }
}

Предположим, что у нас есть запись времени запуска узла до и после обновления, давайте рассмотрим t-тест, чтобы увидеть, повлияло ли обновление на время запуска узла значимым образом.

resp = client.search(
    index="node_upgrade",
    size=0,
    aggs={
        "startup_time_ttest": {
            "t_test": {
                "a": {
                    "field": "startup_time_before"
                },
                "b": {
                    "field": "startup_time_after"
                },
                "type": "paired"
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'node_upgrade',
  body: {
    size: 0,
    aggregations: {
      startup_time_ttest: {
        t_test: {
          a: {
            field: 'startup_time_before'
          },
          b: {
            field: 'startup_time_after'
          },
          type: 'paired'
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "node_upgrade",
  size: 0,
  aggs: {
    startup_time_ttest: {
      t_test: {
        a: {
          field: "startup_time_before",
        },
        b: {
          field: "startup_time_after",
        },
        type: "paired",
      },
    },
  },
});
console.log(response);
GET node_upgrade/_search
{
  "size": 0,
  "aggs": {
    "startup_time_ttest": {
      "t_test": {
        "a": { "field": "startup_time_before" },  
        "b": { "field": "startup_time_after" },   
        "type": "paired"                          
      }
    }
  }
}

Поле startup_time_before должно быть числовым полем.

Поле startup_time_after должно быть числовым полем.

Поскольку у нас есть данные от одних и тех же узлов, мы используем парный t-тест.

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

{
  ...

 "aggregations": {
    "startup_time_ttest": {
      "value": 0.1914368843365979 
    }
  }
}

Значение p.

Типы t-тестов

Агрегирование t_test поддерживает непарные и парные двухвыборочные t-тесты. Тип теста можно указать с помощью параметра type:

"type": "paired"
выполняет парный t-тест
"type": "homoscedastic"
выполняет двухвыборочный тест с равной дисперсией
"type": "heteroscedastic"
выполняет двухвыборочный тест с неравной дисперсией (это значение по умолчанию)

Фильтры

Также можно выполнить непарный t-тест на различных наборах записей с помощью фильтров. Например, если мы хотим проверить разницу во временах запуска до обновления между двумя различными группами узлов, мы используем то же поле startup_time_before для отдельных групп узлов с помощью фильтров терминов по полю имени группы:

resp = client.search(
    index="node_upgrade",
    size=0,
    aggs={
        "startup_time_ttest": {
            "t_test": {
                "a": {
                    "field": "startup_time_before",
                    "filter": {
                        "term": {
                            "group": "A"
                        }
                    }
                },
                "b": {
                    "field": "startup_time_before",
                    "filter": {
                        "term": {
                            "group": "B"
                        }
                    }
                },
                "type": "heteroscedastic"
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'node_upgrade',
  body: {
    size: 0,
    aggregations: {
      startup_time_ttest: {
        t_test: {
          a: {
            field: 'startup_time_before',
            filter: {
              term: {
                group: 'A'
              }
            }
          },
          b: {
            field: 'startup_time_before',
            filter: {
              term: {
                group: 'B'
              }
            }
          },
          type: 'heteroscedastic'
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "node_upgrade",
  size: 0,
  aggs: {
    startup_time_ttest: {
      t_test: {
        a: {
          field: "startup_time_before",
          filter: {
            term: {
              group: "A",
            },
          },
        },
        b: {
          field: "startup_time_before",
          filter: {
            term: {
              group: "B",
            },
          },
        },
        type: "heteroscedastic",
      },
    },
  },
});
console.log(response);
GET node_upgrade/_search
{
  "size": 0,
  "aggs": {
    "startup_time_ttest": {
      "t_test": {
        "a": {
          "field": "startup_time_before",         
          "filter": {
            "term": {
              "group": "A"                        
            }
          }
        },
        "b": {
          "field": "startup_time_before",         
          "filter": {
            "term": {
              "group": "B"                        
            }
          }
        },
        "type": "heteroscedastic"                 
      }
    }
  }
}

Поле startup_time_before должно быть числовым полем.

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

Мы используем то же поле

но используем разные фильтры.

Поскольку у нас есть данные с разных узлов, мы не можем использовать парный t-тест.

{
  ...

 "aggregations": {
    "startup_time_ttest": {
      "value": 0.2981858007281437 
    }
  }
}

Значение p.

Генеральные совокупности не обязательно должны находиться в одном индексе. Если наборы данных находятся в разных индексах, можно использовать фильтр терминов по полю _index для выбора генеральных совокупностей.

Скрипт

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

resp = client.search(
    index="node_upgrade",
    size=0,
    runtime_mappings={
        "startup_time_before.adjusted": {
            "type": "long",
            "script": {
                "source": "emit(doc['startup_time_before'].value - params.adjustment)",
                "params": {
                    "adjustment": 10
                }
            }
        }
    },
    aggs={
        "startup_time_ttest": {
            "t_test": {
                "a": {
                    "field": "startup_time_before.adjusted"
                },
                "b": {
                    "field": "startup_time_after"
                },
                "type": "paired"
            }
        }
    },
)
print(resp)
response = client.search(
  index: 'node_upgrade',
  body: {
    size: 0,
    runtime_mappings: {
      'startup_time_before.adjusted' => {
        type: 'long',
        script: {
          source: "emit(doc['startup_time_before'].value - params.adjustment)",
          params: {
            adjustment: 10
          }
        }
      }
    },
    aggregations: {
      startup_time_ttest: {
        t_test: {
          a: {
            field: 'startup_time_before.adjusted'
          },
          b: {
            field: 'startup_time_after'
          },
          type: 'paired'
        }
      }
    }
  }
)
puts response
const response = await client.search({
  index: "node_upgrade",
  size: 0,
  runtime_mappings: {
    "startup_time_before.adjusted": {
      type: "long",
      script: {
        source: "emit(doc['startup_time_before'].value - params.adjustment)",
        params: {
          adjustment: 10,
        },
      },
    },
  },
  aggs: {
    startup_time_ttest: {
      t_test: {
        a: {
          field: "startup_time_before.adjusted",
        },
        b: {
          field: "startup_time_after",
        },
        type: "paired",
      },
    },
  },
});
console.log(response);
GET node_upgrade/_search
{
  "size": 0,
  "runtime_mappings": {
    "startup_time_before.adjusted": {
      "type": "long",
      "script": {
        "source": "emit(doc['startup_time_before'].value - params.adjustment)",
        "params": {
          "adjustment": 10
        }
      }
    }
  },
  "aggs": {
    "startup_time_ttest": {
      "t_test": {
        "a": {
          "field": "startup_time_before.adjusted"
        },
        "b": {
          "field": "startup_time_after"
        },
        "type": "paired"
      }
    }
  }
}

© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/8.17/search-aggregations-metrics-ttest-aggregation.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API