Як визначити, який розподіл найкраще відповідає моїм даним?


133

У мене є набір даних і я хотів би визначити, який розподіл найкраще відповідає моїм даним.

Я використовував fitdistr()функцію для оцінки необхідних параметрів для опису передбачуваного розподілу (тобто Weibull, Cauchy, Normal). Використовуючи ці параметри, я можу провести тест Колмогорова-Смірнова, щоб оцінити, чи є мої вибіркові дані з того ж розподілу, що і мій припущений розподіл.

Якщо р-значення> 0,05, я можу припустити, що вибіркові дані беруться з одного розподілу. Але p-значення не дає ніякої інформації про божество придатності, чи не так?

Отже, якщо p-значення моїх вибіркових даних становить> 0,05 для нормального розподілу, а також розподілу weibull, як я можу знати, який розподіл краще відповідає моїм даним?

Це в основному те, що я зробив:

> 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

Значення р дорівнюють 0,8669 для розподілу Вейбулла і 0,5522 для нормального розподілу. Таким чином, я можу припустити, що мої дані відповідають Weibull, а також нормальному розподілу. Але яка функція розподілу краще описує мої дані?


Посилаючись на elevendollar, я знайшов наступний код, але не знаю, як інтерпретувати результати:

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

5
Чому ви хочете з’ясувати, який розподіл найбільше відповідає вашим даним?
Роланд

6
Тому що я хочу генерувати псевдовипадкові числа після даного розподілу.
tobibo

6
Ви не можете використовувати KS, щоб перевірити, чи відповідає розподіл з параметрами, знайденими з набору даних, набору даних. Дивіться, наприклад, №2 на цій сторінці , плюс альтернативи (та інші способи тесту KS можуть бути оманливими).
tpg2114

Ще одне обговорення тут із зразками коду про те, як застосувати тест KS, коли параметри оцінюються з вибірки.
Аксакал

1
I used the fitdistr() function ..... Яка fitdistrфункція? Щось із Excel? Або щось ти написав сам на С?
вовчить

Відповіді:


162

По-перше, ось кілька швидких коментарів:

  • В -значення з в Kolmovorov-Смирнов-Test (KS-Test) з розрахунковими параметрами буде абсолютно неправильно. Тож, на жаль, ви не можете просто встановити розподіл, а потім використати оцінені параметри в тесті Колмогорова-Смірнова для тестування вашої вибірки.p
  • Ваш зразок ніколи точно не буде слідувати конкретному розподілу. Тож навіть якщо ваші значення KS-тесту будуть дійсними і , це просто означає, що ви не можете виключити, що ваші дані слідують цьому конкретному розподілу. Іншим формулюванням буде те, що ваш зразок сумісний з певним розподілом. Але відповідь на запитання "Чи мої дані точно відповідають розподілу xy?" завжди немає.p>0.05
  • Ціль тут не може бути з впевненістю визначити, якому розподілу слід ваш зразок. Мета полягає в тому, що @whuber (в коментарях) називає парсимонічні приблизні описи даних. Маючи певний параметричний розподіл може бути корисним як модель даних.

Але давайте трохи проаналізуємо. Я буду використовувати чудовий fitdistrplusпакет, який пропонує кілька приємних функцій для встановлення розподілу. Ми будемо використовувати цю функцію, descdistщоб отримати деякі уявлення про можливі розподіли кандидатів.

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)

Тепер давайте використовувати descdist:

descdist(x, discrete = FALSE)

Дескдист

Куртоз та нахил у квадраті вашого зразка є графіком у вигляді синьої точки під назвою "Спостереження". Здається, що можливі дистрибуції включають Weibull, Lognormal і, можливо, дистрибутив Gamma.

Приміримо розподіл Weibull і звичайний розподіл:

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

Тепер перевірте придатність на нормальне:

plot(fit.norm)

Нормальне прилягання

А для Weibull підходять:

plot(fit.weibull)

Вейбул підходить

Обидва виглядають добре, але судячи з QQ-Plot, Weibull, можливо, виглядає трохи краще, особливо на хвостах. Відповідно, AIC придатності Weibull нижчий порівняно зі звичайним пристосуванням:

fit.weibull$aic
[1] 519.8537

fit.norm$aic
[1] 523.3079

Моделювання тесту Колмогорова-Смірнова

Я буду використовувати описану тут процедуру @ Aksakal для моделювання статистики KS під нулем.

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 модельованої статистики KS виглядає наступним чином:

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

Модельована KS-статистика

Нарешті, наше -значення, що використовує модельований нульовий розподіл KS-статистики: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

Це підтверджує наш графічний висновок про те, що зразок сумісний з розподілом Вейбулла.

Як пояснено тут , ми можемо використовувати завантажувальний додаток, щоб додати точкові інтервали довіри до передбачуваного Weibull PDF або 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


Автоматична розподільна установка з GAMLSS

У gamlssпакеті Rпропонується можливість спробувати багато різних дистрибутивів і вибрати "найкраще" відповідно до GAIC (узагальнений критерій інформації Akaike). Основна функція - fitDist. Важливим варіантом цієї функції є тип перевірених розподілів. Наприклад, налаштування type = "realline"спробує всі реалізовані дистрибутиви, визначені на всій реальній лінії, тоді як type = "realsplus"буде лише спробувати розподіли, визначені на реальній позитивній лінії. Ще одним важливим варіантом є параметр , який є покаранням для ГАІК. У наведеному нижче прикладі я встановлюю параметр що означає, що "найкращий" розподіл вибирається відповідно до класичного AIC. Ви можете встановити на все, що завгодно, наприкладkk=2klog(n) для 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 ***

Згідно з AIC, розподіл Weibull (точніше WEI2, спеціальна його параметризація) найкраще підходить для даних. Точна параметризація розподілу WEI2детально описана в цьому документі на сторінці 279. Давайте перевіримо придатність, подивившись на залишки в черв'ячній графіці (в основному, тренд-QQ-графік):

WormPlot

Ми очікуємо, що залишки будуть близькими до середньої горизонтальної лінії, і 95% з них лежатимуть між верхньою та нижньою пунктирними кривими, які виконують роль 95% довірчих інтервалів. У цьому випадку для мене виглядає чудовий графік, що вказує на те, що розподіл Weibull є адекватним.


1
+1 Хороший аналіз. Хоча одне питання. Чи дозволяє позитивний висновок щодо сумісності з певним великим розподілом (у цьому випадку Weibull) виключає можливість наявності сумісного розподілу? Або нам потрібно зробити належний аналіз суміші та перевірити GoF, щоб виключити цей варіант?
Олександр Блех

18
@AleksandrBlekh Неможливо мати достатню потужність, щоб виключити суміш: коли суміш має два майже однакових розподілу, її неможливо виявити, і коли всі, крім одного компонента, мають дуже малі пропорції, його також неможливо виявити. Зазвичай (за відсутності теорії, яка могла б запропонувати форму розподілу), підходить параметричні розподіли для досягнення парсимонізованих приблизних описів даних. Суміші - це не одна: вони вимагають занадто багато параметрів і занадто гнучкі для цієї мети.
whuber

4
@whuber: +1 Цінуй ваше чудове пояснення!
Олександр Блех

1
@Lourenco Я переглянув графік Каллена та Фей. Синя точка позначає наш зразок. Ви бачите, що точка близька до ліній Weibull, Lognormal і Gamma (що знаходиться між Weibull та Gamma). Після підгонки кожного з цих розподілів я порівняв статистику корисності придатності за допомогою функції gofstatта AIC. Не існує єдиної думки щодо того, який найкращий спосіб визначити "найкращий" розподіл. Мені подобаються графічні методи та АПК.
COOLSerdash

1
@Lourenco Ви маєте на увазі лонормальне? Логістичний розподіл (знак "+") знаходиться досить далеко від спостережуваних даних. Лонормальний також був би кандидатом, якого я зазвичай дивлюся. У цьому підручнику я вирішив не показувати його, щоб повідомлення не було коротким. Лонормальне виявляє гірше відповідність порівняно з розподілом Weibull і Normal. AIC становить 537,59, а графіки також виглядають не надто добре.
COOLSerdash

15

Сюжети - це переважно хороший спосіб отримати краще уявлення про те, як виглядають ваші дані. У вашому випадку я рекомендую побудувати емпіричну функцію кумулятивного розподілу (ecdf) проти теоретичних cdfs з параметрами, отриманими від fitdistr ().

Я робив це один раз для своїх даних, а також включав довірчі інтервали. Ось малюнок, який я отримав за допомогою ggplot2 ().

введіть тут опис зображення

Чорна лінія є емпіричною кумулятивною функцією розподілу, а кольорові лінії - це cdfs з різних розподілів за допомогою параметрів, отриманих методом Максимальна ймовірність. Можна легко побачити, що експоненціальний і нормальний розподіл не дуже підходить до даних, оскільки рядки мають іншу форму, ніж ecdf, а рядки досить далекі від ecdf. На жаль, інші дистрибуції досить близькі. Але я б сказав, що logNormal лінія є найближчою до чорної лінії. Використовуючи міру відстані (наприклад, MSE), можна підтвердити припущення.

Якщо у вас є лише два конкуруючих розподілу (наприклад, вибір тих, які, здається, найкраще входять у сюжет), ви можете скористатися Тестом ймовірності співвідношення, щоб перевірити, які розподіли підходять краще.


20
Ласкаво просимо до CrossValidated! Ваша відповідь може бути кориснішою, якщо ви зможете її відредагувати, щоб вона включала: (а) код, який ви використовували для створення графіки, та (б) як читати графіку.
Стефан Коласа

2
Що там планується? Це якась експоненціальність-сюжет?
Glen_b

1
Але як ви вирішите, який розподіл найбільше відповідає вашим даним? Лише за графікою я не можу сказати, чи найкраще відповідає logNormal чи weibull вашим даним.
tobibo

4
Якщо ви хочете створити генератор псевдовипадкових чисел, чому б не використовувати емпіричний cdf? Ви хочете намалювати числа, що виходять за рамки спостережуваного розповсюдження?
одинадцять

6
Якщо взяти ваш графік за номіналом, виявиться, що жоден із ваших кандидатських дистрибутивів не відповідає нормам даних. Крім того, здається, що у вашому ecdf є горизонтальна асимптота менше 0,03, що не має сенсу, тому я не впевнений, що це справді ecdf.
Hong Ooi
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.