Plot the likelihood of weibull - r

I would like to plot the likelihood function of a size 1000 weibull sample with a sequence of shape parameter theta. I have used standardised weibull so the scale lambda is 1. However the output is a horizontal straight line.
n<-1000
lik <- function(theta, x){
K<- length(theta)
n<- length(x)
out<- rep(0,K)
for(k in 1:K){
out[k] <- prod(dweibull(x, shape= theta[k], scale=1))
}
return(out)
}
theta<-seq(0.01, 10, by = 0.01)
x <- rweibull(n, shape= 0.5, scale= 1)
plot(theta, lik(theta, x), type="l", lwd=2)

There is nothing really wrong about what you have done but computers struggle to calculate the product of many small numbers and so can end up as zero (even 0.99^1000 = 4^-5). And so it is easier to log transform and then sum. (As the log transform is a monotonic increasing function maximising the log-likelihood is the same as maximising the likelihood).Thus change
prod(dweibull(x, shape= theta[k], scale=1))
to
sum(dweibull(x, shape= theta[k], scale=1, log=TRUE))
The other minor change is to plot the likelihood witihin a reasonable range of theta so that
you can see the curve.
Working code:
set.seed(1)
n<-1000
lik <- function(theta, x){
K <- length(theta)
n <- length(x)
out <- rep(0,K)
for(k in 1:K){
out[k] <- sum(dweibull(x, shape= theta[k], scale=1, log=TRUE))
}
return(out)
}
popTheta = 0.5
theta = seq(0.01, 1.5, by = 0.01)
x = rweibull(n, shape=popTheta, scale= 1)
plot(theta, lik(theta, x), type="l", lwd=2)
abline(v=popTheta)
theta[which.max( lik(theta, x))]

Related

Confidence Intervals while using nls()

I am writing a code to model the inactivation of bacteria. I was able to get the model using nls(). Now, when I am trying to calculate and plot the confidence and prediction intervals, I am unable to get a proper fit. The lower CI and PI are being plotted awry and I do not know how to rectify this issue.
My code:
Xo <- c(0, 0.461, 0.978, 2.087)
Y <- c(0, -2.891, -4.197, -4.489)
dat <- data.frame(Xo, Y, colClass="numeric")
f <- function(Xo, n, k) {-k*(Xo)^n}
m <- nls(Y~f(Xo, n, k), data=dat, start=c(n=2, k=20), trace=TRUE)
summary(m)
yfitted <- predict(m)
plot(Xo, yfitted)
lines(Xo, yfitted)
plot(dat$Xo, yfitted, xlim=c(0, 5), ylim=c(-5, 0))
y.conf <- predictNLS(m, interval="confidence", alpha =0.05, nsim=10000)$summary
y.pred <- predictNLS(m, interval="prediction", alpha=0.05, nsim=10000)$summary
matlines(Xo, y.conf[, c("Sim.2.5%", "Sim.97.5%")], col="red", lty="dashed")
matlines(Xo, y.pred[, c("Sim.2.5%", "Sim.97.5%")], col="blue", lty="solid")

Density Estimation on Single Point

I am trying to plot the densities by using non-parametric kernel estimation method. For this purpose 'm using asymmetrical kernels like Weibull, Gamma, Inverse Gaussian, etc. i have successfully plotted the densities as given in their articles. My query is about those graphs which are plotted on single point of x, specially x=0 as given in Birnbaum-Saunders and Lognormal Kernel Estimators for
Modelling Durations in High Frequency Financial Data on page # 108 and also some others presented the same thing. Simple density plots can be plotted by using following R code.
Kindly guide me how to plot on specific point.
n <- 200
k <- 400
y <- rexp(n, 1)
h <- 0.79 * IQR(y) * length(y) ^ (-1/5)
x <- seq(min(y) + 0.05, max(y), length=k)
Kbs <- matrix(rep(0, k * n), ncol=k)
fhat <- rep(0, k)
########### BS ###########
for (j in 1:k) {
for (i in 1:n) {
Kbs[i, j] <- (1 / (2*sqrt(2*h*pi))) *
((sqrt(1 / (x[j]*y[i]))) + (sqrt(x[j] / (y[i]^3)))) *
exp(- (y[i] / (2*h*x[j])) + (1/h) - (x[j]/(2*h*y[i])))
Kbs[is.nan(Kbs)] <- 0
}
fhat[j] <- 1/n * (sum(Kbs[, j]))
}
d1 <- density(y, bw=h)
plot(x, fhat, type="s", ylab="Density Function", lty=1, xlab="Time")
lines(d1, type="p", col="red")
legend("topright", c("Real Density", "Density by Birnbaum-Saunders Kernel"),
col=c("red", "black"), lty=c(1, 2))
Regards.

Calculating a tangent intersection with R

I am trying to add a tangent to my plot at the point x = 30 and I want to calculate the x-intersection of the tangent at y = 0.08.
I already found a very useful example, which I tried to use, but for some reason it is not working for y = 0.08.
I don't understand the meaning of deriv in the predict() function nor the actual difference in between pred0 and pred1. Can someone please explain?
x <- seq(0,40)
y <- dnorm(seq(0,40), mean=25, sd=5)
plot(x, y)
spl <- smooth.spline(y ~ x)
lines(spl, col="green")
newx <- 30
pred0 <- predict(spl, x=newx, deriv=0)
pred1 <- predict(spl, x=newx, deriv=1)
yint <- pred0$y - (pred1$y*newx)
xint <- -yint/pred1$y
xint
plot(x, y)
abline(h=0, col="red")
lines(spl, col="red")
points(pred0,col="red", pch=19)
lines(x, yint + pred1$y*x)
points(xint, 0, col="red", pch=19)
It seems like you have no problem calculating the tangent line and the intersect, but rather need some help in finding the x value for a given y value. This method will work for any smooth curve, but mark Gregors warning. There might not be a corresponding x value, or there might be several.
x <- seq(0, 40, by=0.01)
y <- dnorm(x, mean=25, sd=5)
spl <- smooth.spline(y ~ x)
plot(spl, type="l")
yval <- 0.08
ad <- abs(yval - spl$y)
if (min(ad) > max(diff(spl$y))*10) {
warning("The supplied y value is out of bounds")
}
xval <- x[which(diff(sign(diff(ad))) > 1) + 1]
points(xval, rep(yval, length(xval)))
With that xval you can calculate the tangent as you've already done.

How to adjust smoothness of spline

set.seed(1); x <- round(rnorm(30), 1); y <- sin(pi * x) + rnorm(30)/10
plot(x, y, main = "spline(x,y) when x has ties")
lines(spline(x, y, n = 201), col = 2)
Is there a way to adjust the smoothness of the spline? Especially from -0.5 and onwards, there are wiggly parts that could be smoother. I have looked at the documentation but there doesn't seem to be a straightforward parameter that does this (something like spar in smooth.spline).
loess is one method, but if you want to use splines, use smooth.spline, not the interpolating spline
set.seed(1);
x <- round(rnorm(30), 1);
y <- sin(pi * x) + rnorm(30)/10
plot(x, y, main = "spline(x,y) when x has ties")
sm <- smooth.spline(x, y, spar = 0.5) # play with spar
pred <- predict(sm, seq(-2, 2, by = 0.1))
lines(pred, col = "red")
There is a problem with this solution: note that in the negative region where points are less dense, the fit is not so good. loess is more local (that's what the l stands for), so it might be better.
I would use LOESS for smoothing:
lines(loess.smooth(y=spl[["y"]], x=spl[["x"]], span = 0.05), col=2)
Adjust span as needed.

Getting values from kernel density estimation in R

I am trying to get density estimates for the log of stock prices in R. I know I can plot it using plot(density(x)). However, I actually want values for the function.
I'm trying to implement the kernel density estimation formula. Here's what I have so far:
a <- read.csv("boi_new.csv", header=FALSE)
S = a[,3] # takes column of increments in stock prices
dS=S[!is.na(S)] # omits first empty field
N = length(dS) # Sample size
rseed = 0 # Random seed
x = rep(c(1:5),N/5) # Inputted data
set.seed(rseed) # Sets random seed for reproducibility
QL <- function(dS){
h = density(dS)$bandwidth
r = log(dS^2)
f = 0*x
for(i in 1:N){
f[i] = 1/(N*h) * sum(dnorm((x-r[i])/h))
}
return(f)
}
QL(dS)
Any help would be much appreciated. Been at this for days!
You can pull the values directly from the density function:
x = rnorm(100)
d = density(x, from=-5, to = 5, n = 1000)
d$x
d$y
Alternatively, if you really want to write your own kernel density function, here's some code to get you started:
Set the points z and x range:
z = c(-2, -1, 2)
x = seq(-5, 5, 0.01)
Now we'll add the points to a graph
plot(0, 0, xlim=c(-5, 5), ylim=c(-0.02, 0.8),
pch=NA, ylab="", xlab="z")
for(i in 1:length(z)) {
points(z[i], 0, pch="X", col=2)
}
abline(h=0)
Put Normal density's around each point:
## Now we combine the kernels,
x_total = numeric(length(x))
for(i in 1:length(x_total)) {
for(j in 1:length(z)) {
x_total[i] = x_total[i] +
dnorm(x[i], z[j], sd=1)
}
}
and add the curves to the plot:
lines(x, x_total, col=4, lty=2)
Finally, calculate the complete estimate:
## Just as a histogram is the sum of the boxes,
## the kernel density estimate is just the sum of the bumps.
## All that's left to do, is ensure that the estimate has the
## correct area, i.e. in this case we divide by $n=3$:
plot(x, x_total/3,
xlim=c(-5, 5), ylim=c(-0.02, 0.8),
ylab="", xlab="z", type="l")
abline(h=0)
This corresponds to
density(z, adjust=1, bw=1)
The plots above give:

Resources