There is probably not a hard answer for this, but I am wondering if you need to collect more data when trying to estimate the parameters of generalized pareto distribution well?
The reason I ask is because I am trying to estimate the parameters of a generalized pareto distribution using Bayesian estimation, and my parameter estimates seem to be very good when I have lots of data (say, 1000+ data points), but when I drop the data size to say 100 then the estimates can be very poor.
For example, if I have a generalized pareto distribution with true parameters $\mu=0$, $\sigma=1.2$, and $\xi=0.8$, and I sample $N=1000$ observations then (running my Bayesian algorithm) I get estimates of $\hat\sigma=1.27$ 95% CI: $(1.12, 1.46)$ and $\hat\xi=0.83$ 95% CI: $(0.72, 0.98)$.
However, if I drop the same size to $N=100$ I get $\hat\sigma=0.87$ 95% CI: $(0.55, 1.24)$ and $\hat\xi=0.94$ 95% CI: $(0.61, 1.38)$.
If I keep decreasing $N$, the point estimates of $\sigma$ and $\xi$ only get worst. Is there a rule of thumb about how much data is need for extreme value distributions? In most cases, 100 data points would be sufficient for modeling a distribution that doesn't have too extreme of values (say, normal, exponential, gamma, etc.). In my application I will always be dealing with less than 100 data points and so is it a bad idea to use the generalized pareto distribution?
Here is an example of code doing what I am trying to explain:
# log-likelihood
likelihood <- function(x, xi, sigma){
llik <- -log(sigma) - (1 / xi + 1) * log(1 + xi * x / sigma)
lik <- sum(llik)
return(lik)
}
# log(prior)
prior <- function(xi, sigma){
prior1 <- dgamma(xi, .01, .01, log = TRUE)
prior2 <- dgamma(sigma, .01, .01, log = TRUE)
prior <- (prior1 + prior2)
return(prior)
}
# log(posterior)
posterior <- function(x, xi, sigma){
post <- likelihood(x, xi, sigma) + prior(xi, sigma)
return(post)
}
##############################################################
### Function to simulate data from GPD
##############################################################
gpd <- function(n, mu, sigma, xi){
u <- runif(n)
x = mu + sigma * (u^-xi - 1) / xi
return(x)
}
set.seed(4)
N = 1000 # Number of data points
x = gpd(N, 0, 1.2, .8) # Here mu = 0, sigma = 1.2, and xi = 0.8
S <- 10000
xi <- rep(NA, S)
sigma <- rep(NA, S)
xi[1] <- 1
sigma[1] <- 1
for(i in 2:S){
# MCMC for xi
xi.star = xi[i-1] + rnorm(1,0)
if(xi.star < 0){
alpha = 0
}else{
ratio <- exp(posterior(x, xi.star, sigma[i-1]) - posterior(x, xi[i-1], sigma[i-1]))
alpha <- min(1, ratio)
}
if(runif(1) < alpha){
xi[i] <- xi.star
}else{
xi[i] <- xi[i - 1]
}
# MCMC for sigma
sigma.star = xi[i-1] + rnorm(1,0)
if(sigma.star < 0){
alpha = 0
}else{
ratio <- exp(posterior(x, xi[i-1], sigma.star) - posterior(x, xi[i-1], sigma[i-1]))
alpha <- min(1, ratio)
}
if(runif(1) < alpha){
sigma[i] <- sigma.star
}else{
sigma[i] <- sigma[i - 1]
}
}
sigma <- sigma[5000:S]
xi <- xi[5000:S]
mean(sigma)
mean(xi)