看其他篇章到目录 选择。
概率分布是概率论的一个基础。
在 Commons Math包中也专门有一个子包对概率分布进行了封装实现。在 distribution包中,定义了一个基本接口 Distribution。该接口只有两个方法,一个是 double cumulativeProbability (double x),一个是 double cumulativeProbability
(double x0, double x1)
。前者对于服从某种分布的随机变量X,返回P(X<=x);后者则返回P(x0<=X<=x1)。正如其名所示,这样也就得到了概率。
具体 distribution包中实现了基本所有的概率分布,分为连续型分布和离散型分布,连续型包括了像熟悉的指数分布、柯西分布等,离散型包括了泊松分布和二项分布等等。具体的类图结构见下图:
在连续型的 ContinuousDistribution接口中,添加了一个 double inverseCumulativeProbability (double p)的方法,这个方法返回 P(X<x)=p中的 x。也就是说通过已知概率,可以求得随机变量 X的 x范围。当然看 api文档还应注意一句,在 3.0的版本中会加入 public double density(double x)这个求概率密度函数的方法,敬请期待吧。离散型的接口 DiscreteDistribution中则添加了 double probability (double x)方法,用来计算 P(X=x)的概率。
具体的代码我们以离散型的泊松分布和连续型的正态分布来讲解。泊松分布的接口继承了 IntegerDistribution接口,在此基础上加了 getMean()方法和 normalApproximateProbability()方法。正态分布 NormalDistribution继承了 ContinuousDistribution,又添加了 getMean()方法和 double density(double x)方法以及 getStandardDeviation()方法。
2 *
3 */
4 package algorithm . math;
5
6 import org . apache . commons . math . MathException;
7 import org . apache . commons . math . distribution . NormalDistribution;
8 import org . apache . commons . math . distribution . NormalDistributionImpl;
9 import org . apache . commons . math . distribution . PoissonDistribution;
10 import org . apache . commons . math . distribution . PoissonDistributionImpl;
11
12 /**
13 * @author Jia Yu
14 * @date 2010 - 11 - 28
15 */
16 public class DistributionTest {
17
18 /**
19 * @param args
20 */
21 public static void main(String[] args) {
22 // TODO Auto - generated method stub
23 poisson();
24 System . out . println( " ------------------------------------------ " );
25 normal();
26 test();
27 }
28
29 /**
30 * test for example
31 * 《饮料装填量不足与超量的概率》
32 * 某饮料公司装瓶流程严谨,每罐饮料装填量符合平均600毫升,标准差3毫升的常态分配法则。随机选取一罐,容量超过605毫升的概率?容量小于590毫升的概率
33 * 容量超过605毫升的概率 = p ( X > 605 ) = p ( ((X - μ) / σ) > ( ( 605 – 600 ) / 3 ) ) = p ( Z > 5 / 3 ) = p( Z > 1.67 ) = 0.0475
34 * 容量小于590毫升的概率 = p (X < 590 ) = p ( ((X - μ) / σ) < ( ( 590 – 600 ) / 3 ) ) = p ( Z < - 10 / 3 ) = p( Z < - 3.33 ) = 0.0004
35 */
36 private static void test() {
37 // TODO Auto - generated method stub
38 NormalDistribution normal = new NormalDistributionImpl( 600 , 3 );
39 try {
40 System . out . println( " P(X<590) = " + normal . cumulativeProbability( 590 ));
41 System . out . println( " P(X>605) = " + ( 1 - normal . cumulativeProbability( 605 )));
42 } catch (MathException e) {
43 // TODO Auto - generated catch block
44 e . printStackTrace();
45 }
46 }
47
48 private static void poisson() {
49 // TODO Auto - generated method stub
50 PoissonDistribution dist = new PoissonDistributionImpl( 4.0 );
51 try {
52 System . out . println( " P(X<=2.0) = " + dist . cumulativeProbability( 2.0 ));
53 System . out . println( " mean value is " + dist . getMean());
54 System . out . println( " P(X=1.0) = " + dist . probability( 1.0 ));
55 System . out . println( " P(X=x)=0.8 where x = " + dist . inverseCumulativeProbability( 0.8 ));
56 } catch (MathException e) {
57 // TODO Auto - generated catch block
58 e . printStackTrace();
59 }
60 }
61
62 private static void normal() {
63 // TODO Auto - generated method stub
64 NormalDistribution normal = new NormalDistributionImpl( 0 , 1 );
65 try {
66 System . out . println( " P(X<2.0) = " + normal . cumulativeProbability( 2.0 ));
67 System . out . println( " mean value is " + normal . getMean());
68 System . out . println( " standard deviation is " + normal . getStandardDeviation());
69 System . out . println( " P(X=1) = " + normal . density( 1.0 ));
70 System . out . println( " P(X<x)=0.8 where x = " + normal . inverseCumulativeProbability( 0.8 ));
71 } catch (MathException e) {
72 // TODO Auto - generated catch block
73 e . printStackTrace();
74 }
75 }
76
77 }
78
输出:
P(X<=2.0) = 0.23810330555354414
mean value is 4.0
P(X=1.0) = 0.07326255555493674
P(X=x)=0.8 where x = 5
------------------------------------------
P(X<2.0) = 0.9772498680518208
mean value is 0.0
standard deviation is 1.0
P(X=1) = 0.24197072451914337
P(X<x)=0.8 where x = 0.8416212335731417
P(X<590) = 4.290603331968401E-4
P(X>605) = 0.047790352272814696
泊松分布只需要给定参数 λ 即可,而其期望就是 λ。所以构造方法一般就是new PoissonDistributionImpl(double mean)这样的形式了。
正态分布需要知道均值和方差,因此要在构造函数时传入,另外程序中以一个维基百科上的示例来验证正态分布的正确性。
相关资料:
概率分布: http://zh.wikipedia.org/zh-cn/%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83
泊松分布: http://zh.wikipedia.org/zh-cn/%E6%B3%8A%E6%9D%BE%E5%88%86%E5%B8%83
正态分布: http://zh.wikipedia.org/zh-cn/%E6%AD%A3%E6%80%81%E5%88%86%E5%B8%83
Commons math包: http://commons.apache.org/math/index.html