【问题标题】:Estimate / fit data to exGaussian distribution in Android在 Android 中估计/拟合数据到 exGaussian 分布
【发布时间】:2017-05-16 12:33:36
【问题描述】:

如何使用 JAVA/Android 估计/拟合指数修正高斯分布 (exGaussian) 的参数?

我需要类似下面的伪代码:

    // some observed data points
    double dataPoints[] = {200,300,400,278,366,466,325,335,322,332};

    // ex-gaussian distribution
    ExponentiallyModifiedGaussianDistribution exGaussian = new ExponentiallyModifiedGaussianDistribution();

    // MLE
    MaximumLikelihoodEstimation MLE = new MaximumLikelihoodEstimation(dataPoints, exGaussian);
    MLE.setGuess(3.0, 1.0, 1.0);
    MLE.compute();

    // get estimated / fitted parameters
    double[] parameterEstimates = MLE.getEstimates();

有一些示例演示了 Gamma Distribution 的参数估计。但是这个库似乎不是开源的。

我在 JAVA 中找到了ex-gaussian distribution implementation。但是缺少参数估计。

我认为有很多方法可以估计参数,例如使用最大似然估计(MLE)等。

更新 1:

我会避免使用less than 40 dataPoints

更新 2:

估计分布参数的一个简单替代方法是矩估计方法 (described on wiki)

【问题讨论】:

    标签: java android mathematical-optimization mle


    【解决方案1】:

    ELKI 包含用于分布的各种估计器(请注意,对于某些分布,我们有多种估计技术;而对于某些我们还没有 - 请贡献 !):

    ExponentiallyModifiedGaussianDistribution dist = 
        EMGOlivierNorbergEstimator.STATIC.estimate(dataPoints, DoubleArrayAdapter.STATIC);
    

    将产生 ExGaussian 分布:

    > ExGaussianDistribution(mean=0.2675761092764285, stddev=0.07999178722695827,
          lambda=4.4179732613344)
    

    您也可以尝试最合适的估计。

    Distribution dist = BestFitEstimator.STATIC.estimate(dataPoints, DoubleArrayAdapter.STATIC);
    

    这表明移位的对数法线可能更适合您的数据(但是,理论上 EMG 可能更适合您的问题 - 移位的对数法线总是有点奇怪)。

    > LogNormalDistribution(logmean=-1.945322593396174, logstddev=0.968522285758599,
          shift=0.2654438504801123)
    

    【讨论】:

      【解决方案2】:

      也许您可以在 stats.stackexchange.com 上获得更好的答案。

      但我认为您可以创建一个优化算法来进行矩匹配。基本上你需要最小化样本数据与理论分布之间的一阶矩(均值)、二阶矩(方差)、三阶矩(偏度)等的差异。

      您可以将目标函数视为矩的总和或乘积。您还可以对时刻使用不同的权重(均值获得更高的权重)。

      您可以尝试使用梯度下降法(使用 Mathematica 或 Sage 数学)来获得目标函数的导数,甚至可以使用有限差分法进行数值计算。这种方法被大量用于估计回归、逻辑回归和人工神经网络的参数。

      您也可以使用元启发式算法(遗传、禁忌搜索等)。

      【讨论】:

      • 所以我也许可以使用 Nelder-Mead simplex/optimizer 来估计参数。 java中有一个现有的lib。
      • 在维基百科的文章中,他们建议使用前 3 个时刻。 en.wikipedia.org/wiki/… "(...) 分布的参数可以通过矩量法从样本数据中估计出来:[4][5] (...)"
      • 我可以计算平均值和标准偏差。但是y1呢? γ1 是偏度。如何获得只有一些数据点的值?
      • y1 =(平均值/中位数)/标准偏差。我在章节倾斜下方发现了这一点。感谢您的帮助!
      【解决方案3】:

      估计分布参数的一个简单替代方法是矩量法 (described on wiki)。

      实施:

          // some observed data points
          double dataPoints[] = {0.464,0.443,0.424,0.386,0.367,0.382,0.455,0.410,0.411,0.424,0.338,0.355,0.342,0.324,
                  0.354,0.322,0.364,0.375,1.085,0.575,0.597,0.464,0.414,0.408,1.156,0.819,1.156,1.024,1.152,1.103,
                  0.431,0.378,0.358,0.382,0.354,0.435,0.386,0.361,0.397,0.362,0.334,0.357,0.344,0.362,0.317,0.331,
                  0.199,0.351,0.284,0.343,0.354,0.336,0.280,0.312,0.778,0.723,0.755,0.774,0.759,0.762,0.490,0.400,
                  0.364,0.439,0.441,0.673};
      
          DescriptiveStatistics maths = new DescriptiveStatistics(dataPoints);
          double sampleMean = maths.getMean();
          double sampleStdDev = maths.getStandardDeviation();
          double sampleSkev = (Math.abs(sampleMean - maths.getPercentile(50)) / sampleStdDev);
      
          // parameter estimation using method of moments ex-gaussian distribution
          double mean = sampleMean - sampleStdDev * Math.pow(sampleSkev/2., 1./3) ;
          double stdDev = Math.sqrt(sampleStdDev*(1 - Math.pow(sampleSkev/2., 2./3)));
          double tau = sampleStdDev * (Math.pow(sampleSkev/2., 1./3));
          double lambda = 1 / tau;
      
          ExponentiallyModifiedGaussianDistribution exGaussian = new ExponentiallyModifiedGaussianDistribution(mean, stdDev, lambda);
          System.out.println(sampleStdDev);
          System.out.println(exGaussian.getStddev());
      

      Gradle 依赖项:

      编译组:'de.lmu.ifi.dbs.elki',名称:'elki',版本:'0.7.1'

      编译组:'org.apache.commons',名称:'commons-math3',版本: '3.6'

      【讨论】:

      猜你喜欢
      • 2013-12-13
      • 2011-05-16
      • 1970-01-01
      • 2014-03-19
      • 2012-05-17
      • 2019-01-13
      • 1970-01-01
      • 2020-07-31
      • 2016-11-10
      相关资源
      最近更新 更多