什么是获得输入文件或std out数据流的近似行数的最快方法。仅供参考,这是一个概率算法,我在网上找不到很多例子。
数据可能只是来自csv文件的awk脚本的一列或两列!让我们说我想在其中一个列上使用aprox groupby。我会使用数据库组,但行数超过6-7亿。我希望第一个近似结果在3到4秒内。然后在对先前做出决定之后运行贝叶斯或其他东西。关于一个非常粗略的初始组计数的任何想法?
如果你能在python或java中提供算法示例,那将非常有帮助。
答案 0 :(得分:5)
groupby
,估计不同群体的百分比更有意义。)
我将首先假设您只有两个组(可以使用扩展程序使其适用于多个组,请参阅后面的解释。),group1
和group2
。
对于您处理的第一个m
行(行)中的group1
n
,我们将该事件表示为M(m,n)
。显然,您会看到n-m
group2
,因为我们假设他们是唯一两个可能的群组。因此,您知道事件M(m,n)
的条件概率给定group1
(s
)的百分比,由具有n
次试验的二项分布给出。我们正试图以贝叶斯方式估算s
。
二项式的共轭前缀是β分布。因此,为简单起见,我们选择Beta(1,1)
作为先验(当然,您可以在alpha
和beta
选择您自己的参数),这是(0,1)上的均匀分布。因此,对于此测试版分发,alpha=1
和beta=1
。
二项式+ beta先验的递归更新公式如下:
if group == 'group1':
alpha = alpha + 1
else:
beta = beta + 1
s
的后验实际上也是一个beta分布:
s^(m+alpha-1) (1-s)^(n-m+beta-1)
p(s| M(m,n)) = ----------------------------------- = Beta (m+alpha, n-m+beta)
B(m+alpha, n-m+beta)
其中B
是beta function。要报告估算结果,您可以依赖Beta
distribution's均值和方差,其中:
mean = alpha/(alpha+beta)
var = alpha*beta/((alpha+beta)**2 * (alpha+beta+1))
groupby.py
从stdin
开始处理数据的几行python并估计group1
的百分比如下所示:
import sys
alpha = 1.
beta = 1.
for line in sys.stdin:
data = line.strip()
if data == 'group1':
alpha += 1.
elif data == 'group2':
beta += 1.
else:
continue
mean = alpha/(alpha+beta)
var = alpha*beta/((alpha+beta)**2 * (alpha+beta+1))
print 'mean = %.3f, var = %.3f' % (mean, var)
我向代码提供了几行数据:
group1
group1
group1
group1
group2
group2
group2
group1
group1
group1
group2
group1
group1
group1
group2
以下是我得到的结果:
mean = 0.667, var = 0.056
mean = 0.750, var = 0.037
mean = 0.800, var = 0.027
mean = 0.833, var = 0.020
mean = 0.714, var = 0.026
mean = 0.625, var = 0.026
mean = 0.556, var = 0.025
mean = 0.600, var = 0.022
mean = 0.636, var = 0.019
mean = 0.667, var = 0.017
mean = 0.615, var = 0.017
mean = 0.643, var = 0.015
mean = 0.667, var = 0.014
mean = 0.688, var = 0.013
mean = 0.647, var = 0.013
结果显示,在处理完第15行之前,group1估计有64.7%的百分比(基于之前的beta(1,1))。你可能会注意到方差不断缩小,因为我们有越来越多的观察点。
现在,如果您有两个以上的组,只需将下划线分布从二项式更改为多项式,然后相应的conjugate prior将是Dirichlet。其他一切你只是做出类似的改变。
你说你想在3-4秒内估计一下。在这种情况下,您只需对数据的一部分进行采样并将输出提供给上述脚本,例如
head -n100000 YOURDATA.txt | python groupby.py
就是这样。希望能帮助到你。
答案 1 :(得分:3)
如果假设数据是IID是合理的(因此没有偏差,例如在流的某些部分出现某些类型的记录),那么只需按照近似大小对子计数进行二次采样和放大。
说出前百万条记录(这应该可以在几秒钟内完成)。它的大小是 x 单位(MB,字符,无论你关心什么)。完整流的大小为 y ,其中 y >> X 。现在,从样本 x 中得出你关心的任何数量,并简单地用因子 y / * x *来计算它们的近似完全计数。例如:您想要在整个流中大致了解第1列的值为 v 的记录数。第一百万条记录的文件大小为100MB,而文件总大小为10GB。在第一百万条记录中,150,000条记录中第1列的值为 v 。因此,您假设在完整的10GB记录中,您将看到150,000 *(10,000,000,000 / 100,000,000)= 15,000,000值。您在样本上计算的任何统计数据都可以简单地按相同因子进行缩放,以产生估算值。
如果数据中存在偏差,使得某些记录或多或少可能位于文件的某些位置,那么您应该从总集中随机(或间隔均匀)选择样本记录。这将确保一个无偏见的,有代表性的样本,但可能会产生更大的I / O开销。