T 检验聚合
编辑T 检验聚合编辑
t_test
指标聚合,它对从聚合文档中提取的数值执行统计假设检验,在零假设下,检验统计量遵循学生 t 分布。实际上,这将告诉您两个总体均值之间的差异是否具有统计学意义,并且不是偶然发生的。
语法编辑
t_test
聚合在孤立情况下如下所示
{ "t_test": { "a": "value_before", "b": "value_after", "type": "paired" } }
假设我们有升级前后节点启动时间的记录,让我们看一下 t 检验,看看升级是否以有意义的方式影响了节点启动时间。
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
GET node_upgrade/_search { "size": 0, "aggs": { "startup_time_ttest": { "t_test": { "a": { "field": "startup_time_before" }, "b": { "field": "startup_time_after" }, "type": "paired" } } } }
响应将返回检验的 p 值或概率值。它是假设零假设正确(这意味着总体均值之间没有差异)的情况下,获得至少与聚合处理的结果一样极端的结果的概率。较小的 p 值意味着零假设更有可能不正确,并且总体均值确实不同。
T 检验类型编辑
t_test
聚合支持非配对和配对双样本 t 检验。可以使用 type
参数指定检验类型
-
"type": "paired"
- 执行配对 t 检验
-
"type": "homoscedastic"
- 执行双样本等方差检验
-
"type": "heteroscedastic"
- 执行双样本不等方差检验(这是默认值)
过滤器编辑
也可以使用过滤器对不同记录集运行非配对 t 检验。例如,如果我们想测试升级前两组不同节点的启动时间差异,我们使用相同的字段 startup_time_before
,但使用组名称字段上的术语过滤器对不同组的节点进行分组
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
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" } } } }
字段 |
|
任何将两组分开的查询都可以在这里使用。 |
|
我们使用相同的字段 |
|
但我们使用不同的过滤器。 |
|
由于我们拥有来自不同节点的数据,因此我们无法使用配对 t 检验。 |
总体不必位于同一个索引中。如果数据集位于不同的索引中,则可以使用 _index
字段上的术语过滤器来选择总体。
脚本编辑
如果您需要对无法通过字段清晰表示的值运行 t_test
,则应在 运行时字段 上运行聚合。例如,如果您想调整之前值的加载时间
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
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" } } } }