【问题标题】:Calculating a trimmed mean at scale按比例计算修剪后的平均值
【发布时间】:2020-06-17 05:55:44
【问题描述】:

我目前有一个数据集,在 Elasticsearch 中有许多数据点(大约数十亿)。我以 Elasticsearch 提供的方式(平均值、中位数、百分位数等)对这些文档进行统计。

但是我现在需要Trimmed Mean 计算。简而言之,这是您订购数据,并从数据的两侧(高位和低位)取出 x% 并计算剩余数据点的平均值的时候。例如,收入的 5% 修剪平均值将消除收入最低 5% 和收入最高 5% 的人,并对剩余的收入值取平均值

它旨在衡量集中趋势,以减少主要异常值的影响。

但是,据我所知,Elasticsearch 不支持这一点,而且我找不到很多支持的东西。即使是百分位数之类的事情也很难大规模进行,但 Elasticsearch 有一些算法可以进行一些估计(我认为它们是基于数据草图,但我不完全确定)。

我可以通过查询我的数据的两个百分位数(x percentile 和 100-x percentile)来重新创建这种效果,然后执行第三个查询,过滤掉这些数据点并计算平均值。这行得通,但现在我正在执行三个相对较长的查询,理想情况下希望在我的数据集上来回最小化。

我说我正在使用 Elasticsearch,这在解决方案方面更可取,但真的欢迎任何建议

【问题讨论】:

    标签: elasticsearch statistics mean


    【解决方案1】:

    我认为不可能一次性完成,但这是我的两步操作。

    首先使用percentiles 聚合计算修剪限制。

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

    但需要注意的是,对于数十亿个值,百分位聚合将 probably be approximate 和非确定性(对同一查询产生不同的结果)。


    以上查询计算:

    {
     ...
      "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
            }
          }
        }
      }
    }
    

    您可以使用statsextended_stats,具体取决于您实际需要多少信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-10
      • 1970-01-01
      • 2021-12-11
      相关资源
      最近更新 更多