opt_circ_bw {cylcop} | R Documentation |
Find the Optimal Bandwidth for a Circular Kernel Density Estimate
Description
This function basically wraps circular::bw.cv.ml.circular()
and circular::bw.nrd.circular()
of the 'circular'
package, simplifying their inputs. For more control,
these 'circular' functions could be used directly.
The normal reference distribution ("nrd"
) method of finding the bandwidth
parameter might give very bad results,
especially for multi-modal population distributions.
In these cases it can help to set kappa.est = "trigmoments"
.
Usage
opt_circ_bw(theta, method = c("cv", "nrd"), kappa.est = "trigmoments")
Arguments
theta |
|
method |
character string describing the method,
either |
kappa.est |
character string describing how the spread is estimated.
Either maximum likelihood |
Details
method="nrd"
is somewhat similar to the linear case (see
fit_steplength()
). Instead of matching a normal distribution to
the data and then calculating its optimal bandwidth, a von Mises distribution is used.
To match that von Mises distribution to the data we can either find its concentration
parameter kappa using maximum likelihood (kappa.est="ML"
) or by trigonometric moment
matching (kappa.est="trigmoments"
). When the data is multimodal, fitting a
(unimodal) von Mises distribution using maximum likelihood will probably give bad
results. Using kappa.est="trigmoments"
potentially works better in those cases.
As an alternative, the bandwidth can be found by maximizing the cross-validation likelihood
(method="cv"
). However, with this leave-one-out cross-validation scheme, at every
likelihood optimization step, n(n-1)
von Mises densities need to be calculated, where
n=
length(theta)
. Therefore, this method can become quite slow with
large sample sizes.
Value
A numeric value, the optimized bandwidth.
See Also
circular::bw.cv.ml.circular()
,
circular::bw.nrd.circular()
,
opt_circ_bw()
.
Examples
require(circular)
require(graphics)
set.seed(123)
n <- 10 #n (number of samples) is set small for performance. Increase n to
# a value larger than 1000 to see the effects of multimodality
angles <- rvonmisesmix(n,
mu = c(0,pi),
kappa = c(2,1),
prop = c(0.5,0.5)
)
bw1 <- opt_circ_bw(theta = angles, method="nrd", kappa.est = "ML")
bw2 <- opt_circ_bw(theta = angles, method="nrd", kappa.est = "trigmoments")
bw3 <- opt_circ_bw(theta = angles, method="cv")
dens1 <- fit_angle(theta = angles, parametric = FALSE, bandwidth = bw1)
dens2 <- fit_angle(theta = angles, parametric = FALSE, bandwidth = bw2)
dens3 <- fit_angle(theta = angles, parametric = FALSE, bandwidth = bw3)
true_dens <- dvonmisesmix(
seq(-pi,pi,0.001),
mu = c(0,pi),
kappa = c(2,1),
prop = c(0.5,0.5)
)
if(interactive()){
plot(seq(-pi, pi, 0.001), true_dens, type = "l")
lines(as.double(dens1$x), as.double(dens1$y), col = "red")
lines(as.double(dens2$x), as.double(dens2$y), col = "green")
lines(as.double(dens3$x), as.double(dens3$y), col = "blue")
}