De två exemplen nedan kommer från https://ovn.ing-stat.se/ [29] som också innehåller “FAQ,
Exercises, Graphs, Guides”. DoE (Design of Experiment,
Försöksplanering på svenska) innebär att man provocerar sin
process för att mäta utfallet under olika betingelser. Avsikten är att
förstå om och i så fall hur en variabel har signifikant
betydelse för utfallet.
Notera att om analysen finner att en eller
flera variabler (t.ex. tid och/eller temperatur) inte inte har
signifikant betydelse kan detta också vara intressant; varje
processägare blir sannolikt nöjd ty då kan ju dessa variabler sänkas
vilket sparar kostnader.
I allmänhet försöker man anpassa en
matematisk modell till mätresultaten och sedan använder man denna modell
för att förstå sambanden. Den modell som initialt används till bägge
exemplen nedan finns på skärmdumpen. En dylik modell blir ett skev plan
om det ritas som ett 3D-diagram. Se t.ex. fjärde diagrammet under
knappen ‘Graphs’, se länken ovan.
Varje skärmdump visar fyra slider som använts för simulering av data, en för varje β-parameter. Den nedersta sliden anger residualernas standardavvikelse (σ) som använts vid simulering av data (‘residualer’ är skillnaden mellan modell och mätvärde). De beräknade b-värdena anges i blått till höger.
Detta dokument delas in i två delar:
1. En DoE med två förklaringsvariabler, inget samspel
2. En DoE med två förklaringsvariabler, med samspel
1. En DoE med två förklaringsvariabler, inget samspel
Exemplet innehåller två förklaringsvariabler på två nivåer och inget samspel och då representerar modellen ett plan utan skevhet. Se t.ex. diagram 1-3 under ‘Graphs’ i ovanstående länk.
Följande R-kommandon visar data samt en tabell av den simulerade data. Variabel X1 och X2 är kodade med ‘-1’ respektive ‘+1’ för låg och hög nivå på variabelns ‘processvärden’. (Det fins många fördelar med en dylik kodning av försöksvariablerna):
library(kableExtra)
Ydata <- c(11.2, 10.1, 17.3, 18.1, 3.8, 2.4, 9.4, 10.2)
X1 <- c(+1, +1, +1, +1, -1, -1, -1, -1)
X2 <- c(-1, -1, +1, +1, -1, -1, +1, +1)
doe1Data <- data.frame(Ydata, X1, X2) # Skapar en sk. 'dataframe'.
data <- kable(head(doe1Data), "html")
kable_styling(data, "striped", position = "left", font_size = 17, full_width = FALSE) %>%
column_spec(1, width = "4cm") %>%
column_spec(2, width = "3cm") %>%
column_spec(3, width = "3cm")
| Ydata | X1 | X2 |
|---|---|---|
| 11.2 | 1 | -1 |
| 10.1 | 1 | -1 |
| 17.3 | 1 | 1 |
| 18.1 | 1 | 1 |
| 3.8 | -1 | -1 |
| 2.4 | -1 | -1 |
Nedanstående R-kommandon skapar samma diagram som i skärmdumpen för exempel 1:
library(ggplot2) # Rutiner som behövs för att rita graferna.
diaData <- data.frame(Ydata, X1)
Doe1Dia <- ggplot(diaData, aes(x = X1, y =Ydata)) + geom_point(color = "red", size = 3) +
xlab("Variabel X1") + ylab("Mätresultat") + scale_x_continuous(breaks=c(-1, 1),
limits=c(-1.2, 1.2), labels=c("-1", "+1")) +
theme(axis.text = element_text(color = "black", size = 13))
Doe1Dia + theme(axis.title.x = element_text(size = 11, color = "blue", face = "bold"),
axis.title.y = element_text(size = 11, color = "blue", face = "bold"))
Diagram över samspel, exempel 1. Det är vanligt att en analys av
mätvärden mot ett antal förklaringsvariabler innehåller s.k.
samspel (interaktion, interaction, Eng). Om man,
som här, har två förklaringsvariabler, X1 och X2, kallas ett samspel
mellan dem för ett tvåfaktorsamspel. I ett experiment med t.ex.
tre faktorer (X1, X2, X3) kan man ha samspel X1X2, X1X3, X2X3.
Teoretiskt sett kan det finnas X1X2X3-samspel men är ytterst osannolikt
i praktiska sammanhang.
I just detta exempel finns inte något
samspel och följande graf visar därför två parallella kurvor (den
matematiska analysen visar också om det finns eller inte finns samspel,
men en graf underlättar dock tolkningen):
interaction.plot(X1, X2, Ydata, fun = mean,
xlab = "Variabel X1",
ylab = "Medelvärde mätvärden",
main = "Samspelsdiagram mellan X1 och X2")
Analysen av data sker med en s.k. linjär modell, därav det inledande kommandot ‘lm’ som skapar en utskrift i form av en tabell. Tabellens viktigaste rader är ‘Intercept’ t.o.m. ‘X1:X2’ där varje rad är en term i modellen. Kolumnen ‘Estimate’ är skattningar av β-koefficienterna som naturligtvis är okända i verkligheten. Den högra kolumnen ’Pr(>|t|) är viktigast. Den anger om försöksvariabeln (eller termen) har någon betydelse. Gränsvärdet brukar sättas som 0.05. Alla rader utom samspelstermen (X1:X2) har låga värden. (Helt korrekt ty data var simulerat utan samspel. Denna term skall alltså bort i efterföljande analys):
analys1 <- lm(formula = Ydata ~ X1 + X2 + X1*X2) # Den linjära modellen ikl samspelsterm.
summary(analys1) # En sammanfattande tabell.
##
## Call:
## lm(formula = Ydata ~ X1 + X2 + X1 * X2)
##
## Residuals:
## 1 2 3 4 5 6 7 8
## 0.55 -0.55 -0.40 0.40 0.70 -0.70 -0.40 0.40
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 10.3125 0.2637 39.109 2.55e-06 ***
## X1 3.8625 0.2637 14.648 0.000126 ***
## X2 3.4375 0.2637 13.036 0.000200 ***
## X1:X2 0.0875 0.2637 0.332 0.756675
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.7458 on 4 degrees of freedom
## Multiple R-squared: 0.9897, Adjusted R-squared: 0.982
## F-statistic: 128.2 on 3 and 4 DF, p-value: 0.000198
Modellen ändras alltså och analysen görs om utan samspelstermen:
analys2 <- lm(formula = Ydata ~ X1 + X2) # Den linjära modellen, samspelstem borttagen.
summary(analys2)
##
## Call:
## lm(formula = Ydata ~ X1 + X2)
##
## Residuals:
## 1 2 3 4 5 6 7 8
## 0.4625 -0.6375 -0.3125 0.4875 0.7875 -0.6125 -0.4875 0.3125
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 10.3125 0.2391 43.13 1.26e-07 ***
## X1 3.8625 0.2391 16.16 1.66e-05 ***
## X2 3.4375 0.2391 14.38 2.93e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.6762 on 5 degrees of freedom
## Multiple R-squared: 0.9894, Adjusted R-squared: 0.9852
## F-statistic: 233.9 on 2 and 5 DF, p-value: 1.15e-05
Följande uttryck beskriver sambanden mellan mätresultat och försöksvariabler. De estimerade β-koefficienterna (10.31, 3.86, 3.44) är inskrivna i modellen. Det framgår att en ökning av X1 och X2 ger en ökning av utfallet (Y). (Kanske detta kan användas till ett nytt försök där försöksområdet då flyttas):
\[ \begin{align} \large Y = b_{0} + b_{1}X_{1} + b_{2}X_{2} = 10.31 + 3.86X_{1} + 3.44X_{2} \phantom{invisible}\text{(Koeff. enl utskrift)} \end{align} \]
Genom att sätta in X2 = -1 och X2 = +1 i uttrycket erhålles två räta linjer som ritas in i ett diagram:
\[ \begin{align} \large Y = 10.31 + 3.86X_{1} + 3.44\cdot (-1) = 6.87 + 3.86X_{1} \phantom{invisible}\text{(X2 = -1)} \\ \\ \large Y = 10.31 + 3.86X_{1} + 3.44\cdot (+1) = 13.75 + 3.86X_{1} \phantom{invisible}\text{(X2 = +1)} \end{align} \]Följande kommandon plockar fram koefficienterna och beräknar och ritar två linjer i diagrammet:
Koeff <- summary(analys2)$coefficients # Alla skattade koefficienter, läggs i en lista.
b0 <- Koeff[1, 1] # (Intercept) # Plockar ut enskilda koefficienter.
b1 <- Koeff[2, 1] # X
b2 <- Koeff[3, 1]
Doe2Dia <- ggplot(diaData, aes(x = X1, y =Ydata)) + geom_point(color = "red", size = 3) +
xlab("Variabel X1") + ylab("Mätresultat") + scale_x_continuous(breaks=c(-1, 1), limits=c(-1.2, 1.2),
labels=c("-1", "+1")) + theme(axis.text = element_text(color = "black", size = 18))
Doe2Dia <- Doe2Dia + theme(axis.title.x = element_text(size = 15, color = "blue", face = "bold"),
axis.title.y = element_text(size = 15, color = "blue", face = "bold"))
Doe2Dia <- Doe2Dia + geom_abline(intercept = b0 + b2*(-1), slope = b1, linetype = 1, colour = "black") +
geom_abline(intercept = b0 + b2*(+1), slope = b1, linetype = 1, colour = "black")
Doe2Dia
Tolkning av diagrammet. En linje visar hur mätresultatet förändras då man går från lägsta till högsta nivån på X1 (från -1 till +1). Den undre linjen gäller då X2 = -1 och den övre då X2 = 1. Om man vill ha ett högt utfall skall man alltså ställa in högsta värdet på både X1 och X2. Med modellen erhålles då följande:
\[ \begin{align} \large Y = 10.31 + 3.86 \cdot (+1) + 3.44 \cdot (+1) = 17.61 \end{align} \]Värdet 17.61 är dock ett s.k. väntevärde men det bör också åtföljas av ett konfidensintervall för denna skattning. Ett dylikt intervall kan beräknas av datorprogrammet (redovisas inte här). Notera att diagrammets X-axel visar variabel X1. Naturligtvis kan variabel X2 utgöra X-axeln och då erhålles återigen två räta linjer, för X1 = -1 respektive X1 = +1. Det är ibland enklare att tolka ett 3D-diagram på detta sätt.
2. En DoE med två förklaringsvariabler, med samspel
Detta exempel är i allt väsentligt samma som ovan med undantag för att data har simulerats med en samspelsterm. Sliden för smaspelstermen är inte längre 0 utan satt till 2.1:
En tabell över data med samspel:
Ydata <- c(9.9, 9.7, 18.6, 18.4, 6.4, 7.0, 6.6, 5.9)
X1 <- c(+1, +1, +1, +1, -1, -1, -1, -1)
X2 <- c(-1, -1, +1, +1, -1, -1, +1, +1)
doe2Data <- data.frame(Ydata, X1, X2)
data <- kable(head(doe2Data), "html")
kable_styling(data, "striped", position = "left", font_size = 17, full_width = FALSE) %>%
column_spec(1, width = "4cm") %>%
column_spec(2, width = "3cm") %>%
column_spec(3, width = "3cm")
| Ydata | X1 | X2 |
|---|---|---|
| 9.9 | 1 | -1 |
| 9.7 | 1 | -1 |
| 18.6 | 1 | 1 |
| 18.4 | 1 | 1 |
| 6.4 | -1 | -1 |
| 7.0 | -1 | -1 |
Nedanstående R-kommandon skapar samma diagram som i skärmdumpen för exempel 2:
diaData <- data.frame(Ydata, X1)
Doe2Dia <- ggplot(diaData, aes(x = X1, y =Ydata)) + geom_point(color = "red", size = 3) +
xlab("Variabel X1") + ylab("Mätresultat") + scale_x_continuous(breaks=c(-1, 1), limits=c(-1.2, 1.2),
labels=c("-1", "+1")) + theme(axis.text = element_text(color = "black", size = 18))
Doe2Dia + theme(axis.title.x = element_text(size = 15, color = "blue", face = "bold"),
axis.title.y = element_text(size = 15, color = "blue", face = "bold"))
Diagram över samspel, exempel 2. Här finns det ett tydligt samspel mellan X1 och X2 eftersom kurvorna inte är parallella. Förändringen i utfallet då X1 ändras från låg till hög nivå är olika och beror på inställningen av X2. Alltså är det ett samspel mellan X1 och X2:
interaction.plot(X1, X2, Ydata, fun = mean,
xlab = "Variabel X1",
ylab = "Medelvärde mätvärden",
main = "Samspelsdiagram mellan X1 och X2")
Analysen sker igen med ‘lm’-kommandot (‘linjär modell’). Här kommer även samspelstermen (X1:X2) att vara signifikant dvs att den behövs i modellen för att förklara sambanden:
analys3 <- lm(formula = Ydata ~ X1 + X2 + X1*X2 )
summary(analys3)
##
## Call:
## lm(formula = Ydata ~ X1 + X2 + X1 * X2)
##
## Residuals:
## 1 2 3 4 5 6 7 8
## 0.10 -0.10 0.10 -0.10 -0.30 0.30 0.35 -0.35
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 10.3125 0.1205 85.55 1.12e-07 ***
## X1 3.8375 0.1205 31.83 5.80e-06 ***
## X2 2.0625 0.1205 17.11 6.84e-05 ***
## X1:X2 2.2875 0.1205 18.98 4.54e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.341 on 4 degrees of freedom
## Multiple R-squared: 0.9976, Adjusted R-squared: 0.9958
## F-statistic: 555.4 on 3 and 4 DF, p-value: 1.074e-05
Följande uttryck beskriver sambanden mellan mätresultat och försöksvariabler. De estimerade koefficienterna är inskrivna i modellen:
\[ \begin{align} \large Y = b_{0} + b_{1}X_{1} + b_{2}X_{2} + b_{3}X_{1}X_{2} = 10.31 + 3.84X_{1} + 2.06X_{2} + 2.29X_{1}X_{2} \end{align} \]När X2-värdena skrivs in i modellen erhålles återigen två räta linjer men denna gång har de olika lutning:
\[ \begin{align*} \large Y = 10.31 + 3.84X_{1} + 2.06\cdot (-1) + 2.29 X_{1} \cdot (-1)=8.25 + 1.55 X_{1} \\ \\ \large Y = 10.31 + 3.84X_{1} + 2.06\cdot (+1) + 2.29 X_{1} \cdot (+1)=12.37 + 6.13 X_{1} \end{align*} \]
Följande kommandon plockar fram koefficienterna och beräknar och ritar två linjer i diagrammet:
Koeff <- summary(analys3)$coefficients # All estimated coefficients.
b0 <- Koeff[1, 1] # (Intercept) # Extracts coefficients.
b1 <- Koeff[2, 1] # X
b2 <- Koeff[3, 1]
b3 <- Koeff[3, 1]
Doe2Dia <- ggplot(diaData, aes(x = X1, y =Ydata)) + geom_point(color = "red", size = 3) +
xlab("Variabel X1") + ylab("Mätresultat") + scale_x_continuous(breaks=c(-1, 1), limits=c(-1.2, 1.2),
labels=c("-1", "+1")) + theme(axis.text = element_text(color = "black", size = 18))
Doe2Dia <- Doe2Dia + theme(axis.title.x = element_text(size = 15, color = "blue", face = "bold"),
axis.title.y = element_text(size = 15, color = "blue", face = "bold"))
Doe2Dia + geom_abline(intercept = b0 + b2*(-1), slope = b1 + b3*(-1), linetype = 1, colour = "black") +
geom_abline(intercept = b0 + b2*(+1), slope = b1 + b3*(+1), linetype = 1, colour = "black")
Tolkning av diagrammet med samspel. Vid frågan ‘Hur förändras
utfallet från X1 = -1 till X1 = +1?’ Här måste ett svar bli ‘Det beror
på inställningen av variabel X2, om X = +1 har kurvan en brantare
lutning’. Det är kanske lätt att se situationer då samspel uppstår och
faktum är att väldigt många undersökningar innehåller mer eller mindre
tydliga samspel mellan förklaringavariabler.
Det dock inte alltid
lätt att inse hur diagrammen visar samspel och hur man skall tolka eller
förklara.
Avslutningsvis
Ovanstående text avser inte att ge en
uttömmande diskussion om problemen som diskuteras i de ursprungliga
graferna. Snarare är avsikten att visa att det går att resonera och
ifrågasätta t.ex. grafer eller påståenden med hjälp av lite statistisk
teori.
(Analyserna har gjorts med datorprogrammet ‘R’ och med det grafiska gränssnittet ‘R-studio’ och bägge är gratis tillgängliga på nätet. Se https://www.indstat.se och knappen [Statistikprogram - R] för installation.)
(Se https://www.indstat.se för många andra simuleringsövningar.)