Skip to content

Fractional Factorial Designs

Fractional factorial designs run only a carefully selected subset of the full factorial design, reducing experimental cost while still providing valuable information about main effects and important interactions.

When to Use Fractional Factorial Designs

  • Many factors to screen: 5 or more factors where full factorial is too expensive
  • Limited resources: When experimental runs are costly or time-consuming
  • Screening studies: To identify the most important factors before detailed study
  • Sequential experimentation: As a first step before running a full factorial on important factors

Key Concepts

Aliasing (Confounding)

In fractional factorial designs, some effects are aliased (confounded) with others. This means you cannot distinguish between aliased effects from the experimental data alone.

Resolution

Resolution describes the quality of a fractional factorial design:

  • Resolution III: Main effects are not aliased with each other (but may be aliased with 2-factor interactions)
  • Resolution IV: Main effects are not aliased with each other or 2-factor interactions
  • Resolution V: Main effects and 2-factor interactions are not aliased with each other

Generators

Generators define how the fractional design is constructed. For example, in a 2^(4-1) design with generator D=ABC, factor D is set equal to the product of factors A, B, and C.

Basic Usage

Simple Fractional Factorial

import daspi as dsp

# 2^(3-1) design: 4 runs instead of 8
A = dsp.Factor('A', (-1, 1))
B = dsp.Factor('B', (-1, 1))
C = dsp.Factor('C', (-1, 1))

builder = dsp.FractionalFactorialDesignBuilder(
    A, B, C,
    generators=['C=AB']  # C is determined by A×B
)

design = builder.build_design(corrected=False)
print(design)

Using Default Generators

For common designs, you can use standard generators:

# Get standard generators for 2^(5-2) design
generators = dsp.get_default_generators(k=5, p=2)
print(generators)  # ['D=AB', 'E=AC']

# Create the design
A = dsp.Factor('A', (-1, 1))
B = dsp.Factor('B', (-1, 1))
C = dsp.Factor('C', (-1, 1))
D = dsp.Factor('D', (-1, 1))
E = dsp.Factor('E', (-1, 1))

builder = dsp.FractionalFactorialDesignBuilder(
    A, B, C, D, E,
    generators=generators
)

design = builder.build_design(corrected=False)

Foldover Designs

Foldover adds a second fraction where the signs of one or more factors are reversed, helping to resolve aliasing between main effects and 2-factor interactions.

Complete Foldover

# Foldover all factors
builder = dsp.FractionalFactorialDesignBuilder(
    A, B, C,
    generators=['C=AB'],
    fold=True  # Reverses all factors
)

design = builder.build_design(corrected=False)
# This creates 8 runs total (4 original + 4 foldover)

Partial Foldover

# Foldover only factor A
builder = dsp.FractionalFactorialDesignBuilder(
    A, B, C,
    generators=['C=AB'],
    fold='A'  # Reverses only factor A
)

design = builder.build_design(corrected=False)

Common Fractional Factorial Designs

Design Basic Factors Generated Factors Generators Resolution
2^(3-1) A, B C C=AB III
2^(4-1) A, B, C D D=ABC IV
2^(5-2) A, B, C D, E D=AB, E=AC III
2^(6-3) A, B, C D, E, F D=AB, E=AC, F=BC III
2^(7-3) A, B, C, D E, F, G E=ABC, F=ABD, G=BCD IV

Design Strategy

  1. Start small: Use a fractional factorial to screen many factors
  2. Analyze results: Identify the most important factors
  3. Follow up: Run a full factorial or higher-resolution fractional factorial on important factors
  4. Use foldover: If main effects are confounded with 2-factor interactions

Advanced Features

With Blocking and Replication

builder = dsp.FractionalFactorialDesignBuilder(
    A, B, C, D, E,
    generators=['D=AB', 'E=AC'],
    replicates=2,
    central_points=3,
    blocks=2,  # Split into 2 blocks
    fold=True,
    shuffle=True
)

design = builder.build_design(corrected=False)

API Reference

daspi.doe.FractionalFactorialDesignBuilder(*factors, generators, fold=False, replicates=1, central_points=0, blocks=1, shuffle=True)

Bases: BaseDesignBuilder

Builder for 2-level fractional factorial designs with optional foldover.

This class supports the construction of regular 2-level fractional factorial designs using generator strings (e.g., 'C=AB'), and can optionally add a foldover to the design.

Default generators for common designs (see also get_default_generators):

Design Basic Factors Generators Example Generator Strings
2^(3-1) A, B C = AB ['C=AB']
2^(4-1) A, B, C D = ABC ['D=ABC']
2^(5-2) A, B, C D = AB, E = AC ['D=AB', 'E=AC']
2^(6-3) A, B, C D = AB, E = AC, F = BC ['D=AB', 'E=AC', 'F=BC']
2^(7-3) A, B, C, D E = ABC, F = ABD, G = BCD ['E=ABC', 'F=ABD', 'G=BCD']
PARAMETER DESCRIPTION
factors

Factors defining the design space. All factors must have exactly 2 levels.

TYPE: Iterable[Factor] DEFAULT: ()

generators

List of generator strings that define how dependent factors are constructed from basic factors. For example, if you have 4 factors A, B, C, and D, you can set generators to ['C=AB', 'D=BC']. This means that factor C is defined as the product of factors A and B (C = A * B), and factor D as the product of B and C (D = B * C). The order of the generator strings should match the order of the dependent factors in the factors list. For common designs, see the table above or use get_default_generators(k, p).

TYPE: List[str]

fold

Whether to add a foldover. If True, a foldover will be added for all factors. If a string is provided, it should be the name of the factor to fold over. Default is False (no foldover).

TYPE: bool | str DEFAULT: False

replicates

Number of replicates. Must be positive, by default 1.

TYPE: int DEFAULT: 1

central_points

Number of central points to be added to each block. These are used to test linear effects. Must be non-negative. If set to 0, no central points are added. by default 0.

TYPE: int DEFAULT: 0

blocks

Number of blocks. Must be positive, by default 1.

TYPE: int DEFAULT: 1

shuffle

Whether to shuffle the design, by default True.

TYPE: bool DEFAULT: True

Examples:

Create a 2^(3-1) fractional factorial design (3 factors, 1 generator):

from daspi.doe.build import Factor, FractionalFactorialDesignBuilder

A = Factor('A', (-1, 1))
B = Factor('B', (-1, 1))
C = Factor('C', (-1, 1))
builder = FractionalFactorialDesignBuilder(A, B, C, generators=['C=AB'])
df = builder.build_design(corrected=False)
print(df)
   std_order  run_order  central_point  replica  block  A  B  C
0          0          0              1        1      1 -1 -1  1
1          1          1              1        1      1 -1  1 -1
2          2          2              1        1      1  1 -1 -1
3          3          3              1        1      1  1  1  1

Create the same design with foldover (doubles the number of runs, reverses A):

builder = FractionalFactorialDesignBuilder(
    A, B, C, generators=['C=AB'], fold=True)
df = builder.build_design(corrected=False)
print(df)
   std_order  run_order  central_point  replica  block  A  B  C
0          0          0              1        1      1 -1 -1  1
1          1          1              1        1      1 -1  1 -1
2          2          2              1        1      1  1 -1 -1
3          3          3              1        1      1  1  1  1
4          4          4              1        1      1  1 -1 -1
5          5          5              1        1      1  1  1  1
6          6          6              1        1      1 -1 -1  1
7          7          7              1        1      1 -1  1 -1
RAISES DESCRIPTION
AssertionError

If any of the parameters are invalid: - All factors must have exactly 2 levels. - Number of replicates must be positive. - Number of central points must be non-negative. - Number of blocks must be positive. - Generators must be provided as a list of strings. - Generators must match the number of dependent factors. - Each generator string must be in the format 'C=AB' where C is the dependent factor and AB are the independent factors. - Each dependent factor must be defined in the generators. - The first basic factor must be reversed in sign for foldover.

Notes

In fractional factorial designs, only a subset of all possible factor combinations is run, which leads to confounding (aliasing) between main effects and interactions. Foldover is a technique to resolve some of these confoundings by running an additional set of experiments where the sign of one or more basic factors is reversed. This effectively doubles the number of runs and allows for the separation of certain effects that were aliased in the original fraction. Foldover is especially useful for identifying main effects that may be confounded with two-factor interactions in the initial design. Key points: - Foldover is meaningful only for regular 2-level fractional factorial designs, not for full factorials, non-regular designs, or designs with more than two levels per factor. - For full factorial designs, foldover is unnecessary because there is no aliasing to resolve. - For non-regular or mixed-level designs, the concept of foldover does not apply in the classical sense.

generators = generators instance-attribute

List of generator strings defining dependent factors.

by_resolution(*factors, resolution, fold=False, replicates=1, central_points=0, blocks=1, shuffle=True) classmethod

Create a FractionalFactorialDesignBuilder with generators chosen to achieve the specified resolution.

Resolution is a measure of design quality that indicates the degree of confounding between effects: - Resolution III: Main effects are not confounded with each other, but may be confounded with 2-factor interactions. - Resolution IV: Main effects are not confounded with 2-factor interactions, but 2-factor interactions may be confounded with each other. - Resolution V: Main effects and 2-factor interactions are not confounded with each other, but may be confounded with 3-factor interactions.

This method automatically selects standard generators that achieve the highest possible resolution for the given number of factors, or uses a fractional design if a full factorial would exceed the desired resolution constraints.

PARAMETER DESCRIPTION
factors

Factors defining the design space. All factors must have exactly 2 levels.

TYPE: Iterable[Factor] DEFAULT: ()

resolution

Desired design resolution (III, IV, or V). Must be between 3 and 5.

TYPE: int

fold

Whether to add a foldover. If True, a foldover will be added for all factors. If a string is provided, it should be the name of the factor to fold over. Default is False (no foldover).

TYPE: bool | str DEFAULT: False

replicates

Number of replicates. Must be positive, by default 1.

TYPE: int DEFAULT: 1

central_points

Number of central points to be added to each block. These are used to test linear effects. Must be non-negative. If set to 0, no central points are added. by default 0.

TYPE: int DEFAULT: 0

blocks

Number of blocks. Must be positive, by default 1.

TYPE: int DEFAULT: 1

shuffle

Whether to shuffle the design, by default True.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION
FractionalFactorialDesignBuilder

An instance configured with appropriate generators for the specified resolution.

Examples:

Create a Resolution IV design with 5 factors:

import daspi as dsp

factors = [dsp.Factor(f'F{i}', (-1, 1)) for i in range(1, 6)]
builder = dsp.FractionalFactorialDesignBuilder.by_resolution(
    *factors, resolution=4)
df = builder.build_design(corrected=True)
print(f"Design: 2^({len(factors)}-{len(builder.generators)})")
print(f"Runs: {len(df)}")

Create a Resolution V design with 7 factors:

import daspi as dsp

factors = [dsp.Factor(f'F{i}', (-1, 1)) for i in range(1, 8)]
builder = dsp.FractionalFactorialDesignBuilder.by_resolution(
    *factors, resolution=5)
df = builder.build_design(corrected=True)
print(f"Design: 2^({len(factors)}-{len(builder.generators)})")
print(f"Runs: {len(df)}")

Raises ----__ AssertionError If any of the parameters are invalid: - All factors must have exactly 2 levels. - Resolution must be between 3 and 5. - Not enough factors for the specified resolution. ValueError If no standard generators are available for the required k and p combination.

Notes

This method uses standard generator sets optimized for the specified resolution. The generators are selected to achieve the highest resolution possible while minimizing the number of experimental runs.

Resolution selection guidelines: - Resolution III: Suitable for screening many factors when interactions are less important. - Resolution IV: Good balance between run count and ability to estimate main effects clearly. - Resolution V: Allows estimation of main effects and 2-factor interactions without confounding.

For the mathematical definition of resolution and aliasing patterns, see Montgomery (2017) "Design and Analysis of Experiments".

daspi.doe.get_default_generators(k, p)

Return standard generators for regular 2-level fractional factorial designs.

PARAMETER DESCRIPTION
k

Total number of factors.

TYPE: int

p

Number of generators (fractionality, so design is 2^(k-p)).

TYPE: int

RETURNS DESCRIPTION
List[str]

List of generator strings, e.g. ['C=AB', 'D=AC'].

Notes

These are standard choices for high-resolution designs, suitable for most practical cases. For more, see Montgomery (2017), Box, Hunter & Hunter, or standard DOE tables.