我有一个快速的问题。我正在尝试用Java制作欺诈检测应用程序,该应用程序将主要基于本福德定律。本福德定律 super 酷,基本上可以解释为,在实际的金融交易中,第一位数通常是1、2或3,很少是8、9。我无法获得本福德公式转换为可以在Java中运行的代码。
http://www.mathpages.com/home/kmath302/kmath302.htm此链接提供有关什么是本福德法则以及如何使用本法的更多信息。
我知道我将必须使用java math类才能使用自然的日志函数,但是我不确定如何做到这一点。任何帮助将不胜感激。
非常感谢!!
最佳答案
@Rui提到了如何计算概率分布函数,但这对您没有太大帮助。
您要使用的是Kolmogorov-Smirnov test或Chi-squared test。两者均用于将数据与已知概率分布进行比较,以确定数据集是否可能/不太可能具有该概率分布。
卡方用于离散分布,而K-S用于连续分布。
为了使用符合本福德定律的卡方,您只需创建直方图H [N],例如具有9个bin的N = 1,2,... 9,遍历数据集以检查第一个数字以对9个非零数字(或具有90个bin的前两个数字)中的每个数字计数样本数。然后运行卡方检验以将直方图与预期计数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
然后计算Χ2= sum((H [k] -E [k])^ 2/E [k]),并与测试中指定的阈值进行比较。 (这里我们有一个没有参数的固定分布,因此参数s = 0且p = s + 1 = 1的个数,箱数n为9,因此自由度的个数= np = 8 *。然后转到handy-dandy chi-squared table,看看数字是否正确,对于8个自由度,置信度如下所示:
Χ2> 13.362:数据集仍然符合本福德定律的可能性为10%
Χ2> 15.507:数据集仍然符合本福德定律的可能性为5%
Χ2> 17.535:数据集仍然符合本福德定律的可能性为2.5%
Χ2> 20.090:数据集仍然符合本福德定律的几率为1%
Χ2> 26.125:数据集仍然符合本福德定律的可能性为0.1%
假设您的直方图得出X = 0.5585,则H = [29,17,12,10,8,7,6,5,6]。这非常接近预期的分布。 (甚至太近了!)
现在假设您的直方图对于Χ2= 13.89产生H = [27,16,10,9,5,11,6,5,11]。该直方图来自与本福德定律匹配的分布的可能性不到10%。因此,我称数据集有问题,但不是过分。
请注意,您必须选择显着性水平(例如10%/5%/等)。如果使用10%,则可以预期实际上来自Benford分布的每10个数据集中大约有1个失败,即使它们没问题。这是一个判断电话。
看起来Apache Commons Math具有卡方测试的Java实现:
ChiSquareTestImpl.chiSquare(double[] expected, long[] observed)
*注意自由度= 8:这是有道理的;您有9个数字,但它们有1个约束,即它们都必须加起来等于数据集的大小,因此,一旦知道直方图的前8个数字,就可以算出第九个数字。
Kolmogorov-Smirnov实际上更简单(直到我找到了关于其工作原理的足够简单的陈述后,我才意识到这一点),但可以用于连续发行版。该方法的工作方式如下:
让我们为本福德定律更深入地处理这些问题。
本福德定律的
这是一个示例:假设我们的数据集= [3.02,1.99,28.3,47,0.61]。然后,用排序后的数组[1.99,2.83,3.02,4.7,6.1]表示ECDF,并按以下方式计算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)
)
其中= 0.2988(= log10(1.99)-0)。
最后,您必须使用D统计量-我似乎无法在线找到任何信誉良好的表,但是Apache Commons Math具有KolmogorovSmirnovDistributionImpl.cdf()函数,该函数将计算出的D值作为输入,并告诉您D小于此值的可能性。 。取1-cdf(D)可能更容易,它告诉您D大于或等于您计算出的值的可能性:如果是1%或0.1%,则可能意味着数据不符合本福德定律,但如果是25%或50%,则可能是一个不错的选择。
关于java - Java中的本福德定律-如何将数学函数转换为Java,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7815155/