Change Dir

先知cd——热爱生活是一切艺术的开始

统计

留言簿(18)

积分与排名

“牛”们的博客

各个公司技术

我的链接

淘宝技术

阅读排行榜

评论排行榜

Commons Math学习笔记——随机生成和统计初步

 

3.3 随机生成和统计初步

看其他篇章到目录选择。

概率统计最基本的前提就是有数据,而我们做模拟或者测试时总会用到大量的随机数据。我们知道绝对的随机是做不到的,但是可以利用算法来实现伪随机数的生成。Commons Math库提供了一个random的包,其中定义实现了很多可以用来生成随机数的类和接口。random包中定义了5个接口,分别是EmpiricalDistributionNormalizedRandomGeneratorRandomDataRandomGeneratorRandomVectorGenerator。其中EmpiricalDistribution接口是对经验概率分布的一个定义,指在不做任何假设下对观测数据得到的经验分布。其中有void load(URL url)方法来从一个计算经验分布,其中的方法参数还可以是一个File对象或者直接是一个double数组。它的StatisticalSummary getSampleStats()方法返回一个StatisticalSummary对象,这个类在stat包中有定义,可以得到观测数据的均值、方差等相应的统计度量。EmpiricalDistributionImpl实现了该接口,其中内部用到了RandomData接口,而且定义了一个内部抽象类DataAdapter,不同的load方式会有不同的内部具体类去继承这个内部抽象类,而计算统计度量的方式也是直接调用了StatisticalSummary的方法,这个类的作用重点在构造,具体的计算和生成还是在RandomDataRandomGenerator中。RandomData接口是随机数据生成的一个应用接口,其中定义了各种next***的方法来生成随机数,比如double nextExponential(double mean)返回一个服从均值为mean的指数分布的随机数。RandomDataImpl类具体实现了这个接口,具体的实现都是依赖RandomGenerator的(其实这是不准确的,因为用到的RandomGeneratorJDKRandomGenerator,这个类是继承了jdk中的Random类,因此从本质上讲没有什么新意,不过像指数和泊松这样的分布数据是自己实现的)。所以我们重点介绍RandomGenerator接口(绕了好久啊-_-!),RandomGenerator接口有几个具体实现,其中刚才说到的JDKRandomGenerator是其中之一,还有两个抽象类是BitsStreamGeneratorAbstractRandomGeneratorMersenneTwister继承了BitsStreamGenerator,这个类是原作者C算法的一个Java实现,可以在相关资料中去查询论文原文。另外几个接口就不说了,用法其实都类似,用到的直接查API就可以了。说了这么多介绍性的东西,还是直接用代码说话比较方便,在实际应用中,可能最常用的还是RandomData

 1/**
 2 * 
 3 */

 4package algorithm.math;
 5
 6import org.apache.commons.math.random.RandomData;
 7import org.apache.commons.math.random.RandomDataImpl;
 8import org.apache.commons.math.stat.Frequency;
 9import org.apache.commons.math.stat.StatUtils;
10
11/**
12 * @author Jia Yu
13 * @date   2010-12-4
14 */

15public class RandomTest {
16
17    /**
18     * @param args
19     */

20    public static void main(String[] args) {
21        // TODO Auto-generated method stub
22        random();
23    }

24
25    private static void random() {
26        // TODO Auto-generated method stub
27        RandomData randomData = new RandomDataImpl();
28        
29        //Generate a random int value uniformly distributed between lower and upper, inclusive
30        System.out.println("a uniform value: "+randomData.nextInt(16));
31        //Returns a random value from an Exponential distribution with the given mean
32        System.out.println("a Exponential value: "+randomData.nextExponential(5));
33        //Generate a random value from a Normal
34        System.out.println("a Normal value: "+randomData.nextGaussian(01));
35        //Generates a random value from the Poisson distribution with the given mean
36        System.out.println("a Poisson value: "+randomData.nextPoisson(3));
37        //Generates an integer array of length k whose entries are selected randomly, without repetition, from the integers 0 through n-1
38        int[] a = randomData.nextPermutation(103);
39        for(int i=0;i<a.length;i++){
40            System.out.print(a[i]+" ");
41        }

42        System.out.println();
43        
44        //generate 1000 numbers between 0 and 3 inclusive, then using frequency to see the distribution
45        Frequency freq = new Frequency();
46        int value = 0;
47        for (int i = 0; i < 1000; i++{
48            value = randomData.nextInt(03);
49            freq.addValue(value);
50        }

51        long[] observed = new long[4];
52        double[] perc = new double[4];
53        for (int i = 0; i < 4; i++{
54            observed[i] = freq.getCount(i);
55            perc[i] = freq.getPct(i);
56            System.out.println("there are "+observed[i]+" "+i+" in dataset with "+(perc[i]*100)+"%");
57        }

58        
59        //stat test
60        double[] data = {1d,2d,2d,3d};
61        System.out.println("sum of data is "+StatUtils.sum(data));
62        System.out.println("sum of square of data is "+StatUtils.sumSq(data));
63        System.out.println("var of data is "+StatUtils.variance(data));
64        System.out.println("mean of data is "+StatUtils.mean(data));
65        System.out.println("max value of data is "+StatUtils.max(data));
66        System.out.println("min value of data is "+StatUtils.min(data));
67        System.out.println("geometry mean of data is "+StatUtils.geometricMean(data));
68        System.out.println("product of data is "+StatUtils.product(data));
69    }

70
71}

72


看看结果:
a uniform value: 6
a Exponential value: 3.4850055739123356
a Normal value: -0.510139146901537
a Poisson value: 4
1 4 3
there are 266 0 in dataset with 26.6%
there are 234 1 in dataset with 23.400000000000002%
there are 240 2 in dataset with 24.0%
there are 260 3 in dataset with 26.0%
sum of data is 8.0
sum of square of data is 18.0
var of data is 0.6666666666666666
mean of data is 2.0
max value of data is 3.0
min value of data is 1.0
geometry mean of data is 1.8612097182041993
product of data is 12.0

 

关于代码中的Frequency类和StatUtils类,这是stat包中的两个基本类。Frequency负责统计数据的频率,通过addValue方法来添加数据,再利用getCount得到频率,利用getPct得到对应数据所占比例。还可以利用getCumFreqgetCumPct得到累积的统计信息。StatUtils则是对stat下面子包descriptive中的一些类的调用。包括上面部分讲random的时候提到的StatisticalSummary接口,这些都是descriptive包中的基本接口。其中UnivariateStatistic表示单元统计信息,包括了均值、标准差、中值、最大最小、求和与高阶矩等统计量的实现,这是统计中的最基本的接口,其他接口都基于此实现或封装。另外还有多元统计接口StatisticalMultivariateSummary用来得到一些多元统计量。

这两个包没有根据结构画出类图,我觉得这块的可扩展性不是太大,概念和计算太基础,只要会利用就OK了。

相关资料:

MersenneTwisterhttp://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/ARTICLES/mt.pdf

统计:http://zh.wikipedia.org/zh-cn/%E7%BB%9F%E8%AE%A1%E5%AD%A6

Commons math包:http://commons.apache.org/math/index.html

posted on 2011-01-01 18:30 changedi 阅读(3273) 评论(0)  编辑  收藏 所属分类: 数学


只有注册用户登录后才能发表评论。


网站导航: