在Mathematica中使用DistributionFitTest[]进行自定义分布的拟合测试

8

我有两个自定义分布的PDF和CDF,可以生成每个分布的RandomVariates,并且有用于拟合数据参数的代码。之前我在以下链接中发布过一些代码:

在Mathematica中计算自定义分布的期望

以下是其中一部分代码:

nlDist /: PDF[nlDist[alpha_, beta_, mu_, sigma_], 
   x_] := (1/(2*(alpha + beta)))*alpha* 
   beta*(E^(alpha*(mu + (alpha*sigma^2)/2 - x))* 
      Erfc[(mu + alpha*sigma^2 - x)/(Sqrt[2]*sigma)] + 
     E^(beta*(-mu + (beta*sigma^2)/2 + x))* 
      Erfc[(-mu + beta*sigma^2 + x)/(Sqrt[2]*sigma)]); 

nlDist /: 
  CDF[nlDist[alpha_, beta_, mu_, sigma_], 
   x_] := ((1/(2*(alpha + beta)))*((alpha + beta)*E^(alpha*x)* 
        Erfc[(mu - x)/(Sqrt[2]*sigma)] - 
       beta*E^(alpha*mu + (alpha^2*sigma^2)/2)*
        Erfc[(mu + alpha*sigma^2 - x)/(Sqrt[2]*sigma)] + 
       alpha*E^((-beta)*mu + (beta^2*sigma^2)/2 + alpha*x + beta*x)*
        Erfc[(-mu + beta*sigma^2 + x)/(Sqrt[2]*sigma)]))/ 
   E^(alpha*x);         

dplDist /: PDF[dplDist[alpha_, beta_, mu_, sigma_], x_] := 
  PDF[nlDist[alpha, beta, mu, sigma], Log[x]]/x;
dplDist /: CDF[dplDist[alpha_, beta_, mu_, sigma_], x_] := 
  CDF[nlDist[alpha, beta, mu, sigma], Log[x]];

nlDist /: DistributionDomain[nlDist[alpha_, beta_, mu_, sigma_]] := 
 Interval[{-Infinity, Infinity}]

nlDist /: 
    Random`DistributionVector[
    nlDist [alpha_, beta_, mu_, sigma_], n_, prec_] :=
    RandomVariate[ExponentialDistribution[alpha], n, 
        WorkingPrecision -> prec] - 
      RandomVariate[ExponentialDistribution[beta], n, 
        WorkingPrecision -> prec] + 
      RandomVariate[NormalDistribution[mu, sigma], n, 
        WorkingPrecision -> prec];

dplDist /: 
    Random`DistributionVector[
    dplDist[alpha_, beta_, mu_, sigma_], n_, prec_] :=
    Exp[RandomVariate[ExponentialDistribution[alpha], n, 
         WorkingPrecision -> prec] - 
       RandomVariate[ExponentialDistribution[beta], n, 
         WorkingPrecision -> prec] + 
       RandomVariate[NormalDistribution[mu, sigma], n, 
         WorkingPrecision -> prec]];

我可以发布更多的代码供其他人查看,但我认为上面的内容已经很好地阐述了目前的方法。

现在我需要一种方法来使用DistributionFitTest()来处理这些分布,像这样:

DistributionFitTest[data, dplDist[3.77, 1.34, -2.65, 0.40],"HypothesisTestData"]  

啊,但这并不起作用。相反,我收到了一个错误消息,其开头为:

“参数 dplDist [3.77、1.34、-2.65、0.4] 应该是有效的分布……”

所以看来 DistributionFitTest[] 不认识这些分布。

我不知道如何在这种情况下使用 TagSet 会有所帮助,除非可以使用 TagSet 给 DistributionFitTest[] 提供其需要的内容来识别这些自定义分布。

有人能告诉我如何使其起作用吗?我想使用像这样的自定义分布进行 DistributionFitTest[],或找到一些解决方法来评估拟合度。

谢谢 - Jagra

1个回答

15

由于这个问题已经出现了很多次,我认为现在是时候提供一些如何正确地编写v8自定义分布的示例了。

使用TagSet来定义你的分布:

  1. DistributionParameterQDistributionParameterAssumptionsDistributionDomain
  2. 定义PDFCDFSurvivalFunctionHazardFunction
  3. 通过编写Random`DistributionVector代码来定义随机数生成代码

这样做将使得你的分布除了参数估计外的所有工作都能正常运行。

你的错误是dplDist没有DistributionDomain的定义,另外nlDistdplDist都没有定义DistributionParameterQDistributionParameterAssumptions

我在你的定义中添加了以下内容:

dplDist /: DistributionDomain[dplDist[alpha_, beta_, mu_, sigma_]] := 
 Interval[{-Infinity, Infinity}]

nlDist /: 
 DistributionParameterQ[nlDist[alpha_, beta_, mu_, sigma_]] := ! 
  TrueQ[Not[
    Element[{alpha, beta, sigma, mu}, Reals] && alpha > 0 && 
     beta > 0 && sigma > 0]]

dplDist /: 
 DistributionParameterQ[dplDist[alpha_, beta_, mu_, sigma_]] := ! 
  TrueQ[Not[
    Element[{alpha, beta, sigma, mu}, Reals] && alpha > 0 && 
     beta > 0 && sigma > 0]]

nlDist /: 
 DistributionParameterAssumptions[
  nlDist[alpha_, beta_, mu_, sigma_]] := 
 Element[{alpha, beta, sigma, mu}, Reals] && alpha > 0 && beta > 0 && 
  sigma > 0

dplDist /: 
 DistributionParameterAssumptions[
  dplDist[alpha_, beta_, mu_, sigma_]] := 
 Element[{alpha, beta, sigma, mu}, Reals] && alpha > 0 && beta > 0 && 
  sigma > 0

现在它可以正常工作:

In[1014]:= data = RandomVariate[dplDist[3.77, 1.34, -2.65, 0.40], 100];

In[1015]:= DistributionFitTest[data, dplDist[3.77, 1.34, -2.65, 0.40],
  "HypothesisTestData"]

Out[1015]= HypothesisTestData[<<DistributionFitTest>>]

2
不错!我认为你可以将这个(如果你愿意,还可以加上更多细节)添加到我们的小工具包帖子中的“未记录(或很少记录)功能”部分。our little ToolBag post - Dr. belisarius
周到、信息丰富,揭示了引擎内部的运作原理。我想知道编写教程的人是否能够提供一个关于整个主题的详细教程?它可能还涵盖拟合参数、矩等所有需要让自定义分布与Mathematica无缝协作的内容。再次感谢——Jagra - Jagra
对于LogLikelihood也适用吗?基本上,您是否必须使用TagSet来定义自定义分布上的每个可能函数? - jfelectron
@jfelectron 是的,对于 LogLikelihood 也是一样的。 - Sasha
@Jagra Wolfram技术会议2011年研讨会“创建您自己的分布”演示文稿现在可以从此处下载。 - Sasha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接