4
$\begingroup$

The simplest version of the issue that I am looking for help is:

How to detect the correct distribution from a small sample size in R by using fitdistrplus

A simpler version:

I am generating some random numbers with Gamma distribution and fitting these random numbers to different distributions (Lognormal, Weibull, Exp, Gamma), but unfortunately the AIC obtained from Gamma is not always the minimum AIC, I appreciate if someone could help me to find an approach to detect Gamma after fitting even for a small sample size.

Longer version:

I am generating some random numbers with Gamma distribution. In order to do that I need three parameters:Number of random numbers, shape and scale. I am using pre-calculated shape and scale and for the number of random numbers, this varies from 40 to 120. I know that if shape gets close to 1 it is difficult to distinguish exp, gamma and Weibull as stated here, so I am trying to keep shape far away from 1. Sample size is another matter and if I increase my sample size the results will be much better, but I have to keep my sample size small. I am trying to detect Gamma after fitting with a high accuracy but seems it is not possible. I am thinking of changing the method from mle to qme or something else but not sure which one I shall go for. I have tried a few of them but no success as I am not a statistician. Another issue is that I considered not only the lowest AIC to detect the best-fitted distribution, but also by using some other parameters such as std error of the fitting, but no success. I appreciate any help especially in simple terms:). Please let me know if you need more information.

So this is my code in R:

library(fitdistrplus)

require(distr)

shapegoriginal=0.769230769230769
scalegoriginal=78
numberofrandomnumbers=60
numbeoftrial=100
counter_AIC_fitw=0;
counter_AIC_fitl=0;
counter_AIC_fitgamma=0;
counter_AIC_fite=0;
out <- matrix(NA, nrow=numbeoftrial, ncol=13)
for(i in 1:numbeoftrial) {
        nn=(rgamma(numberofrandomnumbers, shape = shapegoriginal, 
                    scale = scalegoriginal))
        fite=fitdist (nn ,'exp')
        lambda=fite[1]$estimate[1]

        fitl=fitdist (nn ,'lnorm')
        meanl=fitl[1]$estimate[1] 
	sdl=fitl[1]$estimate[2]   
    
        fitw=fitdist (nn  ,'weibull')
        shape=fitw[1]$estimate[1] 
	scale=fitw[1]$estimate[2]
        
        fitgamma=fitdist (nn ,'gamma')
        shapeg=fitgamma[1]$estimate[1] 
	scaleg=1/fitgamma[1]$estimate[2]
        
        AIC_fitw=summary(fitw)$aic
   	AIC_fitl=summary(fitl)$aic
        AIC_fitgamma=summary(fitgamma)$aic
   	AIC_fite=summary(fite)$aic
        
        min_AIC=min(AIC_fitw,AIC_fitl,AIC_fitgamma,AIC_fite)
            
        if(min_AIC==AIC_fitw){counter_AIC_fitw=counter_AIC_fitw+1 }
        if(min_AIC==AIC_fitl){counter_AIC_fitl=counter_AIC_fitl+1}
        if(min_AIC==AIC_fitgamma)
           {counter_AIC_fitgamma=counter_AIC_fitgamma+1}
        if(min_AIC==AIC_fite){counter_AIC_fite=counter_AIC_fite+1}
            out[i,]=c(i, lambda, meanl, sdl, shape, scale, shapeg, 
            scaleg, AIC_fitw, AIC_fitl, AIC_fitgamma, AIC_fite, min_AIC)
            
    }
print('#when Weibull detected')
print(counter_AIC_fitw)
print('#when Lognormal detected')
print(counter_AIC_fitl)
print('#when Gamma detected')
print(counter_AIC_fitgamma)
print('#when Exp detected')
print(counter_AIC_fite)
colnames(out)=c('i', 'lambda', 'meanl', 'sdl', 'shape', 'scale', 
                'shapeg', 'scaleg', 'AIC_fitw', 'AIC_fitl', 
                'AIC_fitgamma', 'AIC_fite', 'min_AIC')

out

A short explanation:

The reason for having this approach with this small sample size is as follows: I have some devices which only detects a small portion of passing objects and I am trying to find out which distribution the inter-arrival of these objects have. So, instead of fitting these inter-arrival times to fitdist, I am investigating the accuracy of this approach. My sample size is about 40 to 120 per hour. Shape and scale are calculated based on the typical mean and sd of these inter-arrivals per hour

$\endgroup$
1
  • $\begingroup$ Any idea?what about if I check the density of these distributions based on the parameters(shape,scale,mean,..) which I get from fitdist? $\endgroup$ Commented Feb 10, 2017 at 20:04

1 Answer 1

0
$\begingroup$

First AIC parameter is used to find what model best fit your data. you generated vector of data that follow gama distribution with certain parameters, your next step is not to look for AIC ili BIC but to compare your data with this generated values to confirm if those two datasets come from same distribution (gamma). You should use KS.test to compare datasets, p values will tell you if this correct.

If you want to fit generated data to gamma you should get starting parameters for shape and scale...

1. generate vector nn
nn <- rgamma(100, shape = 0.769230769230769, scale = 78)

2. 
   > fitlndist <- fitdist(nn,"lnorm")
   > fitwedist <- fitdist(nn, "weibull")
   > fitgammadist <- fitdist(nn,"gamma")

3. 
   > summary(fitlndist)
Fitting of the distribution ' lnorm ' by maximum likelihood 
Parameters : 
        estimate Std. Error
meanlog 3.272449  0.1680574
sdlog   1.680574  0.1188343
Loglikelihood:  -521.0523   AIC:  1046.105   BIC:  1051.315 
Correlation matrix:
        meanlog sdlog
meanlog       1     0
sdlog         0     1

    > summary(fitwedist)
Fitting of the distribution ' weibull ' by maximum likelihood 
Parameters : 
        estimate Std. Error
shape  0.8452515 0.06980877
scale 55.1395899 6.83242053
Loglikelihood:  -506.383   AIC:  1016.766   BIC:  1021.976 
Correlation matrix:
          shape     scale
shape 1.0000000 0.2971663
scale 0.2971663 1.0000000


> summary(fitgammadist)
Fitting of the distribution ' gamma ' by maximum likelihood 
Parameters : 
       estimate Std. Error
shape 0.7372576 0.08885377
rate  0.0123892 0.00205807
Loglikelihood:  -505.1706   AIC:  1014.341   BIC:  1019.552 
Correlation matrix:
          shape      rate
shape 1.0000000 0.7175698
rate  0.7175698 1.0000000

As you can see, gamma distribution have lowest AIC and BIC. We can use ks.test, using parameters from "fitgammadist"

result is

> nnnew <- rgamma(100, shape = 0.7372576, rate = 0.0123892)
> ks.test(nnnew, nn)

    Two-sample Kolmogorov-Smirnov test

data:  nnnew and nn
D = 0.18, p-value = 0.07832
alternative hypothesis: two-sided

we proved that both datasets follow gamma distribution

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.