Nothing
## ----load ino, include = FALSE------------------------------------------------
library("ino")
## ----faithful-plot------------------------------------------------------------
library("ggplot2")
ggplot(faithful, aes(x = eruptions)) +
geom_histogram(aes(y = after_stat(density)), bins = 30) +
xlab("eruption time (min)")
## ----define mixture ll--------------------------------------------------------
normal_mixture_llk <- function(mu, sigma, lambda, data) {
sigma <- exp(sigma)
lambda <- plogis(lambda)
sum(log(lambda * dnorm(data, mu[1], sigma[1]) + (1 - lambda) * dnorm(data, mu[2], sigma[2])))
}
normal_mixture_llk(mu = 1:2, sigma = 3:4, lambda = 5, data = faithful$eruptions)
## ----initialize Nop-----------------------------------------------------------
Nop_mixture <- Nop$new(
f = normal_mixture_llk, # the objective function
target = c("mu", "sigma", "lambda"), # names of target arguments
npar = c(2, 2, 1), # lengths of target arguments
data = faithful$eruptions # values for fixed arguments
)
## ----example evaluation-------------------------------------------------------
Nop_mixture$evaluate(at = 1:5) # same values as above
## ----define optimizer---------------------------------------------------------
nlm <- optimizeR::Optimizer$new(which = "stats::nlm")
Nop_mixture$set_optimizer(nlm)
## ----example optimization-----------------------------------------------------
set.seed(1)
Nop_mixture$
initialize_random(runs = 20)$
optimize(which_direction = "max", optimization_label = "random")
## ----access results-----------------------------------------------------------
Nop_mixture$results
## ----overview optima----------------------------------------------------------
Nop_mixture$optima(which_direction = "max", digits = 0)
## ----global and local optimum-------------------------------------------------
global <- Nop_mixture$maximum$parameter
library("dplyr")
local <- Nop_mixture$results |>
slice_min(abs(value - (-421)), n = 1) |>
pull(parameter) |>
unlist()
## ----transform parameter------------------------------------------------------
transform <- function(theta) c(theta[1:2], exp(theta[3:4]), plogis(theta[5]))
(global <- transform(global))
(local <- transform(local))
## ----estimated-mixtures-------------------------------------------------------
mixture_density <- function (data, mu, sigma, lambda) {
lambda * dnorm(data, mu[1], sigma[1]) + (1 - lambda) * dnorm(data, mu[2], sigma[2])
}
ggplot(faithful, aes(x = eruptions)) +
geom_histogram(aes(y = after_stat(density)), bins = 30) +
labs(x = "eruption time (min)", colour = "parameter") +
stat_function(
fun = function(x) {
mixture_density(x, mu = global[1:2], sigma = global[3:4], lambda = global[5])
}, aes(color = "global"), linewidth = 1
) +
stat_function(
fun = function(x) {
mixture_density(x, mu = local[1:2], sigma = local[3:4], lambda = local[5])
}, aes(color = "local"), linewidth = 1
)
## ----grid initial-------------------------------------------------------------
Nop_mixture$initialize_grid(
lower = c(1.5, 3.5, log(0.5), log(0.5), qlogis(0.4)), # lower bounds for the grid
upper = c(2.5, 4.5, log(1.5), log(1.5), qlogis(0.6)), # upper bounds for the grid
breaks = c(3, 3, 3, 3, 3), # breaks for the grid in each dimension
jitter = TRUE # random shuffle of the grid points
)
## ----steepest gradient--------------------------------------------------------
Nop_mixture$
initialize_promising(proportion = 0.1, condition = "gradient_large")$
optimize(which_direction = "max", optimization_label = "promising_grid")
## ----overview comparison------------------------------------------------------
Nop_mixture$optima(which_direction = "max", group_by = "optimization", digits = 0)
## ----define em, include = FALSE-----------------------------------------------
em <- function(f, theta, ..., epsilon = 1e-08, iterlim = 1000, data) {
llk <- f(theta, ...)
mu <- theta[1:2]
sigma <- exp(theta[3:4])
lambda <- plogis(theta[5])
for (i in 1:iterlim) {
class_1 <- lambda * dnorm(data, mu[1], sigma[1])
class_2 <- (1 - lambda) * dnorm(data, mu[2], sigma[2])
posterior <- class_1 / (class_1 + class_2)
lambda <- mean(posterior)
mu[1] <- mean(posterior * data) / lambda
mu[2] <- (mean(data) - lambda * mu[1]) / (1 - lambda)
sigma[1] <- sqrt(mean(posterior * (data - mu[1])^2) / lambda)
sigma[2] <- sqrt(mean((1 - posterior) * (data - mu[2])^2) / (1 - lambda))
llk_old <- llk
theta <- c(mu, log(sigma), qlogis(lambda))
llk <- f(theta, ...)
if (is.na(llk)) stop("em failed")
if (abs(llk - llk_old) < epsilon) break
}
list("llk" = llk, "estimate" = theta, "iterations" = i)
}
em_optimizer <- optimizeR::Optimizer$new("custom")
em_optimizer$definition(
algorithm = em,
arg_objective = "f",
arg_initial = "theta",
out_value = "llk",
out_parameter = "estimate",
direction = "max"
)
em_optimizer$set_arguments("data" = faithful$eruptions)
## ----set optim and em algorithm-----------------------------------------------
optim <- optimizeR::Optimizer$new(which = "stats::optim")
Nop_mixture$
set_optimizer(optim)$
set_optimizer(em_optimizer)
## ----optimizer comparison-----------------------------------------------------
Nop_mixture$
initialize_random(runs = 100)$
optimize(which_direction = "max", optimization_label = "optimizer_comparison")
## ----plot-seconds-------------------------------------------------------------
Nop_mixture$results |>
filter(.optimization_label == "optimizer_comparison") |>
autoplot(which_element = "seconds", group_by = "optimizer", relative = TRUE) +
scale_x_continuous(labels = scales::percent_format()) +
labs(
"x" = "optimization time relative to overall median",
"y" = "optimizer"
)
## ----overview optima em-------------------------------------------------------
Nop_mixture$optima(which_direction = "max", group_by = "optimizer", digits = 0)
## ----extract best-------------------------------------------------------------
Nop_mixture$maximum
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.