Sta*_*eff 5 .net c# excel accord.net
我正在尝试将以前通过Excel工作表提供的一些功能实现到C#应用程序中,但Accord.NET的概率质量功能由于某种原因与excel功能不同.
在Excel中probabilty群发功能,使用这种方法
=BINOM.DIST(250; 3779; 0.0638; FALSE)
Result: 0.021944019794458
Run Code Online (Sandbox Code Playgroud)
当我尝试使用Accord.NET时
var binom = new BinomialDistribution(3779, 0.0638);
binom.ProbabilityMassFunction(250);
// Result: Infinity
Run Code Online (Sandbox Code Playgroud)
但累积分布似乎正常工作(除了最后几位数,但我认为这只是某种精度误差)
Excel中:
=BINOM.DIST(250; 3779; 0.0638; TRUE)
Result: 0.736156366002849
Run Code Online (Sandbox Code Playgroud)
Accord.NET:
var binom = new BinomialDistribution(3779, 0.0638);
binom.DistributionFunction(250);
// Result: 0.736156366002318
Run Code Online (Sandbox Code Playgroud)
为什么结果如此不同?有没有办法通过Accord获得Excel结果?
编辑: Extreme.Numerics计算与Excel相同的结果,但我不想使用此库,因为此库的许可证系统在过去总是导致麻烦.
编辑2:似乎某种溢出错误.
当我使用它时,我得到了正确的结果:
Math.Exp(binom.LogProbabilityMassFunction(250));
Run Code Online (Sandbox Code Playgroud)
任何想法为什么会发生这种情况?
检查Accord.NET实现的源代码,可以看出它ProbabilityMassFunction是这样的:
//...
return Special.Binomial(numberOfTrials, k) * Math.Pow(probability, k)
* Math.Pow(1 - probability, numberOfTrials - k);
Run Code Online (Sandbox Code Playgroud)
你的情况numberOfTrials是3779和k是250.的二项式功能3779上250是大于10 398,这似乎太多的double数据类型(大致范围是高达有点超过10 308).所以你进入Infinity第一个乘法项,这决定了最终的结果.
我不确定如何Extreme.Numerics实现,但你的结果表明他们以更聪明的方式做到了.另外,遗憾的是,Accord.NET似乎没有提供decimal其界面版本.
这个问题似乎已在最新的Accord.NET实现中得到修复.该实现现在看起来如下:
double log = Special.LogBinomial(numberOfTrials, k) + k * Math.Log(probability)
+ (numberOfTrials - k) * Math.Log(1 - probability);
return Math.Exp(log);
Run Code Online (Sandbox Code Playgroud)