是否有一种算法可以估算一组值的中值,众数,偏度和/或峰度,但这不需要一次将所有值存储在内存中?
我想计算基本统计数据:
计算其中任何一个的基本公式是小学算术,我确实知道它们。也有许多实现它们的统计资料库。
我的问题是我正在处理的集合中有大量(十亿个)值:在Python中工作,我不能仅仅创建包含数十亿个元素的列表或哈希。即使我用C编写了此代码,十亿个元素的数组也不太实用。
数据未排序。它是由其他过程动态随机产生的。每个集合的大小是高度可变的,并且大小不会事先知道。
我已经弄清楚了如何很好地处理均值和方差,以任意顺序遍历集合中的每个值。(实际上,就我而言,我按照生成它们的顺序来处理它们。)这是我使用的算法,由http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#On- line_algorithm提供:
这种“在线”算法具有弱点(例如,由于sum_of_squares迅速增长到大于整数范围或浮点精度的精度问题),但是它基本上满足了我的需要,而不必在每个集合中存储每个值。
但我不知道是否存在类似的技术来估算其他统计信息(中位数,众数,偏度,峰度)。只要处理N个值所需的内存大大小于O(N),我就可以使用有偏估计器,甚至可以使用在某种程度上损害准确性的方法。
如果该库具有“在线”计算这些操作中的一项或多项的功能,则将我指向现有的统计信息库也将有所帮助。
偏度和峰度
有关偏度和峰度的在线算法(沿方差行),请参见此处的同一Wiki页面上的并行算法,以获取较高矩的统计信息。
中位数
没有排序的数据,中位数很难。如果您知道有多少个数据点,那么从理论上讲,您仅需要进行部分排序即可,例如,使用选择算法。但是,这对数十亿美元的价值并没有太大帮助。我建议使用频率计数,请参阅下一节。
中值和频率计数模式
如果它是整数,我会计算 频率,可能会截断最高和最低值,超出我确定不再相关的某个值。对于浮点数(或太多整数),我可能会创建存储桶/区间,然后使用与整数相同的方法。基于频率表,(近似)模式和中值计算变得容易。
正态分布随机变量
如果它是正态分布的,我将使用总体样本均值,方差,偏度和峰度作为一小部分子集的最大似然估计量。您已经在使用(在线)算法来计算这些算法。例如,读取数十万或数百万个数据点,直到您的估计误差变得足够小为止。只需确保从集合中随机选择即可(例如,通过选择前100000个值不会引入偏差)。同样的方法也可以用于正常情况的估计模式和中位数(两个样本均值都是估计量)。
进一步的评论
如果有帮助,可以并行运行以上所有算法(包括许多排序和选择算法,例如QuickSort和QuickSelect)。
我一直假设(关于正态分布的部分除外)我们谈论的是样本矩,中值和众数,而不是给定已知分布的理论矩的估计量。
一般而言,只要所有观测值都是相同随机变量(具有相同分布)以及矩,模式和该分布实际上存在中位数。最后的警告并非无害。例如,柯西分布的均值(以及所有更高的矩)不存在。在这种情况下,“小”子集的样本均值可能与整个样本的样本均值相差很大。