Làm thế nào để xác định phân phối nào phù hợp với dữ liệu của tôi nhất?


133

Tôi có một bộ dữ liệu và muốn tìm ra phân phối nào phù hợp nhất với dữ liệu của tôi.

Tôi đã sử dụng fitdistr()hàm để ước tính các tham số cần thiết để mô tả phân phối giả định (ví dụ Weibull, Cauchy, Bình thường). Sử dụng các tham số đó, tôi có thể tiến hành Thử nghiệm Kolmogorov-Smirnov để ước tính liệu dữ liệu mẫu của tôi có cùng phân phối với phân phối giả định của tôi không.

Nếu giá trị p> 0,05 tôi có thể giả sử rằng dữ liệu mẫu được rút ra từ cùng một phân phối. Nhưng giá trị p không cung cấp bất kỳ thông tin nào về sự phù hợp, phải không?

Vì vậy, trong trường hợp giá trị p của dữ liệu mẫu của tôi> 0,05 cho phân phối bình thường cũng như phân phối rộng rãi, làm thế nào tôi có thể biết phân phối nào phù hợp với dữ liệu của mình hơn?

Về cơ bản, đây là những gì tôi đã làm:

> 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

Giá trị p là 0,8669 cho phân phối Weibull và 0,5522 cho phân phối bình thường. Do đó tôi có thể giả định rằng dữ liệu của mình tuân theo Weibull cũng như phân phối bình thường. Nhưng chức năng phân phối nào mô tả dữ liệu của tôi tốt hơn?


Nhắc đến elevendollar tôi đã tìm thấy đoạn mã sau, nhưng không biết cách diễn giải kết quả:

fits <- list(no = fitdistr(mydata, "normal"),
             we = fitdistr(mydata, "weibull"))
sapply(fits, function(i) i$loglik)
       no        we 
-259.6540 -257.9268 

5
Tại sao bạn muốn tìm ra phân phối nào phù hợp nhất với dữ liệu của bạn?
Roland

6
Bởi vì tôi muốn tạo các số giả ngẫu nhiên theo phân phối đã cho.
tobibo

6
Bạn không thể sử dụng KS để kiểm tra xem phân phối có tham số được tìm thấy từ tập dữ liệu có khớp với tập dữ liệu không. Xem số 2 trên trang này chẳng hạn, cộng với các lựa chọn thay thế (và các cách khác mà bài kiểm tra KS có thể gây hiểu nhầm).
tpg2114

Một cuộc thảo luận khác ở đây với các mẫu mã về cách áp dụng thử nghiệm KS khi các tham số được ước tính từ mẫu.
Aksakal

1
I used the fitdistr() function ..... fitdistrChức năng gì? Một cái gì đó từ Excel? Hoặc một cái gì đó bạn đã tự viết trong C?
sói

Câu trả lời:


162

Đầu tiên, đây là một số nhận xét nhanh:

  • Giá trị của Kolmovorov-Smirnov-Test (KS-Test) với các tham số ước tính sẽ khá sai. Thật không may, bạn không thể vừa một bản phân phối và sau đó sử dụng các tham số ước tính trong Kolmogorov-Smirnov-Test để kiểm tra mẫu của bạn.p
  • Mẫu của bạn sẽ không bao giờ theo một phân phối cụ thể chính xác. Vì vậy, ngay cả khi giá trị của bạn từ Kiểm tra KS sẽ hợp lệ và , điều đó chỉ có nghĩa là bạn không thể loại trừ rằng dữ liệu của bạn tuân theo phân phối cụ thể này. Một công thức khác là mẫu của bạn tương thích với một phân phối nhất định. Nhưng câu trả lời cho câu hỏi "Dữ liệu của tôi có tuân theo phân phối xy chính xác không?" luôn luôn là khôngp>0.05
  • Mục tiêu ở đây không thể là xác định chắc chắn phân phối mẫu của bạn theo sau. Mục tiêu là cái mà @whuber (trong các bình luận) gọi là mô tả gần đúng về dữ liệu. Có một phân phối tham số cụ thể có thể hữu ích như một mô hình của dữ liệu.

Nhưng hãy làm một số khám phá. Tôi sẽ sử dụng fitdistrplusgói tuyệt vời cung cấp một số chức năng tốt để phù hợp với phân phối. Chúng tôi sẽ sử dụng chức năng descdistđể đạt được một số ý tưởng về phân phối ứng viên có thể.

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)

Bây giờ cho phép sử dụng descdist:

descdist(x, discrete = FALSE)

Descdist

Độ lệch và độ lệch bình phương của mẫu của bạn là plottet như một điểm màu xanh có tên là "Quan sát". Có vẻ như các bản phân phối có thể bao gồm phân phối Weibull, Logn normal và có thể là phân phối Gamma.

Hãy phù hợp với phân phối Weibull và phân phối bình thường:

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

Bây giờ kiểm tra sự phù hợp cho bình thường:

plot(fit.norm)

Phù hợp bình thường

Và cho phù hợp với Weibull:

plot(fit.weibull)

Phù hợp Weibull

Cả hai đều có vẻ tốt nhưng được đánh giá bởi QQ-Plot, Weibull có thể trông tốt hơn một chút, đặc biệt là ở phần đuôi. Tương ứng, AIC của phù hợp Weibull thấp hơn so với phù hợp thông thường:

fit.weibull$aic
[1] 519.8537

fit.norm$aic
[1] 523.3079

Mô phỏng thử nghiệm Kolmogorov-Smirnov

Tôi sẽ sử dụng quy trình của @ Aksakal được giải thích ở đây để mô phỏng thống kê của KS theo null.

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 của thống kê KS mô phỏng trông như sau:

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

Thống kê mô phỏng KS

Cuối cùng, giá trị của chúng tôi bằng cách sử dụng phân phối null mô phỏng của thống kê KS là:p

fit <- logspline(stats)

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

[1] 0.4889511

Điều này xác nhận kết luận đồ họa của chúng tôi rằng mẫu tương thích với phân phối Weibull.

Như đã giải thích ở đây , chúng ta có thể sử dụng bootstrapping để thêm các khoảng tin cậy theo chiều cho vào Weibull PDF hoặc CDF ước tính:

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_D mật độ

#-----------------------------------------------------------------------------
# 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


Phân phối tự động phù hợp với GAMLSS

Các gamlssgói cho RMời khả năng thử nhiều bản phân phối khác nhau và chọn "tốt nhất" theo GAIC (tiêu chuẩn thông tin Akaike tổng quát). Chức năng chính là fitDist. Một tùy chọn quan trọng trong chức năng này là loại phân phối được thử. Ví dụ: cài đặt type = "realline"sẽ thử tất cả các phân phối đã triển khai được xác định trên toàn bộ dòng thực trong khi type = "realsplus"sẽ chỉ thử các phân phối được xác định trên dòng thực dương. Một tùy chọn quan trọng khác là tham số , đó là hình phạt cho GAIC. Trong ví dụ dưới đây, tôi đặt tham số có nghĩa là phân phối "tốt nhất" được chọn theo AIC cổ điển. Bạn có thể đặt thành bất cứ thứ gì bạn thích, chẳng hạn nhưkk=2klog(n) cho BIC.

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 ***

Theo AIC, phân phối Weibull (cụ thể hơn WEI2là một tham số đặc biệt của nó) phù hợp nhất với dữ liệu. Thông số chính xác của phân phối WEI2được ghi lại trong tài liệu này ở trang 279. Chúng ta hãy kiểm tra sự phù hợp bằng cách xem xét các phần dư trong một lô giun (về cơ bản là một âm mưu QQ bị loại bỏ):

WormPlot

Chúng tôi hy vọng phần dư sẽ nằm gần đường ngang giữa và 95% trong số chúng nằm giữa các đường cong chấm trên và dưới, đóng vai trò là khoảng tin cậy theo chiều ngang 95%. Trong trường hợp này, âm mưu sâu có vẻ tốt đối với tôi chỉ ra rằng phân phối Weibull là phù hợp.


1
+1 Phân tích đẹp. Một câu hỏi, mặc dù. Liệu kết luận tích cực về khả năng tương thích với một phân phối chính cụ thể (Weibull, trong trường hợp này) có cho phép loại trừ khả năng có sự hiện diện của phân phối hỗn hợp không? Hoặc chúng ta cần thực hiện phân tích hỗn hợp thích hợp và kiểm tra GoF để loại trừ tùy chọn đó?
Alexanderr Blekh

18
@AleksandrBlekh Không thể có đủ sức mạnh để loại trừ hỗn hợp: khi hỗn hợp có hai phân phối gần như giống hệt nhau, nó cũng không thể được phát hiện và khi một thành phần có tỷ lệ rất nhỏ thì cũng không thể phát hiện được. Thông thường (trong trường hợp không có lý thuyết có thể đề xuất một hình thức phân phối), người ta phù hợp với các phân phối tham số để đạt được các mô tả gần đúng về dữ liệu. Hỗn hợp không phải là một trong số đó: chúng yêu cầu quá nhiều tham số và quá linh hoạt cho mục đích.
whuber

4
@whuber: +1 Đánh giá cao lời giải thích tuyệt vời của bạn !
Alexanderr Blekh

1
@Lourenco Tôi nhìn vào biểu đồ Cullen và Fey. Điểm màu xanh biểu thị mẫu của chúng tôi. Bạn thấy rằng điểm này gần với các dòng của Weibull, Logn normal và Gamma (nằm giữa Weibull và Gamma). Sau khi phù hợp với từng phân phối đó, tôi đã so sánh số liệu thống kê mức độ phù hợp bằng cách sử dụng chức năng gofstatvà AIC. Không có sự đồng thuận về cách tốt nhất để xác định phân phối "tốt nhất" là gì. Tôi thích phương pháp đồ họa và AIC.
COOLSerdash

1
@Lourenco Ý bạn là sự bất thường? Phân phối logistic (dấu "+") cách dữ liệu quan sát được một chút. Lognatural cũng sẽ là một ứng cử viên tôi thường nhìn vào. Đối với hướng dẫn này, tôi đã chọn không hiển thị nó để giữ cho bài viết ngắn. Sự bất thường cho thấy sự phù hợp tồi tệ hơn so với cả phân phối Weibull và Bình thường. AIC là 537,59 và các biểu đồ cũng không quá tốt.
COOLSerdash

15

Cốt truyện chủ yếu là một cách tốt để có được ý tưởng tốt hơn về dữ liệu của bạn trông như thế nào. Trong trường hợp của bạn, tôi khuyên bạn nên vẽ đồ thị hàm phân phối tích lũy theo kinh nghiệm (ecdf) dựa trên các cdfs lý thuyết với các tham số bạn nhận được từ fitdistr ().

Tôi đã làm điều đó một lần cho dữ liệu của mình và cũng bao gồm các khoảng tin cậy. Đây là hình ảnh tôi đã sử dụng ggplot2 ().

nhập mô tả hình ảnh ở đây

Đường màu đen là hàm phân phối tích lũy theo kinh nghiệm và các đường màu là các cdf từ các phân phối khác nhau bằng các tham số tôi nhận được bằng phương pháp Tối đa khả năng. Người ta có thể dễ dàng thấy rằng phân phối theo cấp số nhân và bình thường không phù hợp với dữ liệu, bởi vì các dòng có dạng khác với ecdf và các dòng khá xa so với ecdf. Thật không may, các phân phối khác là khá gần. Nhưng tôi sẽ nói rằng dòng logN normal là gần nhất với dòng màu đen. Sử dụng thước đo khoảng cách (ví dụ MSE) người ta có thể xác nhận giả định.

Nếu bạn chỉ có hai bản phân phối cạnh tranh (ví dụ: chọn những bản phân phối có vẻ phù hợp nhất trong cốt truyện), bạn có thể sử dụng Kiểm tra tỷ lệ khả năng để kiểm tra phân phối nào phù hợp hơn.


20
Chào mừng đến với CrossValidated! Câu trả lời của bạn có thể hữu ích hơn nếu bạn có thể chỉnh sửa nó để bao gồm (a) mã bạn đã sử dụng để tạo đồ họa và (b) cách người ta đọc đồ họa.
Stephan Kolassa

2
Điều gì đang được vẽ ở đó? Đó có phải là một số loại cốt truyện?
Glen_b

1
Nhưng làm thế nào để bạn quyết định phân phối nào phù hợp với dữ liệu của bạn nhất? Chỉ theo đồ họa tôi không thể cho bạn biết liệu logN normal hay weibull phù hợp nhất với dữ liệu của bạn.
tobibo

4
Nếu bạn muốn tạo một bộ tạo số giả ngẫu nhiên tại sao không sử dụng cdf theo kinh nghiệm? Bạn có muốn vẽ những con số vượt ra ngoài phân phối quan sát của bạn?
elevendollar

6
Lấy biểu đồ của bạn theo mệnh giá, có vẻ như không có bản phân phối ứng cử viên nào của bạn phù hợp với dữ liệu cả. Ngoài ra, ecdf của bạn dường như có một tiệm cận ngang ở mức dưới 0,03 không có ý nghĩa gì, vì vậy tôi không chắc chắn rằng nó thực sự là một ecdf ở nơi đầu tiên.
Hồng Ooi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.