Diseños \(2^{k}\)

Para el primer desarrollo se trabaja con un diseño completo \(2^{k}\) donde \(k = 2\). La base de datos será la propuesta por Gutierrez(1998). Para este ejemplo, interesa conocer los efectos en la respuesta media de la vibración de una ranura. Tenemos dos factores \(x_{1}\) el cual es tamaño de la broca y \(x_{2}\) la velocidad. Para \(x_{1}: -1 = 1/16 \text{pulgadas}, +1 = 1/8 \text{pulgadas}\). Para el fector 2 \(x_{2}: -1 = 40, +1 = 90\).

library(dplyr)
y = c( 18.2, 27.2, 15.9, 41.0, 18.9, 24.0, 14.5, 43.9, 12.9, 22.4, 15.1,
       36.3, 14.4, 22.5, 14.2, 39.9)
x1 = c(-1, +1, -1, +1, -1, +1, -1, +1, -1, +1, -1, +1, -1, +1, -1, +1 )
x2 = c(-1, -1, +1, +1, -1, -1, +1, +1, -1, -1, +1, +1, -1, -1, +1, +1 )
datos = data.frame(y, x1, x2)
head(datos)
     y x1 x2
1 18.2 -1 -1
2 27.2  1 -1
3 15.9 -1  1
4 41.0  1  1
5 18.9 -1 -1
6 24.0  1 -1

Para empezar se realiza una inspección gráfica con gráficos de cajas y alambres:

par(mfrow = c(1,2))
boxplot(y ~ x1, main = "Vibraciones por tamaño")
boxplot(y ~ x2, main = "Vibraciones por velocidad")

par(mfrow = c(1,1))

Como se observa, parece que existen diferencias entre los dos niveles de velocidad de de la broca y el tamaño de la broca para explicar las vibraciones. Para conocer si existe evidencia de efectos en las interacciones, se calcula el mapa de contorno de la regresión lineal buscando curvaturas sobre las curvas de nivel del plano \(x_{1}, x_{2}\):

library(rsm)
modelo1 <- rsm(y ~ FO(x1, x2, x1*x2), data = datos)
par(mfrow = c(1,2))
persp(modelo1, x2 ~ x1, 
      zlab = "y", 
      contours = list(z = "bottom", col = "colors"), # posicion y color
      at = c(summary(modelo1$canonical$xs)),
      theta = 15, # coordenadas graficas
      phi = 20)

# Grafico de contornos
contour(modelo1, ~ x1 + x2, image = TRUE)

Como se observa en la curva de nivel del hiperplano de la regresión muestra cierto nivel de curvatura por lo que quizá se detecten diferencias significativas en el ANOVA. Se calcula ahora el análisis de varianza:

anova(lm(y ~ x1 + x2 + x1*x2))
## Analysis of Variance Table
## 
## Response: y
##           Df  Sum Sq Mean Sq F value    Pr(>F)    
## x1         1 1107.23 1107.23 185.252 1.175e-08 ***
## x2         1  227.26  227.26  38.023 4.826e-05 ***
## x1:x2      1  303.63  303.63  50.801 1.201e-05 ***
## Residuals 12   71.72    5.98                      
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
interaction.plot(x.factor = x1, trace.factor = x2, response = y)

orden = seq(1,16,1)
modelo1 = lm(y ~ x1 + x2 + x1*x2)
par(mfrow=c(2,2))
residuos = modelo1$residuals
estimado = modelo1$fitted.values
plot(y = residuos, x = estimado, main = "A")
plot(x1, residuos, main = "B")
qqnorm(residuos, main = "C")
qqline(residuos)
plot(residuos, orden, main = "D")

El siguiente ejemplo procede de Monstgomery(), en el se presenta un estudio sobre el efecto del porcentaje de carbonatación (A), la preparación de la operación (B) yla velocidad de linea sobre la altura de llenado de una bebida carbonatada. La variable de respuesta (y) es la desviación de la altura de llenado. Este es un ejemplo aplicado al control de calidad. Los datos son los siguientes:

A = c(-1,+1,-1,+1,-1,+1,-1,+1,-1,+1,-1,+1,-1,+1,-1,+1)
B = c(-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1)
C = c(-1,-1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,+1,+1)
y = c(-3,0,-1,2,-1,2,1,6, -1,1,0,3,0,1,1,5)
datos = data.frame(A,B,C,y)
head(datos)
##    A  B  C  y
## 1 -1 -1 -1 -3
## 2  1 -1 -1  0
## 3 -1  1 -1 -1
## 4  1  1 -1  2
## 5 -1 -1  1 -1
## 6  1 -1  1  2

Realizamos una inspección con un gráfico de cajas y alambres:

par(mfrow = c(1,3))
boxplot(y ~ A)
boxplot(y ~ B)
boxplot(y ~ C)

Realizamos el ANOVA para analizar tanto si existen diferencias significativas entre factores como para analizar la significancia de las interacciones:

modelo1 = lm(y ~ A*B*C, data = datos)
anova(modelo1)
## Analysis of Variance Table
## 
## Response: y
##           Df Sum Sq Mean Sq F value    Pr(>F)    
## A          1  36.00  36.000    57.6 6.368e-05 ***
## B          1  20.25  20.250    32.4 0.0004585 ***
## C          1  12.25  12.250    19.6 0.0022053 ** 
## A:B        1   2.25   2.250     3.6 0.0943498 .  
## A:C        1   0.25   0.250     0.4 0.5447373    
## B:C        1   1.00   1.000     1.6 0.2415040    
## A:B:C      1   1.00   1.000     1.6 0.2415040    
## Residuals  8   5.00   0.625                      
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Siguiendo a Montgomery() solo los efectos principales son significativos y la interacción de A y B pero solo con una significacia estadística del 90%. El modelo de regresión propuesto y el gráfico de contorno es el siguiente:

modelo2 = lm(y ~ A + B + C + A*B, data = datos)
summary(modelo2)
## 
## Call:
## lm(formula = y ~ A + B + C + A * B, data = datos)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -1.1250 -0.4375 -0.1250  0.4375  1.1250 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)    1.000      0.203   4.927 0.000452 ***
## A              1.500      0.203   7.391 1.38e-05 ***
## B              1.125      0.203   5.543 0.000175 ***
## C              0.875      0.203   4.311 0.001233 ** 
## A:B            0.375      0.203   1.848 0.091700 .  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.8118 on 11 degrees of freedom
## Multiple R-squared:  0.9071, Adjusted R-squared:  0.8733 
## F-statistic: 26.84 on 4 and 11 DF,  p-value: 1.267e-05
library(rsm)
modelo2 <- rsm(y ~ FO(A, B, A*B), data = datos)
par(mfrow = c(1,2))
persp(modelo2, A ~ B, 
      zlab = "y", 
      contours = list(z = "bottom", col = "colors"), # posicion y color
      #at = c(summary(modelo1$canonical$xs)),
      theta = 15, # coordenadas graficas
      phi = 20)
contour(modelo2, ~ A + B, image = TRUE)

Se calcula ahora el gráfico de interacción entre variables A y B:

interaction.plot(x.factor = A, trace.factor = B, response = y)

Finalmente comprobamos los supuestos

orden = seq(1,16,1)
modelo1 = lm(y ~ A + B + C + A*B)
par(mfrow=c(2,3))
residuos = modelo1$residuals
estimado = modelo1$fitted.values
plot(y = residuos, x = estimado)
qqnorm(residuos)
qqline(residuos)
plot(residuos, orden)
plot(A, residuos)
plot(B, residuos)
plot(C, residuos)

Diseños Fraccionados

Para este caso seguiremos a Montgomery(). Se investigaron cinco factores de un proceso de manufactura de un circuito integrado en un diseño \(2^{5-1}\). Los factores fueron: A = Ajuste de apertura (pequeña y grande), B = tiempo de exposición (20% abajo del nominal, 20% arriba del nominal), C = tiempo de desarrollo (30s, 40s), D = Tamaño de la máscara (pequeña, grande) y E = Tiempo de grabado (14.5min, 15.5min) y el y = rendimiento.

A = c(-1,+1,-1,+1,-1,+1,-1,+1,-1,+1,-1,+1,-1,+1,-1,+1)
B = c(-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1,-1,-1,+1,+1)
C = c(-1,-1,-1,-1,+1,+1,+1,+1,-1,-1,-1,-1,+1,+1,+1,+1)
D = c(-1,-1,-1,-1,-1,-1,-1,-1,+1,+1,+1,+1,+1,+1,+1,+1)
E = c(+1,-1,-1,+1,-1,+1,+1,-1,-1,+1,+1,-1,+1,-1,-1,+1)
y = c(8,9,34,52,16,22,45,60,6,10,30,50,15,21,44,63)
datos = data.frame(A,B,C,D,E,y)
head(datos)
##    A  B  C  D  E  y
## 1 -1 -1 -1 -1  1  8
## 2  1 -1 -1 -1 -1  9
## 3 -1  1 -1 -1 -1 34
## 4  1  1 -1 -1  1 52
## 5 -1 -1  1 -1 -1 16
## 6  1 -1  1 -1  1 22

Realizamos la revisión de los dos primeros efectos del diseño experimental:

modelo3 = lm(y ~ (.)^2, data = datos)
summary(modelo3)
## 
## Call:
## lm(formula = y ~ (.)^2, data = datos)
## 
## Residuals:
## ALL 16 residuals are 0: no residual degrees of freedom!
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)
## (Intercept)  30.3125         NA      NA       NA
## A             5.5625         NA      NA       NA
## B            16.9375         NA      NA       NA
## C             5.4375         NA      NA       NA
## D            -0.4375         NA      NA       NA
## E             0.3125         NA      NA       NA
## A:B           3.4375         NA      NA       NA
## A:C           0.1875         NA      NA       NA
## A:D           0.5625         NA      NA       NA
## A:E           0.5625         NA      NA       NA
## B:C           0.3125         NA      NA       NA
## B:D          -0.0625         NA      NA       NA
## B:E          -0.0625         NA      NA       NA
## C:D           0.4375         NA      NA       NA
## C:E           0.1875         NA      NA       NA
## D:E          -0.6875         NA      NA       NA
## 
## Residual standard error: NaN on 0 degrees of freedom
## Multiple R-squared:      1,  Adjusted R-squared:    NaN 
## F-statistic:   NaN on 15 and 0 DF,  p-value: NA

Como se observa no es posible estimar la significacia estadística de los coeficientes de la regresión debido a que se requiere más información de la disponible. Para aplicar el diseño fraccionado se realiza una inspección gráfica.

Se realiza el gráfico de probabilidad normal o gráfico de Daniel. Este gráfico muestra los efectos estandarizados relacionada con una línea de ajuste de distribución para el caso en que todos los efectos son cero. Los efectos estandarizados son estadísticos t y prueban la hipótesis nula de que el efecto es igual a 0. Este gráfico ayuda a definir la posible significancia estadística de los efectos de un modelo factorial donde no es posible inspeccionar mediante regresión la signifcancia estadística de los coeficientes.

library(daewr)
LGB(coef(modelo3)[-1], rpt = FALSE)

Una vez seleccionados los efectos solo tomaremos la fracción de efectos de A, B, C y AB.

modelo4 = lm(y ~ A + B + C + A*B, data = datos)
anova(modelo4)
## Analysis of Variance Table
## 
## Response: y
##           Df Sum Sq Mean Sq  F value    Pr(>F)    
## A          1  495.1   495.1  193.195 2.535e-08 ***
## B          1 4590.1  4590.1 1791.244 1.560e-13 ***
## C          1  473.1   473.1  184.610 3.214e-08 ***
## A:B        1  189.1   189.1   73.781 3.302e-06 ***
## Residuals 11   28.2     2.6                       
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Se muestra el gráfico de la interacción de los factores AB

interaction.plot(x.factor = A, trace.factor = B, response = y)

Finalmente revisamos los supuestos del modelo

orden = seq(1,16,1)
modelo1 = lm(y ~ A + B + C + A*B)
par(mfrow=c(2,3))
residuos = modelo1$residuals
estimado = modelo1$fitted.values
plot(y = residuos, x = estimado)
qqnorm(residuos)
qqline(residuos)
plot(residuos, orden)
plot(A, residuos)
plot(B, residuos)
plot(C, residuos)

El en siguiente ejemplo se utiliza la base de datos de Carreón (2022) donde se buscan los factores e interacciones importantes en un proceso químico. Para este caso se busca resolver un análisis fraccionario en un diseño \(2^{5-1}\).

datos <- read.csv("https://raw.githubusercontent.com/jpch26/Fractional-Designs-with-R/master/data/yield_data.csv")
head(datos)
##   FeedRate Catalyst AgitationSpeed Temperature Concentration Yield
## 1       -1       -1             -1          -1             1    56
## 2        1       -1             -1          -1            -1    53
## 3       -1        1             -1          -1            -1    63
## 4        1        1             -1          -1             1    65
## 5       -1       -1              1          -1            -1    53
## 6        1       -1              1          -1             1    55

Si se realiza la regresión por mínimos cuadrados ya que solo se tienen 16 observaciones.

modelo4 <- lm(Yield ~ (.)^2, data = datos)
summary(modelo4)
## 
## Call:
## lm(formula = Yield ~ (.)^2, data = datos)
## 
## Residuals:
## ALL 16 residuals are 0: no residual degrees of freedom!
## 
## Coefficients:
##                                Estimate Std. Error t value Pr(>|t|)
## (Intercept)                   6.525e+01         NA      NA       NA
## FeedRate                     -1.000e+00         NA      NA       NA
## Catalyst                      1.025e+01         NA      NA       NA
## AgitationSpeed                1.544e-16         NA      NA       NA
## Temperature                   6.125e+00         NA      NA       NA
## Concentration                -3.125e+00         NA      NA       NA
## FeedRate:Catalyst             7.500e-01         NA      NA       NA
## FeedRate:AgitationSpeed       2.500e-01         NA      NA       NA
## FeedRate:Temperature         -3.750e-01         NA      NA       NA
## FeedRate:Concentration        6.250e-01         NA      NA       NA
## Catalyst:AgitationSpeed       7.500e-01         NA      NA       NA
## Catalyst:Temperature          5.375e+00         NA      NA       NA
## Catalyst:Concentration        6.250e-01         NA      NA       NA
## AgitationSpeed:Temperature    1.250e-01         NA      NA       NA
## AgitationSpeed:Concentration  1.125e+00         NA      NA       NA
## Temperature:Concentration    -4.750e+00         NA      NA       NA
## 
## Residual standard error: NaN on 0 degrees of freedom
## Multiple R-squared:      1,  Adjusted R-squared:    NaN 
## F-statistic:   NaN on 15 and 0 DF,  p-value: NA

Para realizar el diseño fraccionado se realiza el gráfico de Daniel, ahora con la librería DanielPlot del paquete FrF2

library("FrF2")
## Loading required package: DoE.base
## Loading required package: grid
## Loading required package: conf.design
## 
## Attaching package: 'DoE.base'
## The following objects are masked from 'package:stats':
## 
##     aov, lm
## The following object is masked from 'package:graphics':
## 
##     plot.design
## The following object is masked from 'package:base':
## 
##     lengths
DanielPlot(modelo4)

Como se observa el número de efectos principales que son significativos es reducido, se pueden ampliar nuestra visión realizando un gráfico de pareto:

library(ggplot2)

coeficientes <- coefficients(modelo4)[-1] # We discard the intercept

efectos <- data.frame(
  Efecto = names(coeficientes),
  Valor  = unname(coeficientes),
  ValorAbsoluto = abs(unname(coeficientes)),
  Signo   = as.character(unname(sign(coeficientes)))
  )

ggplot(efectos, aes(ValorAbsoluto, reorder(Efecto, -ValorAbsoluto, abs))) +
  geom_col(aes(fill = Signo)) +
  xlab("Magnitud del Efecto") +
  ylab("Efecto") +
  theme_minimal()

Se toma solo los factores con los efectos más grandes para realizar el análisis de varianza.

modelo5 <- lm(Yield ~ Catalyst*Temperature*Concentration, data = datos)
anova(modelo5)
## Analysis of Variance Table
## 
## Response: Yield
##                                    Df  Sum Sq Mean Sq  F value    Pr(>F)    
## Catalyst                            1 1681.00 1681.00 213.4603 4.725e-07 ***
## Temperature                         1  600.25  600.25  76.2222 2.316e-05 ***
## Concentration                       1  156.25  156.25  19.8413  0.002127 ** 
## Catalyst:Temperature                1  462.25  462.25  58.6984 5.953e-05 ***
## Catalyst:Concentration              1    6.25    6.25   0.7937  0.398998    
## Temperature:Concentration           1  361.00  361.00  45.8413  0.000142 ***
## Catalyst:Temperature:Concentration  1    1.00    1.00   0.1270  0.730795    
## Residuals                           8   63.00    7.88                       
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Comos se puede observar de los efectos seleccionados solo Catalyst:Concentration no fue significativo, así como el efecto de tercer orden Catalyst:Temperature:Concentration.