Bagaimana cara menentukan distribusi mana yang paling cocok dengan data saya?

133

Saya memiliki dataset dan ingin mengetahui distribusi mana yang paling cocok dengan data saya.

Saya menggunakan fitdistr()fungsi untuk memperkirakan parameter yang diperlukan untuk menggambarkan distribusi yang diasumsikan (yaitu Weibull, Cauchy, Normal). Dengan menggunakan parameter-parameter tersebut, saya dapat melakukan Tes Kolmogorov-Smirnov untuk memperkirakan apakah data sampel saya berasal dari distribusi yang sama dengan asumsi distribusi saya.

Jika nilai-p> 0,05 saya dapat mengasumsikan bahwa data sampel diambil dari distribusi yang sama. Tetapi nilai-p tidak memberikan informasi apa pun tentang godness of fit, bukan?

Jadi jika nilai-p dari data sampel saya adalah> 0,05 untuk distribusi normal dan juga distribusi weibull, bagaimana saya bisa tahu distribusi mana yang lebih cocok dengan data saya?

Ini pada dasarnya adalah apa yang telah saya lakukan:

> mydata
 [1] 37.50 46.79 48.30 46.04 43.40 39.25 38.49 49.51 40.38 36.98 40.00
[12] 38.49 37.74 47.92 44.53 44.91 44.91 40.00 41.51 47.92 36.98 43.40
[23] 42.26 41.89 38.87 43.02 39.25 40.38 42.64 36.98 44.15 44.91 43.40
[34] 49.81 38.87 40.00 52.45 53.13 47.92 52.45 44.91 29.54 27.13 35.60
[45] 45.34 43.37 54.15 42.77 42.88 44.26 27.14 39.31 24.80 16.62 30.30
[56] 36.39 28.60 28.53 35.84 31.10 34.55 52.65 48.81 43.42 52.49 38.00
[67] 38.65 34.54 37.70 38.11 43.05 29.95 32.48 24.63 35.33 41.34

# estimate shape and scale to perform KS-test for weibull distribution
> fitdistr(mydata, "weibull")
     shape        scale   
   6.4632971   43.2474500 
 ( 0.5800149) ( 0.8073102)

# KS-test for weibull distribution
> ks.test(mydata, "pweibull", scale=43.2474500, shape=6.4632971)

        One-sample Kolmogorov-Smirnov test

data:  mydata
D = 0.0686, p-value = 0.8669
alternative hypothesis: two-sided

# KS-test for normal distribution
> ks.test(mydata, "pnorm", mean=mean(mydata), sd=sd(mydata))

        One-sample Kolmogorov-Smirnov test

data:  mydata
D = 0.0912, p-value = 0.5522
alternative hypothesis: two-sided

Nilai p adalah 0,8669 untuk distribusi Weibull, dan 0,5522 untuk distribusi normal. Jadi saya dapat berasumsi bahwa data saya mengikuti Weibull serta distribusi normal. Tetapi fungsi distribusi mana yang menggambarkan data saya lebih baik?


Mengacu pada elevendollar saya menemukan kode berikut, tetapi tidak tahu bagaimana menafsirkan hasil:

fits <- list(no = fitdistr(mydata, "normal"),
             we = fitdistr(mydata, "weibull"))
sapply(fits, function(i) i$loglik)
       no        we 
-259.6540 -257.9268 
tobibo
sumber
5
Mengapa Anda ingin mengetahui distribusi mana yang paling cocok dengan data Anda?
Roland
6
Karena saya ingin menghasilkan angka pseudo-acak mengikuti distribusi yang diberikan.
tobibo
6
Anda tidak dapat menggunakan KS untuk memeriksa apakah distribusi dengan parameter yang ditemukan dari dataset cocok dengan dataset. Lihat # 2 di halaman ini misalnya, plus alternatif (dan cara-cara lain tes KS bisa menyesatkan).
tpg2114
Diskusi lain di sini dengan sampel kode tentang cara menerapkan uji KS ketika parameter diperkirakan dari sampel.
Aksakal
1
I used the fitdistr() function ..... Apa fitdistrfungsinya? Sesuatu dari Excel? Atau sesuatu yang Anda tulis sendiri di C?
serigala

Jawaban:

162

Pertama, berikut adalah beberapa komentar cepat:

  • hal
  • Sampel Anda tidak akan pernah mengikuti distribusi tertentu dengan tepat. Jadi, bahkan jika nilai- Anda dari Uji KS akan valid dan , itu hanya berarti bahwa Anda tidak dapat mengesampingkan bahwa data Anda mengikuti distribusi spesifik ini. Formulasi lain adalah bahwa sampel Anda kompatibel dengan distribusi tertentu. Tetapi jawaban untuk pertanyaan "Apakah data saya mengikuti distribusi dengan tepat?" selalu tidak.hal>0,05
  • Tujuannya di sini tidak dapat menentukan dengan pasti distribusi apa yang diikuti sampel Anda. Tujuannya adalah apa yang @whuber (dalam komentar) sebut sebagai uraian perkiraan data yang keliru . Memiliki distribusi parametrik spesifik dapat berguna sebagai model data.

Tapi mari kita lakukan eksplorasi. Saya akan menggunakan fitdistrpluspaket luar biasa yang menawarkan beberapa fungsi yang bagus untuk pemasangan distribusi. Kami akan menggunakan fungsi ini descdistuntuk mendapatkan beberapa ide tentang kemungkinan distribusi kandidat.

library(fitdistrplus)
library(logspline)

x <- c(37.50,46.79,48.30,46.04,43.40,39.25,38.49,49.51,40.38,36.98,40.00,
38.49,37.74,47.92,44.53,44.91,44.91,40.00,41.51,47.92,36.98,43.40,
42.26,41.89,38.87,43.02,39.25,40.38,42.64,36.98,44.15,44.91,43.40,
49.81,38.87,40.00,52.45,53.13,47.92,52.45,44.91,29.54,27.13,35.60,
45.34,43.37,54.15,42.77,42.88,44.26,27.14,39.31,24.80,16.62,30.30,
36.39,28.60,28.53,35.84,31.10,34.55,52.65,48.81,43.42,52.49,38.00,
38.65,34.54,37.70,38.11,43.05,29.95,32.48,24.63,35.33,41.34)

Sekarang mari kita gunakan descdist:

descdist(x, discrete = FALSE)

Descdist

Kurtosis dan skewness kuadrat dari sampel Anda adalah plot sebagai titik biru bernama "Observasi". Tampaknya kemungkinan distribusi termasuk Weibull, Lognormal, dan mungkin distribusi Gamma.

Mari kita paskan distribusi Weibull dan distribusi normal:

fit.weibull <- fitdist(x, "weibull")
fit.norm <- fitdist(x, "norm")

Sekarang periksa fit untuk yang normal:

plot(fit.norm)

Fit normal

Dan untuk Weibull:

plot(fit.weibull)

Weibull cocok

Keduanya terlihat bagus tetapi dinilai oleh QQ-Plot, Weibull mungkin terlihat sedikit lebih baik, terutama di bagian ekor. Sejalan dengan itu, AIC dari Weibull fit lebih rendah dibandingkan dengan normal:

fit.weibull$aic
[1] 519.8537

fit.norm$aic
[1] 523.3079

Simulasi tes Kolmogorov-Smirnov

Saya akan menggunakan prosedur @ Aksakal yang dijelaskan di sini untuk mensimulasikan statistik KS di bawah nol.

n.sims <- 5e4

stats <- replicate(n.sims, {      
  r <- rweibull(n = length(x)
                , shape= fit.weibull$estimate["shape"]
                , scale = fit.weibull$estimate["scale"]
  )
  estfit.weibull <- fitdist(r, "weibull") # added to account for the estimated parameters
  as.numeric(ks.test(r
                     , "pweibull"
                     , shape= estfit.weibull$estimate["shape"]
                     , scale = estfit.weibull$estimate["scale"])$statistic
  )      
})

ECDF dari statistik-KS yang disimulasikan terlihat seperti berikut:

plot(ecdf(stats), las = 1, main = "KS-test statistic simulation (CDF)", col = "darkorange", lwd = 1.7)
grid()

Simulasi KS-statistik

hal

fit <- logspline(stats)

1 - plogspline(ks.test(x
                       , "pweibull"
                       , shape= fit.weibull$estimate["shape"]
                       , scale = fit.weibull$estimate["scale"])$statistic
               , fit
)

[1] 0.4889511

Ini mengkonfirmasi kesimpulan grafis kami bahwa sampel tersebut kompatibel dengan distribusi Weibull.

Seperti yang dijelaskan di sini , kita dapat menggunakan bootstrap untuk menambahkan interval kepercayaan pointwise ke perkiraan Weibull PDF atau CDF:

xs <- seq(10, 65, len=500)

true.weibull <- rweibull(1e6, shape= fit.weibull$estimate["shape"]
                         , scale = fit.weibull$estimate["scale"])

boot.pdf <- sapply(1:1000, function(i) {
  xi <- sample(x, size=length(x), replace=TRUE)
  MLE.est <- suppressWarnings(fitdist(xi, distr="weibull"))  
  dweibull(xs, shape=MLE.est$estimate["shape"],  scale = MLE.est$estimate["scale"])
}
)

boot.cdf <- sapply(1:1000, function(i) {
  xi <- sample(x, size=length(x), replace=TRUE)
  MLE.est <- suppressWarnings(fitdist(xi, distr="weibull"))  
  pweibull(xs, shape= MLE.est$estimate["shape"],  scale = MLE.est$estimate["scale"])
}
)   

#-----------------------------------------------------------------------------
# Plot PDF
#-----------------------------------------------------------------------------

par(bg="white", las=1, cex=1.2)
plot(xs, boot.pdf[, 1], type="l", col=rgb(.6, .6, .6, .1), ylim=range(boot.pdf),
     xlab="x", ylab="Probability density")
for(i in 2:ncol(boot.pdf)) lines(xs, boot.pdf[, i], col=rgb(.6, .6, .6, .1))

# Add pointwise confidence bands

quants <- apply(boot.pdf, 1, quantile, c(0.025, 0.5, 0.975))
min.point <- apply(boot.pdf, 1, min, na.rm=TRUE)
max.point <- apply(boot.pdf, 1, max, na.rm=TRUE)
lines(xs, quants[1, ], col="red", lwd=1.5, lty=2)
lines(xs, quants[3, ], col="red", lwd=1.5, lty=2)
lines(xs, quants[2, ], col="darkred", lwd=2)

CI_Density

#-----------------------------------------------------------------------------
# Plot CDF
#-----------------------------------------------------------------------------

par(bg="white", las=1, cex=1.2)
plot(xs, boot.cdf[, 1], type="l", col=rgb(.6, .6, .6, .1), ylim=range(boot.cdf),
     xlab="x", ylab="F(x)")
for(i in 2:ncol(boot.cdf)) lines(xs, boot.cdf[, i], col=rgb(.6, .6, .6, .1))

# Add pointwise confidence bands

quants <- apply(boot.cdf, 1, quantile, c(0.025, 0.5, 0.975))
min.point <- apply(boot.cdf, 1, min, na.rm=TRUE)
max.point <- apply(boot.cdf, 1, max, na.rm=TRUE)
lines(xs, quants[1, ], col="red", lwd=1.5, lty=2)
lines(xs, quants[3, ], col="red", lwd=1.5, lty=2)
lines(xs, quants[2, ], col="darkred", lwd=2)
#lines(xs, min.point, col="purple")
#lines(xs, max.point, col="purple")

CI_CDF


Distribusi otomatis cocok dengan GAMLSS

gamlssRfitDisttype = "realline"type = "realsplus"kk=2kcatatan(n)

library(gamlss)
library(gamlss.dist)
library(gamlss.add)

x <- c(37.50,46.79,48.30,46.04,43.40,39.25,38.49,49.51,40.38,36.98,40.00,
       38.49,37.74,47.92,44.53,44.91,44.91,40.00,41.51,47.92,36.98,43.40,
       42.26,41.89,38.87,43.02,39.25,40.38,42.64,36.98,44.15,44.91,43.40,
       49.81,38.87,40.00,52.45,53.13,47.92,52.45,44.91,29.54,27.13,35.60,
       45.34,43.37,54.15,42.77,42.88,44.26,27.14,39.31,24.80,16.62,30.30,
       36.39,28.60,28.53,35.84,31.10,34.55,52.65,48.81,43.42,52.49,38.00,
       38.65,34.54,37.70,38.11,43.05,29.95,32.48,24.63,35.33,41.34)

fit <- fitDist(x, k = 2, type = "realplus", trace = FALSE, try.gamlss = TRUE)

summary(fit)

*******************************************************************
Family:  c("WEI2", "Weibull type 2") 

Call:  gamlssML(formula = y, family = DIST[i], data = sys.parent()) 

Fitting method: "nlminb" 


Coefficient(s):
             Estimate  Std. Error  t value   Pr(>|t|)    
eta.mu    -24.3468041   2.2141197 -10.9962 < 2.22e-16 ***
eta.sigma   1.8661380   0.0892799  20.9021 < 2.22e-16 ***

Menurut AIC, distribusi Weibull (lebih khusus WEI2, parametriisasi khusus dari itu) paling cocok dengan data. Parameterisasi distribusi yang tepat WEI2ditentukan dalam dokumen ini di halaman 279. Mari kita periksa kecocokan dengan melihat residu dalam plot cacing (pada dasarnya plot QQ yang tidak tren):

WormPlot

Kami perkirakan residunya mendekati garis horizontal tengah dan 95% di antaranya terletak di antara kurva putus-putus atas dan bawah, yang bertindak sebagai interval kepercayaan 95% searah. Dalam hal ini, plot worm terlihat bagus untuk saya yang menunjukkan bahwa distribusi Weibull cukup memadai.

COOLSerdash
sumber
1
+1 Analisis yang bagus. Tapi satu pertanyaan. Apakah kesimpulan positif tentang kompatibilitas dengan distribusi utama tertentu (Weibull, dalam kasus ini) memungkinkan untuk mengesampingkan kemungkinan kehadiran distribusi campuran? Atau kita perlu melakukan analisis campuran yang tepat dan memeriksa GoF untuk mengesampingkan opsi itu?
Aleksandr Blekh
18
@AleksandrBlekh Tidak mungkin untuk memiliki kekuatan yang cukup untuk mengesampingkan campuran: ketika campuran dua distribusi yang hampir identik tidak dapat dideteksi dan ketika semua kecuali satu komponen memiliki proporsi yang sangat kecil itu juga tidak dapat dideteksi. Biasanya (dengan tidak adanya teori yang mungkin menyarankan bentuk distribusi), orang cocok distribusi parametrik untuk mencapai deskripsi perkiraan data pelit . Campuran tidak termasuk di antaranya: mereka memerlukan terlalu banyak parameter dan terlalu fleksibel untuk tujuan tersebut.
whuber
4
@whuber: +1 Hargai penjelasan bagus Anda !
Aleksandr Blekh
1
@Lourenco Saya melihat grafik Cullen dan Fey. Titik biru menunjukkan sampel kami. Anda melihat bahwa intinya dekat dengan garis Weibull, Lognormal dan Gamma (yaitu antara Weibull dan Gamma). Setelah memasang masing-masing distribusi tersebut, saya membandingkan statistik good-of-fit menggunakan fungsi gofstatdan AIC. Tidak ada konsensus tentang apa cara terbaik untuk menentukan distribusi "terbaik". Saya suka metode grafis dan AIC.
COOLSerdash
1
@Lourenco Apakah maksud Anda lognormal? Distribusi logistik (tanda "+") agak jauh dari data yang diamati. Lognormal juga akan menjadi kandidat yang biasanya saya lihat. Untuk tutorial ini, saya memilih untuk tidak menampilkannya agar posnya singkat. Lognormal menunjukkan kecocokan yang lebih buruk dibandingkan dengan distribusi Weibull dan Normal. AIC adalah 537.59 dan grafiknya juga tidak terlalu bagus.
COOLSerdash
15

Plot sebagian besar merupakan cara yang baik untuk mendapatkan gambaran yang lebih baik tentang seperti apa data Anda. Dalam kasus Anda, saya akan merekomendasikan memplot fungsi distribusi kumulatif empiris (ecdf) terhadap cdf teoritis dengan parameter yang Anda dapatkan dari fitdistr ().

Saya melakukan itu sekali untuk data saya dan juga termasuk interval kepercayaan. Ini gambar yang saya dapat menggunakan ggplot2 ().

masukkan deskripsi gambar di sini

Garis hitam adalah fungsi distribusi kumulatif empiris dan garis berwarna adalah cdf dari distribusi yang berbeda menggunakan parameter yang saya dapat menggunakan metode Maximum Likelihood. Orang dapat dengan mudah melihat bahwa distribusi eksponensial dan normal tidak cocok untuk data, karena garis-garis memiliki bentuk yang berbeda dari garis ek dan garis yang cukup jauh dari garis ek. Sayangnya distribusi lainnya cukup dekat. Tapi saya akan mengatakan bahwa garis logNormal adalah yang paling dekat dengan garis hitam. Dengan menggunakan ukuran jarak (misalnya MSE) seseorang dapat memvalidasi asumsi tersebut.

Jika Anda hanya memiliki dua distribusi yang bersaing (misalnya memilih yang tampaknya paling cocok dalam plot), Anda dapat menggunakan Likelihood-Ratio-Test untuk menguji distribusi mana yang lebih cocok.

elevendollar
sumber
20
Selamat datang di CrossValidated! Jawaban Anda mungkin lebih berguna jika Anda dapat mengeditnya untuk memasukkan (a) kode yang Anda gunakan untuk menghasilkan grafik, dan (b) bagaimana seseorang akan membaca grafik.
Stephan Kolassa
2
Apa yang sedang direncanakan di sana? Apakah itu semacam plot eksponensial?
Glen_b
1
Tetapi bagaimana Anda memutuskan distribusi mana yang paling sesuai dengan data Anda? Hanya menurut grafik saya tidak bisa memberi tahu Anda apakah logNormal atau weibull paling cocok dengan data Anda.
tobibo
4
Jika Anda ingin membuat generator angka pseudo-acak, mengapa tidak menggunakan cdf empiris? Apakah Anda ingin menggambar angka yang melampaui distribusi yang Anda amati?
elevendollar
6
Mengambil grafik Anda pada nilai nominal, tampaknya tidak ada distribusi kandidat Anda yang cocok dengan data sama sekali. Selain itu, ecdf Anda tampaknya memiliki asymptote horizontal kurang dari 0,03 yang tidak masuk akal, jadi saya tidak yakin itu sebenarnya adalah ecdf sejak awal.
Hong Ooi