Como desenhar um gráfico ajustado e um gráfico real da distribuição gama em um gráfico?

10

Carregue o pacote necessário.

library(ggplot2)
library(MASS)

Gere 10.000 números ajustados à distribuição gama.

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

Desenhe a função densidade de probabilidade, supondo que não sabemos em qual distribuição x se encaixa.

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 do gráfico, podemos aprender que a distribuição de x é semelhante à distribuição gama, então usamos fitdistr()no pacote MASSpara obter os parâmetros de forma e taxa de distribuição gama.

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

Desenhe o ponto real (ponto preto) e o gráfico ajustado (linha vermelha) no mesmo gráfico, e aqui está a pergunta, verifique primeiro o gráfico.

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

Eu tenho duas perguntas:

  1. Os parâmetros reais são shape=2, rate=0.2e os parâmetros que usam a função fitdistr()para obter são shape=2.01, rate=0.20. Esses dois são praticamente os mesmos, mas por que o gráfico ajustado não se encaixa bem no ponto real, deve haver algo errado no gráfico ajustado, ou a maneira como eu desenho o gráfico ajustado e os pontos reais está totalmente errada, o que devo fazer ?

  2. Depois eu recebo o parâmetro do modelo I estabelecer, de que maneira eu avaliar o modelo, algo como RSS (soma de quadrados residual) para o modelo linear, ou o valor de p shapiro.test(), ks.test()e outro teste?

Eu sou pobre em conhecimento estatístico, você poderia me ajudar?

ps: tenho pesquisado no Google, stackoverflow e CV muitas vezes, mas não encontrei nada relacionado a esse problema

Ling Zhang
fonte
11
Eu fiz essa pergunta pela primeira vez no stackoverflow, mas parecia que essa pergunta pertence ao CV, o amigo disse que eu não entendi a função de massa de probabilidade e a função de densidade de probabilidade, não consegui entender completamente, então me perdoe por responder a essa pergunta novamente em CV
Ling Zhang
11
Seu cálculo de densidades está incorreto. Uma maneira simples de calcular é h <- hist(x, 1000, plot = FALSE); t1 <- data.frame(x = h$mids, y = h$density).
@ Pascal você está certo, eu resolvi o primeiro trimestre, obrigado!
Ling Zhang
Veja a resposta abaixo, a densityfunção é útil.
Eu entendo, obrigado novamente para editar e resolver a minha pergunta
Ling Zhang

Respostas:

11

Questão 1

O modo como você calcula a densidade manualmente parece errado. Não há necessidade de arredondar os números aleatórios da distribuição gama. Como o @Pascal observou, você pode usar um histograma para plotar a densidade dos pontos. No exemplo abaixo, eu uso a função densitypara estimar a densidade e plotá-la como pontos. Apresento o ajuste tanto com os pontos quanto com o 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()

Densidade gama

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

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

Aqui está a solução que o @Pascal forneceu:

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()

Pontos de densidade do histograma

Questão 2

Para avaliar a qualidade do ajuste, recomendo o pacote fitdistrplus. Aqui está como ele pode ser usado para ajustar duas distribuições e comparar seus ajustes graficamente e numericamente. O comando gofstatimprime várias medidas, como AIC, BIC e algumas estatísticas estatísticas, como o Teste KS, etc. Elas são usadas principalmente para comparar ajustes de diferentes distribuições (neste caso gama versus Weibull). Mais informações podem ser encontradas na minha resposta aqui :

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)

A @NickCox recomenda, com razão, que o QQ-Plot (painel superior direito) é o melhor gráfico individual para avaliar e comparar ajustes. Densidades ajustadas são difíceis de comparar. Eu incluo os outros gráficos também por uma questão de integridade.

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
fonte
11
Eu não pode revisar, mas você tem um problema com a crase para fitdistrpluse gofstatem sua ansewer
2
Recomendação de uma linha: o gráfico quantil-quantil é o melhor gráfico único para essa finalidade. É difícil fazer comparações entre densidades observadas e ajustadas. Por exemplo, é difícil identificar desvios sistemáticos com altos valores que, científica e praticamente são frequentemente muito importantes.
Nick Cox
11
Ainda bem que concordamos. O OP começa com 10.000 pontos. Muitos problemas começam com muito menos e, em seguida, obter uma boa idéia da densidade pode ser problemático.
Nick Cox
11
@LingZhang Para comparar ajustes, você pode olhar o valor da AIC. O ajuste com o AIC mais baixo é o preferido. Além disso, eu discordo que a distribuição Weibull e Gamma são as mesmas no QQ-Plot. Os pontos do ajuste Weibull estão mais próximos da linha em comparação com o ajuste Gamma, especialmente nas caudas. Do mesmo modo, o AIC para o ajuste Weibull é menor comparado ao ajuste Gamma.
precisa saber é o seguinte
11
Mais reto é melhor. Além disso, consulte stats.stackexchange.com/questions/111010/…. Os princípios são os mesmos. O desvio sistemático da linearidade é um problema.
Nick Cox