Расчет усеченного среднего по шкале - PullRequest
0 голосов
/ 04 марта 2020

В настоящее время у меня есть набор данных, который имеет много точек данных (порядка миллиардов) в Elasticsearch. И я делаю статистику по этим документам способами, которые предоставляет Elasticsearch (среднее значение, медиана, процентили и т. Д. c.)

Однако теперь мне нужно вычисление Trimmed Mean . Короче говоря, это когда вы упорядочиваете свои данные, снимаете x% с обеих сторон ваших данных (высокого и низкого) и вычисляете среднее значение для оставшихся точек данных. Кроме того, усеченное на 5% среднее значение дохода будет исключать тех, кто находится в нижних 5% дохода, и тех, которые находятся в верхних 5%, и делать среднее значение для оставшихся значений дохода

Это должно быть мерой центральная тенденция, которая уменьшает влияние основных выбросов.

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

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

Я сказал, что использую Elasticsearch, и это предпочтительно с точки зрения решения, но открыто на любые предложения действительно

1 Ответ

0 голосов
/ 04 марта 2020

Я не думаю, что было бы возможно сделать это за один go, но вот мой двухэтапный подход.

Сначала определите пределы обрезки, используя агрегацию percentiles.

GET billion_index/_search
{
  "size": 0,
  "aggs": {
    "boundaries": {
      "percentiles": {
        "field": "price",
        "percents": [
          5,
          95
        ]
      }
    }
  }
}

Тем не менее, важно отметить, что при миллиардах значений процентильные агрегации будут , вероятно, приблизительными и недетерминированными c (получая разные результаты для того же запроса).


Вышеупомянутый запрос вычисляет:

{
 ...
  "hits" : {
    "total" : 1558776,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "aggregations" : {
    "boundaries" : {
      "values" : {
        "5.0" : 1121.4101013907416,
        "95.0" : 1148582.9150790304
      }
    }
  }
}

Включение их в набор отфильтрованных агрегатов extended_stats:

GET billion_index/_search
{
  "size": 0,
  "aggs": {
    "standard_mean": {                 <--- for comparison of non-trimmed
      "extended_stats": {
        "field": "price"
      }
    },
    "pipelined_mean": {
      "filter": {
        "range": {
          "price": {
            "gt": 1121,                <--- filter by % transformed to real vals
            "lt": 1148582
          }
        }
      },
      "aggs": {
        "trimmed_mean": {              <--- calculate stats after having filtered
          "extended_stats": {
            "field": "price"
          }
        }
      }
    }
  }
}

доходность

{
 ...
  "aggregations" : {
    "standard_mean" : {
      "count" : 1558390,
      "min" : 0.0,
      "max" : 8.888888888E9,
      "avg" : 368803.9027932674,                  <--- standard mean
      "sum" : 5.74740314074E11,
      "sum_of_squares" : 8.645745157058162E19,
      "variance" : 5.534268385940522E13,
      "std_deviation" : 7439266.352228909,
      "std_deviation_bounds" : {
        "upper" : 1.5247336607251085E7,
        "lower" : -1.450972880166455E7
      }
    },
    "pipelined_mean" : {
      "doc_count" : 1401944,
      "trimmed_mean" : {
        "count" : 1401944,
        "min" : 1123.0,
        "max" : 1148500.0,
        "avg" : 246760.4101305045,                <--- trimmed mean, understandably lower
        "sum" : 3.4594427642E11,
        "sum_of_squares" : 1.6918684996958976E17,
        "variance" : 5.978947692482006E10,
        "std_deviation" : 244518.86823887448,
        "std_deviation_bounds" : {
          "upper" : 735798.1466082535,
          "lower" : -242277.32634724447
        }
      }
    }
  }
}

Вы можете использовать stats или extended_stats в зависимости от того, сколько информации вам действительно нужно.

...