내 데이터에 가장 적합한 분포를 결정하는 방법은 무엇입니까?


133

데이터 세트가 있으며 데이터에 가장 적합한 분포를 파악하고 싶습니다.

fitdistr()함수를 사용하여 추정 분포 (예 : Weibull, Cauchy, Normal)를 설명하는 데 필요한 매개 변수를 추정했습니다. 이러한 모수를 사용하여 Kolmogorov-Smirnov Test를 수행하여 표본 데이터가 가정 된 분포와 동일한 분포에서 나온 것인지 추정 할 수 있습니다.

p- 값이 0.05보다 크면 표본 데이터가 동일한 분포에서 추출되었다고 가정 할 수 있습니다. 그러나 p- 값은 적합의 신성에 대한 정보를 제공하지 않습니다.

따라서 표본 데이터의 p- 값이 정규 분포와와 이블 분포에 대해 0.05보다 큰 경우 데이터에 더 적합한 분포를 어떻게 알 수 있습니까?

이것은 기본적으로 내가 한 일입니다.

> 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

p- 값은 Weibull 분포의 경우 0.8669이고 정규 분포의 경우 0.5522입니다. 따라서 데이터가 Weibull 및 정규 분포를 따른다고 가정 할 수 있습니다. 그러나 어떤 분포 함수가 내 데이터를 더 잘 설명합니까?


11 달러언급 하면서 다음 코드를 찾았지만 결과를 해석하는 방법을 모른다.

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

5
왜 데이터에 가장 적합한 분포를 알아 내고 싶습니까?
Roland

6
주어진 분포에 따라 의사 난수를 생성하고 싶습니다.
tobibo

6
KS를 사용하여 데이터 세트에서 찾은 모수가있는 분포가 데이터 세트와 일치하는지 확인할 수 없습니다. 예를 들어이 페이지의 # 2 와 대안 (및 KS 테스트가 오도 할 수있는 다른 방법)을 참조하십시오.
tpg2114

또 다른 토론 여기 매개 변수가 샘플로부터 추정 할 때 KS 시험을 적용하는 방법에 대한 코드 샘플.
Aksakal

1
I used the fitdistr() function ..... fitdistr기능은 무엇입니까 ? Excel에서 뭔가요? 아니면 당신이 C로 쓴 것이 있습니까?
wolfies

답변:


162

먼저 몇 가지 간단한 의견이 있습니다.

  • 추정 된 매개 변수 를 사용한 Kolmovorov-Smirnov-Test (KS-Test) 의 값은 매우 잘못됩니다. 불행히도 분포를 맞추고 Kolmogorov-Smirnov-Test의 추정 된 모수를 사용하여 샘플을 테스트 할 수는 없습니다.p
  • 표본은 특정 분포를 정확하게 따르지 않습니다 . 따라서 KS-Test 의 이 유효하고 보다 크더라도 데이터가이 특정 분포를 따른다 는 것을 배제수는 없습니다 . 다른 공식은 표본이 특정 분포와 호환된다는 것입니다. 그러나 "내 데이터가 분포 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은 특히 꼬리에서 조금 더 나아 보일 수 있습니다. 이에 따라 Weibull 피팅의 AIC는 일반 피팅에 비해 낮습니다.

fit.weibull$aic
[1] 519.8537

fit.norm$aic
[1] 523.3079

Kolmogorov-Smirnov 테스트 시뮬레이션

여기 에 설명 된 @Aksakal의 절차 를 사용하여 null에서 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
  )      
})

시뮬레이션 된 KS 통계량의 ECDF는 다음과 같습니다.

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 분포와 호환 가능하다는 그래픽 결론을 확인합니다.

여기 에 설명 된대로 부트 스트랩을 사용하여 예상 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_ 밀도

#-----------------------------------------------------------------------------
# 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 (일반화 된 아카 이케 정보 기준)에 따라 "최고"를 선택 할 수있는 능력. 주요 기능은 fitDist입니다. 이 함수에서 중요한 옵션은 시도한 배포 유형입니다. 예를 들어, 설정 type = "realline"은 전체 실선에 정의 된 모든 구현 분포를 시도하는 반면 type = "realsplus"실제 양수 선에 정의 된 분포 만 시도합니다. 또 다른 중요한 옵션은 매개 변수 . 이는 GAIC에 대한 페널티입니다. 아래 예에서 매개 변수 를 설정했습니다 . 이는 고전적인 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에 따르면,와 이블 분포 (Waibull distribution) (보다 구체적으로 WEI2, 그것의 특별한 매개 변수화)는 데이터에 가장 적합합니다. 분포의 정확한 매개 변수화가 WEI2에서 자세한 조되는 이 문서 의가에 잔류보고 적합성을 검사하자 251 페이지 웜 플롯 (기본적으로 해제 추세 QQ 플롯) :

웜 플롯

잔차는 중간 수평선에 가깝고 95 %는 위쪽 및 아래쪽 점선 곡선 사이에 있으며, 이는 점별 신뢰 구간 95 %로 작동합니다. 이 경우, 웜 플롯은 Weibull 분포가 적절하게 적합하다는 것을 보여줍니다.


1
+1 멋진 분석. 하나의 질문입니다. 특정 주요 분포 (이 경우 Weibull)와의 호환성에 대한 긍정적 결론은 혼합물 분포의 존재 가능성을 배제 할 수 있습니까? 또는 적절한 혼합물 분석을 수행하고 해당 옵션을 배제하기 위해 GoF를 확인해야합니까?
Aleksandr Blekh

18
@AleksandrBlekh 혼합물을 배제하기에 충분한 힘을 갖는 것은 불가능합니다. 혼합물이 거의 동일한 분포의 두 개일 때는이를 감지 할 수 없으며 한 성분을 제외한 모든 성분이 매우 작은 비율을 가질 때도 감지 할 수 없습니다. 일반적으로 (배포 형식을 제안 할 수있는 이론이없는 경우), 대략적인 데이터에 대한 대략적인 설명 을 달성하기 위해 모수 분포에 적합 합니다. 혼합물은 그중 하나가 아닙니다. 너무 많은 매개 변수가 필요 하고 목적에 비해 너무 유연합니다.
whuber

4
@ whuber : +1 훌륭한 설명을 부탁드립니다 !
Aleksandr Blekh

1
@Lourenco 저는 Cullen and Fey 그래프를 보았습니다. 파란색 점은 샘플을 나타냅니다. 점은 Weibull, Lognormal 및 Gamma (Weibull과 Gamma 사이에 있음)의 선에 가깝습니다. 각 분포를 피팅 한 후 함수 gofstat와 AIC를 사용하여 적합도 통계를 비교했습니다 . "최고의"분포를 결정하는 가장 좋은 방법이 무엇인지에 대한 합의가 없습니다. 나는 그래픽 방식과 AIC를 좋아한다.
COOLSerdash

1
@Lourenco 대수를 의미합니까? 로지스틱 분포 ( "+"부호)는 관측 된 데이터와 약간 떨어져 있습니다. 대수 정규식은 내가 일반적으로 볼 후보입니다. 이 자습서에서는 게시물을 짧게 유지하기 위해 표시하지 않도록 선택했습니다. 로그 정규는와 이블 분포와 정규 분포에 비해 적합하지 않습니다. AIC는 537.59이며 그래프도 좋지 않습니다.
COOLSerdash

15

플롯은 데이터가 어떻게 보이는지 더 잘 알 수있는 좋은 방법입니다. 귀하의 경우 fitdistr ()에서 얻은 매개 변수를 사용하여 이론적 인 cdfs에 대해 경험적 누적 분포 함수 (ecdf)를 플로팅하는 것이 좋습니다 .

내 데이터에 대해 한 번 수행했으며 신뢰 구간도 포함했습니다. 다음은 ggplot2 ()를 사용하여 얻은 그림입니다.

여기에 이미지 설명을 입력하십시오

검은 선은 경험적 누적 분포 함수이고 컬러 선은 Maximum Likelihood 방법을 사용하여 얻은 매개 변수를 사용하여 다른 분포의 cdfs입니다. 행이 ecdf와 다른 형식을 가지고 있고 ecdf와는 아주 멀리 있기 때문에 지수 분포와 정규 분포가 데이터에 적합하지 않음을 쉽게 알 수 있습니다. 불행히도 다른 분포는 매우 가깝습니다. 그러나 logNormal 줄이 검은 줄에 가장 가깝습니다. 거리 측정 (예 : MSE)을 사용하면 가정을 검증 할 수 있습니다.

두 개의 경쟁 분포 만있는 경우 (예 : 플롯에 가장 적합한 분포를 선택하는 경우) 우도 비율 검정 을 사용하여 어느 분포가 더 적합한지를 테스트 할 수 있습니다 .


20
CrossValidated에 오신 것을 환영합니다! (a) 그래픽을 생성하는 데 사용한 코드 및 (b) 그래픽을 읽는 방법을 포함하도록 편집 할 수 있으면 답이 더 유용 할 수 있습니다.
Stephan Kolassa

2
거기에 무엇이 그려져 있습니까? 그것은 일종의 지수 플롯입니까?
Glen_b

1
그러나 데이터에 가장 적합한 분포를 어떻게 결정합니까? 그래픽에 따르면 logNormal 또는 weibull이 데이터에 가장 적합한 지 여부를 알 수 없었습니다.
tobibo

4
의사 난수 생성기를 생성하려면 경험적 CDF를 사용하지 않는 이유는 무엇입니까? 관측 된 분포를 넘어서는 숫자를 그리시겠습니까?
11시

6
액면가에서 그래프를 취하면 후보 분포 중 어느 것도 데이터에 잘 맞는 것으로 보이지 않습니다 . 또한 귀하의 ecdf는 0.03 미만의 수평 점근선을 가지고있는 것으로 보이므로 의미가 없습니다.
Hong Ooi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.