跳到正文
格致开物MATHWIKI

正交表

内容维护:格致开物 · 编写与核验 · 修订记录 · 纠错

正交表(orthogonal array)是一种按指定强度精确均衡因素组合的表格。把每次试验排成一行、每个因素排成一列,在任意指定数量的列中,各种水平组合都出现同样多次。这种均衡可用于试验设计,也能用来构造具有低阶独立性的有限随机样本。

例如,下表每列取零、一两个水平: A=(000011101110). 任选两列,00,01,10,11 都恰出现一次。但三列只出现四种组合,而非全部八种;两两均衡与三因素均衡是不同要求。

参数与强度

本文用 OA⁡(N,k,s,t) 表示一个 N×k 表,元素取自 s 个水平,满足 1≤t≤k、s≥2。对任意 t 列,全部 st 种有序水平组合都恰出现 λ 次。其中 N=λst 且 λ 为正整数,称为指数。各文献参数顺序、行列约定有所不同,比较设计时应先核对“试验是一行还是一列”。[1]

上面的表是 OA⁡(4,3,2,2),指数一。固定前两列,它们已经列出全部二位组合;对第一、三列及第二、三列逐一计数也得到同样结果。第三列实际是前两列的异或,这给出一个可直接复核的构造。

四行三因素正交表及其三个二列投影,每个投影都有零零零一一零一一各一次
强度二要求三个二列投影都均衡,不能只检查最左边两列。

低阶边缘仍然均衡

若表的强度为 t,则任取 r≤t 列及一种固定的 r 元组合,也会出现 λst−r=Nsr 次。证明。 将这 r 列扩充成某 t 列。其余 t−r 列共有 st−r 种组合,每种与固定的 r 元组合配对后都出现 λ 次,逐项相加即可。

所以强度二自动使每个单因素均衡,反过来却不成立。两行 000 与 111 的每列都零一各一次,但任意两列只有 00,11,缺少另外两种组合。

两两独立而不相互独立

从正交表的 N 行中等概率随机选一行,把第 j 列的值记为随机变量 Xj。任取 t 列,其某种组合出现概率为 λN=1st. 各列单独均匀取 s 个水平,联合概率等于各自概率乘积,因此任意不超过 t 个不同因素相互独立。这是有限表格中的精确概率陈述,不需要近似抽样。

在四行三列表中,X3=X1⊕X2。因此任意两变量独立,但给定前两变量就完全确定第三变量。例如 ℙ(X1=X2=X3=0)=14, 而三列若相互独立,该概率应为 1/8。正交强度的意义正是明确可保证的联合阶数。

二水平编码与正交性

把零编码为 −1、一编码为 1,将上述表的三列记为 c1,c2,c3∈ℝ4,再增加全一截距列 c0。每个因素均衡,故 c0𝖳cj=0;每对因素四种组合各一次,所以其乘积有两次 1、两次 −1,从而 ci𝖳cj=0。

各列平方长度都是四。令 X=(c0,c1,c2,c3),便得到 X𝖳X=4I4. 这说明在只含截距与三个主效应的线性模型中,各列在代数上正交。它不意味着所有交互作用都能单独估计。本例在负一、一编码下 c3=−c1c2(右侧逐元素相乘),第三主效应列与前两因素交互作用列只差符号,二者在该表上混杂,无法同时辨认。

原四行表的截距与三列负一一编码,右侧显示两列乘积与第三列反号
正交可由列内积检查;同时 c₃=−c₁c₂ 显示一个具体的交互作用混杂。主效应均衡不是能识别任意复杂模型的保证。

变式。 能否只用四次试验,给四个二水平因素构造强度二正交表?若能,其四个均衡编码列加截距列会是 ℝ4 中五个非零且两两正交的向量。非零正交向量必线性无关,而四维空间最多有四个,矛盾。因此不能;单有整除条件 4=1×22 并不足以保证任意列数都可实现。

拉丁方与三因素构造

对一个 s 阶拉丁方,逐格记录“行号、列号、符号”,得到 s2 行、三列的表。行号与列号的组合自然各出现一次;固定行号和符号,由拉丁性质唯一确定列号;固定列号和符号也唯一确定行号。故得到 OA⁡(s2,3,s,2)。

反过来,若有指数一的这类表,以前两列作为行号、列号,第三列填符号,二列投影均衡恰好保证每行每列不重复。这个双向构造把“一个方阵”与“一张试验清单”对应起来,不能把两种表格的行列数直接混写。

定义检验程序

下面按定义枚举列组合、计数每种投影。输入为至少一行等长试验,每个水平必须是 0,…,s−1 的整数;不修改原表。

Python 3
from collections import Counter
from itertools import combinations


def orthogonal_index(array, levels, strength):
    rows = [tuple(row) for row in array]
    if type(levels) is not int or levels < 2 or not rows:
        raise ValueError("Need rows and at least two levels")
    width = len(rows[0])
    if (type(strength) is not int or not 1 <= strength <= width
            or any(len(row) != width for row in rows)):
        raise ValueError("Invalid dimensions or strength")
    if any(type(x) is not int or not 0 <= x < levels
           for row in rows for x in row):
        raise ValueError("Invalid level")
    target, remainder = divmod(len(rows), levels ** strength)
    if remainder or target == 0:
        return None
    for columns in combinations(range(width), strength):
        counts = Counter(tuple(row[j] for j in columns) for row in rows)
        if len(counts) != levels ** strength:
            return None
        if any(count != target for count in counts.values()):
            return None
    return target


print(orthogonal_index([[0, 0, 0], [0, 1, 1],
                        [1, 0, 1], [1, 1, 0]], 2, 2))
print(orthogonal_index([[0, 0, 0], [1, 1, 1]], 2, 2))
# 1
# None

只要每组列投影有全部 st 种不同组合、每种频数都为同一正整数,便恰好满足定义;任何缺失或频数不等都使程序返回 None。按散列表平均时间计,检查所有投影需 O((kt)Nt) 次基本操作;复制输入需 O(Nk) 空间,单次投影计数至多保存 N 个长度 t 的键。

覆盖数组只要求每种指定组合至少出现一次,不要求频数相等。在测试问题中,这种放宽可允许更多因素使用较少的试验行;是否需要均衡,应由试验分析目标而非表名决定。

参考资料

  1. ↑ Andries E. Brouwer:Orthogonal Arrays,Eindhoven University of Technology。该页使用因素为行、试验为列的转置约定 OAλ(n,m,t);本文使用 N 行试验、k 列因素,并保留相同的等频定义。访问日期:2026年10月25日。