第五次假账克星NO.1

来源:互联网 发布:php curl 伪装浏览器 编辑:程序博客网 时间:2024/04/30 15:21
假设走在大街上,随机选择一些人,让他们每人随便写下一个数字,得到的数字的分布将很有可能不是均匀的分布。这很容易理解,比如,中国人就比较避讳数字4,而倾向于数字6或8等。

如果一个公司做假账,自作聪明的伪造者试图在账目中间“隐藏”数据,绝大多数情况下他们都很难高明到不露马脚。2001年,“9.11”事件发生后不久,曾是美国最大的能源交易商、年营业收入达近千亿美元、股票市值最高可达700多亿美元、全球500强中排名第七的安然公司在事先没有任何征兆的情况下突然宣布破产。不久就传出了该公司高层管理人员涉嫌做假账的丑闻,一时间,会计造假成了中外关注的焦点。

研究人员从安然公司所公布的一些数据进行统计分析,果然发现了一些征兆。例如,安然公司在2001年度到2002年度所公布的每股盈利数字的分布就有问题,这些数字的使用频率与一个著名的定律--Benford's law(本福特定律)有较大的偏差,说明这些盈利数据一定是经过篡改后的。

Benford2

图:本福特定律、真实税收数据、伪造数据、随机数据的数字分布

来源(http://www.flatrock.org.nz/topics/intellect_and_entertain/following_benfords_law.htm

Benford's law本福特定律,是关于某些类型数据的开头数字的分布规律的,该定律与你的直觉可能有些偏离:大多数人会认为,世界上千千万万的数据(非0开头)的开头数字是1到9的任何一个数字,而且每个数字开头的概率应该差不多。现在,请你随便找本书,统计一下上面的各种开头数据的开头数字,看看是否符合设想。如果你统计的数据足够多,你就会惊讶的发现,并非每个数字出现的概率均等,实际中以1为开头的数字出现的频率并不是人们想当然认为的1/9,而是0.301,这说明30%的数字都以1开头。而2为首的数字出现的频率是0.176,3开头的数字出现的频率为0.125,往后出现频率依此减少,9打头的数字出现的频率最低,只有0.046。

除了在会计账目数字上,定律的发现者,美国的物理学家Benford,发现各种完全不同的数据,比如人口,死亡率,物理和化学常数,棒球统计表,半衰期放射性同位素,对数表,物理书中的答案,素数数字中均有这个定律的身影。本福特定律在我们的日常生活中很常见。对于财务数据,有趣的是,数学家们还发现,在那些假账中,数字5和6居然是最常见的打头数字,而不是符合定律的数字1。如果审核账本的审计人员掌握了“本福特定律”,伪造者们要通过审计就会相当的困难。Benford定律因此也被誉为“假账克星”。

该定理甚至还可以用于发现选举投票中的欺诈行为。选举投票的票数数据也符合这个定律,如果有人修改票数量,就会漏出蛛丝马迹来。研究人员依据这一定律发现了2004年美国总统选举中佛罗里达州的投票欺诈行为,2004年委内瑞拉的投票欺诈和2006年墨西哥投票欺诈。前段时间的伊朗的大选可谓轰轰隆隆,颇引人注目,内贾德在胜出之后却引来一片质疑,有科学家就尝试用Benford定律去发现是否存在投票欺诈行为(链接)。

=====

本题要求你验证Benford定律,对给定的一段文本,分别算出其中以每个数字1-9打头的数据的比例并输出。

输入:

数据文件(filesize.txt,某文件存储设备上各种文件的尺寸),里面包含很多整数数据,每个数据占一行。

输出:

数字1-9打头的数据所占的比例。为了便于自动检查结果。请使用格式化输出,格式化字符串为

"%d: %6.1f%%\n"
其中第一个参数为数字1-9,第二个参数为对应的百分比。
import java.util.Scanner;  /* * 假账克星   * 参数K和T,以及用起始时刻ts ,终止时刻te 和 增量dt表示的一个时间区间[ts ,te )。包含ts ,但不含te  */public class Main {        public static void main(String[] args) {          Scanner scanner = new Scanner(System.in);          double K = scanner.nextDouble();          double T = scanner.nextDouble();          int ts = scanner.nextInt();          int te = scanner.nextInt();          double dt = scanner.nextDouble();          double a;          int len = 0;          for(int i=0;(ts+i*dt)<te;i++){              a = Math.exp(K*((ts+i*dt)-T))/(1+Math.exp(K*((ts+i*dt)-T)));              System.out.printf(" %4.3f",a);              len++;              if(len==10){                  System.out.println();                  len = 0;              }          }          if(len != 0){              System.out.println();          }      }  }


原创粉丝点击