Skill Tracer
Skills › Scientific Agent Skills › experimental-design › factorial_and_doe.md

factorial_and_doe.md

156 lines · skills/experimental-design/references/factorial_and_doe.md at 5f2bc03

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1# Factorial and Design-of-Experiments (DOE)
2
3When several factors might affect a response, testing them **one factor at a time
4(OFAT)** is both wasteful and blind to interactions. Factorial designs vary factors
5*together*, so the appropriate full design separates main effects and interactions;
6reduced designs trade some of that information for fewer runs. This file covers the family of DOE designs and the
7concepts (resolution, aliasing) needed to read them. Generate them with
8`scripts/doe_designs.py`.
9

Factorial and Design-of-Experiments (DOE)

When several factors might affect a response, testing them one factor at a time (OFAT) is both wasteful and blind to interactions. Factorial designs vary factors together, so the appropriate full design separates main effects and interactions; reduced designs trade some of that information for fewer runs. This file covers the family of DOE designs and the concepts (resolution, aliasing) needed to read them. Generate them with scripts/doe_designs.py.

Raw lines 1 to 9
Runs code scripts/doe_designs.py :8
10## Table of contents
11- [Why factorial beats OFAT](#why-factorial-beats-ofat)
12- [Full factorial (2^k)](#full-factorial)
13- [Fractional factorial (2^(k-p))](#fractional-factorial)
14- [Resolution and aliasing](#resolution-and-aliasing)
15- [Screening designs (Plackett-Burman)](#screening-designs)
16- [Response-surface designs](#response-surface-designs)
17- [Space-filling designs](#space-filling-designs)
18- [Choosing a design](#choosing-a-design)

Table of contents

  • Why factorial beats OFAT
  • Full factorial (2^k)
  • Fractional factorial (2^(k-p))
  • Resolution and aliasing
  • Screening designs (Plackett-Burman)
  • Response-surface designs
  • Space-filling designs
  • Choosing a design
Raw lines 10 to 19
20## Why factorial beats OFAT
22Vary one factor while holding others fixed and you (1) spend runs inefficiently and
23(2) can never see **interactions** — cases where the effect of A depends on the level
24of B, which are the rule, not the exception, in real systems. A factorial varies all
25factors simultaneously across runs; each effect is estimated using *all* the data, so
26a 2^k factorial is more precise than k separate OFAT studies of the same size.

Why factorial beats OFAT

Vary one factor while holding others fixed and you (1) spend runs inefficiently and (2) can never see interactions — cases where the effect of A depends on the level of B, which are the rule, not the exception, in real systems. A factorial varies all factors simultaneously across runs; each effect is estimated using all the data, so a 2^k factorial is more precise than k separate OFAT studies of the same size.

Raw lines 20 to 27
28## Full factorial
30A **2^k** design runs every combination of k factors at two levels (low/high, coded
31−1/+1). It estimates all k main effects and all 2^k − k − 1 interactions. With one observation per combination, the
32model containing every effect plus an intercept is saturated: it has zero residual
33degrees of freedom. Replicate independently or pre-specify a defensible reduced
34model before claiming standard errors or significance.
36- Runs = 2^k: 8 for 3 factors, 16 for 4, 32 for 5. Practical to ~5 factors.
37- Use when you have a handful of factors and want a full picture including
38 interactions.
39- `two_level_factorial({"temp": (20,60), "conc": (1,10), "pH": (6,8)})` → 8 runs.
40- For factors with more than two levels, use `full_factorial` with explicit level
41 lists (runs = product of level counts — grows fast).
43Add **center points** (all factors at their midpoint) to a two-level design to get a
44cheap check for curvature: if the center response departs from the factorial average,
45a linear model is inadequate and you need a response-surface design.

Full factorial

A 2^k design runs every combination of k factors at two levels (low/high, coded −1/+1). It estimates all k main effects and all 2^k − k − 1 interactions. With one observation per combination, the model containing every effect plus an intercept is saturated: it has zero residual degrees of freedom. Replicate independently or pre-specify a defensible reduced model before claiming standard errors or significance.

  • Runs = 2^k: 8 for 3 factors, 16 for 4, 32 for 5. Practical to ~5 factors.
  • Use when you have a handful of factors and want a full picture including interactions.
  • two_level_factorial({"temp": (20,60), "conc": (1,10), "pH": (6,8)}) → 8 runs.
  • For factors with more than two levels, use full_factorial with explicit level lists (runs = product of level counts — grows fast).

Add center points (all factors at their midpoint) to a two-level design to get a cheap check for curvature: if the center response departs from the factorial average, a linear model is inadequate and you need a response-surface design.

Raw lines 28 to 46
47## Fractional factorial
49When k is large, 2^k is too many runs — but most high-order interactions are
50negligible (the *sparsity-of-effects* principle). A **2^(k−p)** fractional factorial
51runs a carefully chosen fraction (1/2, 1/4, ...) of the full design, trading the
52ability to estimate some interactions for far fewer runs.
54- `fractional_factorial(factors, generator="a b c abc")` builds a half-fraction of 4
55 factors in 8 runs. The generator string (Yates notation) assigns each factor to a
56 column; a multi-letter token aliases that factor with an interaction.
57- The price is **aliasing**: some effects become indistinguishable. You must know
58 which.

Fractional factorial

When k is large, 2^k is too many runs — but most high-order interactions are negligible (the sparsity-of-effects principle). A 2^(k−p) fractional factorial runs a carefully chosen fraction (1/2, 1/4, ...) of the full design, trading the ability to estimate some interactions for far fewer runs.

  • fractional_factorial(factors, generator="a b c abc") builds a half-fraction of 4 factors in 8 runs. The generator string (Yates notation) assigns each factor to a column; a multi-letter token aliases that factor with an interaction.
  • The price is aliasing: some effects become indistinguishable. You must know which.
Raw lines 47 to 59
60## Resolution and aliasing
62**Aliasing** (confounding) means two effects are estimated by the same contrast — the
63data cannot separate them. Which effects are aliased is summarized by the design's
64**resolution**:
66| Resolution | Aliasing | Interpretation |
67|------------|----------|----------------|
68| **III** | main effects aliased with 2-factor interactions | Screening only; a "significant" main effect might be an interaction |
69| **IV** | main effects clear of 2FI, but 2FIs aliased with each other | Main effects require negligible aliased 3FI+ |
70| **V** | main effects and 2FIs all clear of each other (aliased with 3FI+) | Main/2FI separation assumes negligible aliased higher effects |
72Always state the resolution and inspect the alias structure before interpreting a
73fractional design. Concluding "factor C has no effect" is unsafe if C is aliased with
74a real interaction (it could cancel out). When in doubt, choose a higher-resolution
75generator (more runs) or add runs to **de-alias** (fold-over / augment the design).

Resolution and aliasing

Aliasing (confounding) means two effects are estimated by the same contrast — the data cannot separate them. Which effects are aliased is summarized by the design's resolution:

ResolutionAliasingInterpretation
IIImain effects aliased with 2-factor interactionsScreening only; a "significant" main effect might be an interaction
IVmain effects clear of 2FI, but 2FIs aliased with each otherMain effects require negligible aliased 3FI+
Vmain effects and 2FIs all clear of each other (aliased with 3FI+)Main/2FI separation assumes negligible aliased higher effects

Always state the resolution and inspect the alias structure before interpreting a fractional design. Concluding "factor C has no effect" is unsafe if C is aliased with a real interaction (it could cancel out). When in doubt, choose a higher-resolution generator (more runs) or add runs to de-alias (fold-over / augment the design).

Raw lines 60 to 76
77## Screening designs
79When the goal is to **find the vital few** factors out of many (5, 10, 20+), use a
80screening design that estimates main effects only, as cheaply as possible:
81- **Plackett-Burman** (`plackett_burman`): runs = the next multiple of 4 above k
82 (e.g. 12 runs for up to 11 factors). Resolution III — two-factor interactions are
83 often confounded with main effects. Use for triage: run it, keep the few
84 factors with large effects, then study those with a full or higher-resolution
85 factorial.
86- Resolution III fractional factorials serve the same purpose.
88The current `pydoe==1.5.0` implementation supports run counts in the families
89`2^a`, `12*2^a`, and `20*2^a`. It can reject a requested factor count whose next
90multiple of four is unsupported (25 factors require 28 runs and raise
91`ValueError`). Inspect the actual matrix before budgeting; choose a supported
92design or a suitable fractional factorial. Reduced subsets may have better
93aliasing properties than the full saturated design, so inspect actual aliases.
94See the [current factorial API](https://pydoe.github.io/pydoe/reference/factorial/).
96Screen first, optimize later — don't try to learn interactions and find the optimum
97in one cheap design.

Screening designs

When the goal is to find the vital few factors out of many (5, 10, 20+), use a screening design that estimates main effects only, as cheaply as possible:

  • Plackett-Burman (plackett_burman): runs = the next multiple of 4 above k (e.g. 12 runs for up to 11 factors). Resolution III — two-factor interactions are often confounded with main effects. Use for triage: run it, keep the few factors with large effects, then study those with a full or higher-resolution factorial.
  • Resolution III fractional factorials serve the same purpose.

The current pydoe==1.5.0 implementation supports run counts in the families 2^a, 12*2^a, and 20*2^a. It can reject a requested factor count whose next multiple of four is unsupported (25 factors require 28 runs and raise ValueError). Inspect the actual matrix before budgeting; choose a supported design or a suitable fractional factorial. Reduced subsets may have better aliasing properties than the full saturated design, so inspect actual aliases. See the current factorial API.

Screen first, optimize later — don't try to learn interactions and find the optimum in one cheap design.

Raw lines 77 to 98
99## Response-surface designs
101Two-level designs fit only a flat (linear + interaction) model; they cannot locate an
102interior optimum or describe **curvature**. To fit a quadratic and optimize, use a
103response-surface methodology (RSM) design over continuous factors:
105- **Central composite design (CCD)** (`central_composite`): a 2^k factorial + center
106 points + axial ("star") points. The axial points add the levels needed to estimate
107 quadratic terms. With `face="circumscribed"` (default) the axial points sit
108 *outside* the factorial box (so actual factor levels exceed your stated low/high);
109 use `face="inscribed"` or `"faced"` to keep everything within the original range.
110- **Box-Behnken** (`box_behnken`, needs ≥3 factors): a quadratic design that avoids
111 the extreme all-low/all-high corners — useful when those corners are unsafe,
112 expensive, or infeasible. Compare actual run counts and the same center-point
113 replication: Box-Behnken is not always smaller (for five factors, its 40
114 non-center runs exceed a half-fraction CCD with 26). The bundled CCD wrapper
115 uses the full factorial and does not build that half-fraction.
116 See [NIST response-surface comparisons](https://www.itl.nist.gov/div898/handbook/pri/section3/pri3363.htm).
118The wrappers default to a single center run (`center=(0, 1)` for CCD;
119`center=1` for Box-Behnken). That supplies no pure-error replication. Pre-plan
120independent replicate runs, inspect quadratic-model rank, and budget lack-of-fit
121assessment. CCD `center` counts refer to factorial and axial construction blocks;
122the wrapper returns a globally shuffled table without block IDs. Preserve or
123construct those IDs before using a physically blocked experiment.
125Workflow: screen → factorial (find important factors & rough region) → response
126surface (model curvature, locate optimum), often moving the experimental region
127between steps (path of steepest ascent).

Response-surface designs

Two-level designs fit only a flat (linear + interaction) model; they cannot locate an interior optimum or describe curvature. To fit a quadratic and optimize, use a response-surface methodology (RSM) design over continuous factors:

  • Central composite design (CCD) (central_composite): a 2^k factorial + center points + axial ("star") points. The axial points add the levels needed to estimate quadratic terms. With face="circumscribed" (default) the axial points sit outside the factorial box (so actual factor levels exceed your stated low/high); use face="inscribed" or "faced" to keep everything within the original range.
  • Box-Behnken (box_behnken, needs ≥3 factors): a quadratic design that avoids the extreme all-low/all-high corners — useful when those corners are unsafe, expensive, or infeasible. Compare actual run counts and the same center-point replication: Box-Behnken is not always smaller (for five factors, its 40 non-center runs exceed a half-fraction CCD with 26). The bundled CCD wrapper uses the full factorial and does not build that half-fraction. See NIST response-surface comparisons.

The wrappers default to a single center run (center=(0, 1) for CCD; center=1 for Box-Behnken). That supplies no pure-error replication. Pre-plan independent replicate runs, inspect quadratic-model rank, and budget lack-of-fit assessment. CCD center counts refer to factorial and axial construction blocks; the wrapper returns a globally shuffled table without block IDs. Preserve or construct those IDs before using a physically blocked experiment.

Workflow: screen → factorial (find important factors & rough region) → response surface (model curvature, locate optimum), often moving the experimental region between steps (path of steepest ascent).

Raw lines 99 to 128
129## Space-filling designs
131For **computer experiments / simulations** (deterministic or expensive models) where
132space coverage may be the main objective, you want even coverage of a
133high-dimensional input space:
134- **Latin hypercube** (`latin_hypercube`): each factor's range is divided into
135 n_samples equal bins, sampled once each, arranged to spread points apart
136 (`criterion="maximin"`). Gives good coverage with relatively few points and is the
137 common input design for surrogate/emulator modeling. A generic LHS alone is not
138 a Saltelli/Sobol sensitivity estimator design. Stochastic simulations may still
139 need replicated random seeds; experimental batches may still need blocking.

Space-filling designs

For computer experiments / simulations (deterministic or expensive models) where space coverage may be the main objective, you want even coverage of a high-dimensional input space:

  • Latin hypercube (latin_hypercube): each factor's range is divided into n_samples equal bins, sampled once each, arranged to spread points apart (criterion="maximin"). Gives good coverage with relatively few points and is the common input design for surrogate/emulator modeling. A generic LHS alone is not a Saltelli/Sobol sensitivity estimator design. Stochastic simulations may still need replicated random seeds; experimental batches may still need blocking.
Raw lines 129 to 140
141## Choosing a design
143| Goal | Factors | Design | Script function |
144|------|---------|--------|-----------------|
145| Screen many factors | 5–20+ | Plackett-Burman / Res III | `plackett_burman` |
146| Main effects, some interactions, few runs | 4–8 | Res IV/V fractional | `fractional_factorial` |
147| All effects + interactions | 2–5 | Full 2^k factorial | `two_level_factorial` |
148| Multi-level categorical | few | Full factorial | `full_factorial` |
149| Optimize a response (curvature) | 2–5 | Central composite / Box-Behnken | `central_composite`, `box_behnken` |
150| Cover a simulation input space | any | Latin hypercube | `latin_hypercube` |
152For physical experiments, **randomize run order within the allowed blocks** to
153avoid systematic alignment with drift. DOE wrappers default to a global shuffle;
154Latin hypercube defaults to `randomize=False` and already has stochastic sample
155placement. Add replicated center points to two-level continuous designs for an
156aggregate curvature check; they cannot separate all pure quadratic coefficients.

Choosing a design

GoalFactorsDesignScript function
Screen many factors5–20+Plackett-Burman / Res IIIplackett_burman
Main effects, some interactions, few runs4–8Res IV/V fractionalfractional_factorial
All effects + interactions2–5Full 2^k factorialtwo_level_factorial
Multi-level categoricalfewFull factorialfull_factorial
Optimize a response (curvature)2–5Central composite / Box-Behnkencentral_composite, box_behnken
Cover a simulation input spaceanyLatin hypercubelatin_hypercube

For physical experiments, randomize run order within the allowed blocks to avoid systematic alignment with drift. DOE wrappers default to a global shuffle; Latin hypercube defaults to randomize=False and already has stochastic sample placement. Add replicated center points to two-level continuous designs for an aggregate curvature check; they cannot separate all pure quadratic coefficients.

Raw lines 141 to 156