在上篇,我了解了基数的基本概念,现在进入Linear Counting算法的学习。 理解颇浅,还请大神指点!
http://blog.codinglabs.org/articles/algorithms-for-cardinality-estimation-part-ii.html
它的基本处理方法和上篇中用bitmap统计的方法类似,但是最后要用到一个公式:
说明:m为bitmap总位数,u为0的个数,最后的结果为n的一个估计,且为最大似然估计(MLE)。
那么问题来了,最大似然估计是什么东东?好像在学概率论的时候听说过,于是又去搜索了一下MLE的信息。
MLE:(此处不使用概率论中的各种符号及表示方法,按我自己的理解写)
以下内容参考链接:http://blog.csdn.net/yanqingan/article/details/6125812
假设进行一个实验,实验次数定为10次,每次实验成功率为0.2,那么不成功的概率为0.8,用n来表示成功的次数。
事件之间是相互独立的,于是可以得到成功次数的概率:
成功次数 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
概率 | 0.107374 | 0.268435 | 0.301990 | 0.201327 | 0.088080 | 0.026424 | 0.005505 | 0.000786 | 0.000074 | 0.000004 | 0.000000 |
以上数据由下述程序计算:
1 #include <stdio.h> 2 #define N 10 3 #define G 0.2 4 5 int factorial(int n) 6 { 7 int i; 8 int ret = 1; 9 for(i = 1; i <= n; ++i) 10 { 11 ret *= i; 12 } 13 return ret; 14 } 15 16 double exponent(double m, int n) 17 { 18 int i; 19 double ret = 1; 20 for(i = 0; i < n; ++i) 21 { 22 ret *= m; 23 } 24 return ret; 25 } 26 27 double fun(int n) 28 { 29 return ((double)factorial(N) / factorial(n) / factorial(N - n) * exponent(G, n) * exponent(1 - G, N - n)); 30 } 31 32 int main() 33 { 34 int i; 35 for(i = 0; i <= N; ++i) 36 { 37 printf("%f ", fun(i)); 38 } 39 printf(" "); 40 }
用excel做出它的图表
而所谓概率密度,就是这一个个柱子的面积。公式如下:
所谓的最大似然估计,就是在已知成功次数n的情况下,求出每次实验成功率的最可能的值。
假设现已知成功次数为n=7,那么每次的成功概率ω可能是多少呢?
可以代入式子:
于是它成了P和ω的方程。
既然成功次数为7,那么假设n=7时,P有极大值,即求上述方程极大值。借助excel,画出它的方程曲线图:
即先求导,然后取导数的0点,即为最大可能概率:
但是这样做又不方便,又容易出错,于是可以借助对数来进行处理:
这样继续求解是不是方便多了呢?
现在回到Linear Counting算法(具体一开始头上带^的n是怎么推导的可以查看一下开关的链接,或者“A linear-time probabilistic counting algorithm for database applications”)
Linear Counting算法中,m是比n小的。我并不知道应该如何描述它,于是按个人的理解举个例子:
假设一个网站一天有n个不同的人访问,现设一m位的bitmap,将“不同的人”传入哈希函数,传出的结果填入bitmap(可能重复),最后用bitmap中的分布情况来估计n的值。
引用链接中的一个图:
每个圈代表一个人,然后用bitmap中的分布情况估计出圈的个数。
这样的估计是有误差的,所以应该对m的选择考虑一番。
结论:Linear Counting算法比直接用bitmap节约了常系数极的空间