¿Cómo dibujar un gráfico ajustado y un gráfico real de distribución gamma en una parcela?

10

Cargue el paquete necesario.

library(ggplot2)
library(MASS)

Genera 10,000 números ajustados a la distribución gamma.

x <- round(rgamma(100000,shape = 2,rate = 0.2),1)
x <- x[which(x>0)]

Dibuje la función de densidad de probabilidad, se supone que no sabemos a qué distribución se ajusta x.

t1 <- as.data.frame(table(x))
names(t1) <- c("x","y")
t1 <- transform(t1,x=as.numeric(as.character(x)))
t1$y <- t1$y/sum(t1[,2])
ggplot() + 
  geom_point(data = t1,aes(x = x,y = y)) + 
  theme_classic()

pdf

A partir del gráfico, podemos aprender que la distribución de x es muy parecida a la distribución gamma, por lo que la utilizamos fitdistr()en un paquete MASSpara obtener los parámetros de forma y velocidad de distribución gamma.

fitdistr(x,"gamma") 
##       output 
##       shape           rate    
##   2.0108224880   0.2011198260 
##  (0.0083543575) (0.0009483429)

Dibuje el punto real (punto negro) y el gráfico ajustado (línea roja) en el mismo diagrama, y ​​esta es la pregunta, primero mire el diagrama.

ggplot() + 
  geom_point(data = t1,aes(x = x,y = y)) +     
  geom_line(aes(x=t1[,1],y=dgamma(t1[,1],2,0.2)),color="red") + 
  theme_classic()

gráfico ajustado

Tengo dos preguntas:

  1. Los parámetros son reales shape=2, rate=0.2y los parámetros que utilizo la función fitdistr()de conseguir son shape=2.01, rate=0.20. Estos dos son casi iguales, pero por qué el gráfico ajustado no se ajusta bien al punto real, debe haber algo mal en el gráfico ajustado, o la forma en que dibujo el gráfico ajustado y los puntos reales es totalmente incorrecta, ¿qué debo hacer? ?

  2. Después de obtener el parámetro del modelo que establezco, ¿de qué manera evalúo el modelo, algo como RSS (suma cuadrada residual) para el modelo lineal, o el valor p de shapiro.test(), ks.test()y otra prueba?

Soy pobre en conocimiento estadístico, ¿podrían ayudarme amablemente?

PD: Tengo búsquedas en Google, stackoverflow y CV muchas veces, pero no encontré nada relacionado con este problema

Ling Zhang
fuente
1
La primera vez que hice esta pregunta en stackoverflow, pero parecía ser que esta pregunta pertenece a CV, el amigo dijo que entendí mal la función de masa de probabilidad y la función de densidad de probabilidad, no pude comprenderla completamente, así que perdóname por responder esta pregunta nuevamente en CV
Ling Zhang
1
Su cálculo de densidades es incorrecto. Una forma simple de calcular es h <- hist(x, 1000, plot = FALSE); t1 <- data.frame(x = h$mids, y = h$density).
@Pascal tienes razón, he resuelto Q1, ¡gracias!
Ling Zhang el
Vea la respuesta a continuación, la densityfunción es útil.
Lo entiendo, gracias nuevamente por editar y resolver mi pregunta
Ling Zhang

Respuestas:

11

Pregunta 1

La forma de calcular la densidad a mano parece incorrecta. No hay necesidad de redondear los números aleatorios de la distribución gamma. Como señaló @Pascal, puede usar un histograma para trazar la densidad de los puntos. En el siguiente ejemplo, uso la función densitypara estimar la densidad y trazarla como puntos. Presento el ajuste tanto con los puntos como con el histograma:

library(ggplot2)
library(MASS)

# Generate gamma rvs

x <- rgamma(100000, shape = 2, rate = 0.2)

den <- density(x)

dat <- data.frame(x = den$x, y = den$y)

# Plot density as points

ggplot(data = dat, aes(x = x, y = y)) + 
  geom_point(size = 3) +
  theme_classic()

Densidad gamma

# Fit parameters (to avoid errors, set lower bounds to zero)

fit.params <- fitdistr(x, "gamma", lower = c(0, 0))

# Plot using density points

ggplot(data = dat, aes(x = x,y = y)) + 
  geom_point(size = 3) +     
  geom_line(aes(x=dat$x, y=dgamma(dat$x,fit.params$estimate["shape"], fit.params$estimate["rate"])), color="red", size = 1) + 
  theme_classic()

Ajuste de densidad gamma

# Plot using histograms

ggplot(data = dat) +
  geom_histogram(data = as.data.frame(x), aes(x=x, y=..density..)) +
  geom_line(aes(x=dat$x, y=dgamma(dat$x,fit.params$estimate["shape"], fit.params$estimate["rate"])), color="red", size = 1) + 
  theme_classic()

Histograma con ajuste

Aquí está la solución que proporcionó @Pascal:

h <- hist(x, 1000, plot = FALSE)
t1 <- data.frame(x = h$mids, y = h$density)

ggplot(data = t1, aes(x = x, y = y)) + 
  geom_point(size = 3) +     
  geom_line(aes(x=t1$x, y=dgamma(t1$x,fit.params$estimate["shape"], fit.params$estimate["rate"])), color="red", size = 1) + 
  theme_classic()

Puntos de densidad de histograma

Pregunta 2

Para evaluar la bondad del ajuste, recomiendo el paquete fitdistrplus. Así es como se puede usar para ajustar dos distribuciones y comparar sus ajustes de forma gráfica y numérica. El comando gofstatimprime varias medidas, como AIC, BIC y algunas estadísticas de gof como la prueba KS, etc. Estas se utilizan principalmente para comparar ajustes de diferentes distribuciones (en este caso, gamma versus Weibull). Puede encontrar más información en mi respuesta aquí :

library(fitdistrplus)

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.weibull <- fitdist(x, "weibull")
fit.gamma <- fitdist(x, "gamma", lower = c(0, 0))

# Compare fits 

graphically

par(mfrow = c(2, 2))
plot.legend <- c("Weibull", "Gamma")
denscomp(list(fit.weibull, fit.gamma), fitcol = c("red", "blue"), legendtext = plot.legend)
qqcomp(list(fit.weibull, fit.gamma), fitcol = c("red", "blue"), legendtext = plot.legend)
cdfcomp(list(fit.weibull, fit.gamma), fitcol = c("red", "blue"), legendtext = plot.legend)
ppcomp(list(fit.weibull, fit.gamma), fitcol = c("red", "blue"), legendtext = plot.legend)

@NickCox informa con razón que QQ-Plot (panel superior derecho) es el mejor gráfico individual para juzgar y comparar ajustes. Las densidades ajustadas son difíciles de comparar. Incluyo los otros gráficos también en aras de la integridad.

Comparar ajustes

# Compare goodness of fit

gofstat(list(fit.weibull, fit.gamma))

Goodness-of-fit statistics
                             1-mle-weibull 2-mle-gamma
Kolmogorov-Smirnov statistic    0.06863193   0.1204876
Cramer-von Mises statistic      0.05673634   0.2060789
Anderson-Darling statistic      0.38619340   1.2031051

Goodness-of-fit criteria
                               1-mle-weibull 2-mle-gamma
Aikake's Information Criterion      519.8537    531.5180
Bayesian Information Criterion      524.5151    536.1795
COOLSerdash
fuente
1
No puedo revisar, pero tiene un problema con el backtick para fitdistrplusy gofstaten su respuesta
2
Recomendación de una línea: el gráfico cuantil-cuantil es el mejor gráfico individual para este propósito. Comparar densidades observadas y ajustadas es difícil de hacer bien. Por ejemplo, es difícil detectar desviaciones sistemáticas en valores altos que científica y prácticamente a menudo son muy importantes.
Nick Cox
1
Me alegra que estemos de acuerdo. El OP comienza con 10,000 puntos. Muchos problemas comienzan con muchos menos y luego tener una buena idea de la densidad puede ser problemático.
Nick Cox
1
@LingZhang Para comparar ajustes, puede observar el valor de la AIC. Se prefiere el ajuste con el AIC más bajo. Además, no estoy de acuerdo con que la distribución de Weibull y Gamma sea bastante similar en el gráfico QQ. Los puntos del ajuste Weibull están más cerca de la línea en comparación con el ajuste Gamma, especialmente en las colas. En consecuencia, el AIC para el ajuste Weibull es más pequeño en comparación con el ajuste Gamma.
COOLSerdash
1
Más recto es mejor. Además, consulte stats.stackexchange.com/questions/111010/… Los principios son los mismos. La desviación sistemática de la linealidad es un problema.
Nick Cox