ohG*_*osh 5 java math syntax function benfords-law
我有一个快速的问题.我试图在java中制作欺诈检测应用程序,该应用程序将主要基于本福德定律.本福德的定律非常酷,它基本上可以解释为在真实的金融交易中,第一个数字通常是1,2或3,很少是8,9.我无法得到本福德公式翻译成可以用Java运行的代码.
http://www.mathpages.com/home/kmath302/kmath302.htm此链接提供了有关本福特法律及其使用方式的更多信息.
我知道我必须使用java数学类才能使用自然日志功能,但我不知道该怎么做.任何帮助将不胜感激.
非常感谢!!
@Rui已经提到了如何计算概率分布函数,但这对你没有多大帮助.
你想要使用的是Kolmogorov-Smirnov检验或卡方检验.两者都用于将数据与已知概率分布进行比较,以确定数据集是否可能/不可能具有该概率分布.
卡方用于离散分布,KS用于连续分布.
对于使用Benford定律的卡方,你只需创建一个直方图H [N],例如9个区间N = 1,2,... 9,迭代数据集以检查第一个数字以计算样本数量9个非零数字中的每一个(或具有90个箱的前两个数字).然后运行卡方检验以将直方图与预期计数E [N]进行比较.
例如,假设您有100条数据.E [N]可以根据本福德定律计算:
E[1] = 30.1030 (=100*log(1+1))
E[2] = 17.6091 (=100*log(1+1/2))
E[3] = 12.4939 (=100*log(1+1/3))
E[4] = 9.6910
E[5] = 7.9181
E[6] = 6.6946
E[7] = 5.7992
E[8] = 5.1152
E[9] = 4.5757
Run Code Online (Sandbox Code Playgroud)
然后计算X 2 = sum((H [k] -E [k])^ 2/E [k]),并与测试中指定的阈值进行比较.(这里我们有一个没有参数的固定分布,所以参数个数s = 0和p = s + 1 = 1,并且二进制数n是9,所以自由度的数量= np = 8*.然后你去你方便的卡通表,看看数字是否正常.对于8自由度,置信水平如下:
Χ 2 > 13.362:10%的几率将数据集仍然符合本福德定律
Χ 2 > 15.507:5%的几率集仍然符合本福德定律
Χ 2 > 17.535:2.5%几率的数据集仍然符合本福德定律
Χ 2 > 20.090:1%的几率集仍然符合本福德定律
Χ 2 > 26.125:0.1%几率的数据集仍然符合本福德定律
假设你的直方图,得到H = [29,17,12,10,8,7,6,5,6],对于Χ 2 = 0.5585.这与预期的分布非常接近.(甚至可能太近了!)
现在假设你的直方图,得到H = [27,16,10,9,5,11,6,5,11],对于Χ 2 = 13.89.该直方图来自符合本福德定律的分布的可能性不到10%.所以我称这个数据集有问题但不过分.
请注意,您必须选择显着性水平(例如10%/ 5%/等).如果你使用10%,那么即使它们没问题,预计每10个真正来自本福特发行版的数据集中大约有1个会失败.这是一个判断电话.
看起来Apache Commons Math有一个卡方测试的Java实现:
ChiSquareTestImpl.chiSquare(double[] expected, long[] observed)
*关于自由度= 8的说明:这是有道理的; 你有9个数字,但它们有1个约束,即它们都必须加起来达到数据集的大小,所以一旦你知道直方图的前8个数字,就可以计算出第9个数字.
Kolmogorov-Smirnov实际上更简单(直到我找到一个关于它如何工作的简单陈述,我才意识到这一点)但是适用于连续分布.该方法的工作方式如下:
让我们更深入地处理本福德定律.
CDF用于本福德定律:这仅仅是C =日志10 x,其中x是在区间[1,10),即,包括1,但不包括10这可以,如果你看可以容易地看出本福德法广义形式,和而不是写它log(1 + 1/n),把它写成log(n + 1)-log(n) - 换句话说,为了得到每个bin的概率,它们减去log的连续差异( n),所以log(n)必须是CDF
ECDF:拿你的数据集,对每个数字,使符号为正,用科学记数法写,并将指数设置为0.(如果你有一个0的数字,不知道怎么办;这似乎不适合自己对本福德定律的分析.)然后按升序对数字进行排序.ECDF是任何有效x的数据点数<= x.
计算每个d [k] = max(CDF(y [k]) - (k-1)/ N,k/N-CDF(y [k])的最大差值D = max(d [k]).
这是一个例子:假设我们的数据集= [3.02,1.99,28.3,47,0.61].然后ECDF由排序的数组[1.99,2.83,3.02,4.7,6.1]表示,你计算D如下:
D = max(
log10(1.99) - 0/5, 1/5 - log10(1.99),
log10(2.83) - 1/5, 2/5 - log10(2.83),
log10(3.02) - 2/5, 3/5 - log10(3.02),
log10(4.70) - 3/5, 4/5 - log10(4.70),
log10(6.10) - 4/5, 5/5 - log10(6.10)
)
Run Code Online (Sandbox Code Playgroud)
其中= 0.2988(= log10(1.99) - 0).
最后你必须使用 D统计 - 我似乎无法在线找到任何有信誉的表,但Apache Commons Math有一个KolmogorovSmirnovDistributionImpl.cdf()函数,它将计算出的D值作为输入并告诉你D的概率小于此.采用1-cdf(D)可能更容易,它告诉你D大于或等于你计算的值的概率:如果这是1%或0.1%,这可能意味着数据不符合本福特定律,但如果它是25%或50%,它可能是一个很好的匹配.