T-test aggregation
集約された文書から抽出された数値に対して、帰無仮説の下で統計的仮説検定を行う t_test
メトリクス集約であり、検定統計量はスチューデントのt分布に従います。実際には、これは2つの母集団の平均の違いが統計的に有意であり、単に偶然によって発生したものではないかを示します。
Syntax
単独での t_test
集約は次のようになります:
Js
{
"t_test": {
"a": "value_before",
"b": "value_after",
"type": "paired"
}
}
アップグレード前後のノードの起動時間の記録があると仮定して、アップグレードがノードの起動時間に意味のある影響を与えたかどうかを確認するためにt検定を見てみましょう。
Python
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)
Ruby
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
Js
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);
Console
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値が小さいほど、帰無仮説が誤っている可能性が高く、母集団の平均が実際に異なることを示します。
Console-Result
{
...
"aggregations": {
"startup_time_ttest": {
"value": 0.1914368843365979
}
}
}
p値。 |
T-Test Types
t_test
集約は、非対応および対応の2サンプルt検定をサポートしています。検定のタイプは、type
パラメータを使用して指定できます:
"type": "paired"
- 対応t検定を実行します
"type": "homoscedastic"
- 2サンプル等分散検定を実行します
"type": "heteroscedastic"
- 2サンプル不等分散検定を実行します(これがデフォルトです)
Filters
フィルターを使用して異なるレコードセットで非対応t検定を実行することも可能です。たとえば、2つの異なるノードグループ間でアップグレード前の起動時間の違いをテストしたい場合、グループ名フィールドに対して用語フィルターを使用して、同じフィールド startup_time_before
を異なるノードグループで使用します:
Python
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)
Ruby
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
Js
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);
Console
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 は数値フィールドでなければなりません。 |
|
2つのグループを分けるクエリはここで使用できます。 | |
同じフィールドを使用していますが | |
異なるフィルターを使用しています。 | |
異なるノードからのデータがあるため、対応t検定を使用できません。 |
Console-Result
{
...
"aggregations": {
"startup_time_ttest": {
"value": 0.2981858007281437
}
}
}
p値。 |
母集団は同じインデックスに存在する必要はありません。データセットが異なるインデックスにある場合、_index
フィールドに対する用語フィルターを使用して母集団を選択できます。
Script
フィールドによってきれいに表現されていない値に対して t_test
を実行する必要がある場合は、ランタイムフィールド で集約を実行してください。たとえば、前の値のロード時間を調整したい場合:
Python
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)
Ruby
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
Js
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);
Console
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"
}
}
}
}