Tracking several criteria simultaneously.
The most direct approach is to simply fit several response surfaces. Then, we can visually inspect results to find factor configurations with desirable values across each response.
To illustrate, we will work with a chemical process dataset, which varied temperature and time in some chemical process and observed changes in three responses – yield, viscosity, and molecular weight. The block below reads in the data and defines a version, mchem
that puts all three responses into one column, using pivot_longer
. We standardize all the responses in mchem
so that when we plot them below, the colors are all on the same scale.
ggplot(mchem) +
geom_point(
aes(time, temp, col = value),
position = position_jitter(w = 0.3, h = 0.3)
) +
facet_grid(. ~ response) +
scale_color_viridis_c()
library(rsm)
chem_coded <- coded.data(chem, time_coded ~ (time - 35) / 5, temp_coded ~ (temp - 155) / 5)
fits <- list(
"yield" = rsm(yield ~ SO(temp_coded, time_coded), data = chem_coded),
"viscosity" = rsm(viscosity ~ SO(temp_coded, time_coded), data = chem_coded),
"molecular_weight" = rsm(molecular_weight ~ SO(temp_coded, time_coded), data = chem_coded)
)
contour(fits[[1]], ~ time_coded + temp_coded, image = TRUE, asp = 1)
contour(fits[[2]], ~ time_coded + temp_coded, image = TRUE, asp = 1)
contour(fits[[3]], ~ time_coded + temp_coded, image = TRUE, asp = 1)
The main downside of the constrained optimization approach is that it forces us to choose one response to prioritize over all others. What if we care about each response more or less equally?
One idea is to optimize a sort of (geometric) averaged response, \[\begin{align*} \underset{x}{\text{maximize}}\medspace \left[\prod_{r = 1}^{R} y_{r}\left(x\right)\right]^{\frac{1}{R}} \end{align*}\]
The issue with this idea is that it treats all responses exactly equally. What if we want to maximize some, but minimize others? What if we want some to be near some target value?
The solution is to use desirability functions. A few are plotted below. You can adjust their shape so that the \(r^{th}\) desirability function is large for the values of \(y_{r}\left(x\right)\) which are good (sloping down when you want to minimize, sloping up when you want to maximize).
desirability
package.coded <- as.data.frame(chem_coded)
x_grid <- expand.grid(
time_coded = seq(min(coded$time_coded), max(coded$time_coded), .1),
temp_coded = seq(min(coded$temp_coded), max(coded$temp_coded), 0.1)
)
ggplot(desirabilities) +
geom_tile(
aes(time_coded, temp_coded, fill = objective)
) +
coord_fixed() +
scale_fill_viridis_c()