本文用Python DOE试验矩阵完成三件事:生成3因子2水平的8组全因子组合、输出可复现的随机运行顺序、验算各因子的主效应。全部响应值为合成教学数据,代码只演示设计与计算,不提供具体生产工艺建议。
1. 先把设计写成数据结构
示例使用A温度、B时间、C速度,每个因子两个水平。实际项目中,水平必须依据工程知识、安全边界、设备能力、可操作范围和过程噪声确定,不能套用固定比例。
from itertools import product
import random
factors = {
"A_temp": [160, 180],
"B_time": [20, 40],
"C_speed": [60, 90],
}
names = list(factors)
levels = [factors[name] for name in names]
design = list(product(*levels))
assert len(design) == 2 ** len(factors) == 8
itertools.product返回笛卡尔积。这里得到的是8个不同角点组合,不包含中心点、独立重复或仿行增加的试验。
2. 输出标准序矩阵
print("std_order," + ",".join(names))
for i, row in enumerate(design, start=1):
print(i, *row, sep=",")
输出:
std_order,A_temp,B_time,C_speed
1,160,20,60
2,160,20,90
3,160,40,60
4,160,40,90
5,180,20,60
6,180,20,90
7,180,40,60
8,180,40,90
标准序便于检查组合是否完整,但现场通常不应直接按此顺序运行。若设备升温、材料随时间变化或人员熟练度存在趋势,固定顺序可能把这些影响与因子效应混在一起。
3. 用固定随机种子生成可复现运行顺序
seed = 20261030
run_order = list(range(8))
random.Random(seed).shuffle(run_order)
print("run_order,std_order," + ",".join(names))
for run_no, index in enumerate(run_order, start=1):
print(run_no, index + 1, *design[index], sep=",")
固定种子的作用是让这份教学代码再次运行时得到同一顺序,不是为了长期反复使用同一个现场随机顺序。实际项目应记录种子、运行顺序和每次执行偏差。
如果试验不能完全随机,例如高温设置切换成本很高,需要把限制写进方案,并评估合适的受限随机化或裂区等方法,而不是事后忽略执行结构。
4. 加一组合成响应值,验算主效应
以下8个Y值与标准序一一对应,纯属合成教学数据:
y = [48, 52, 50, 57, 51, 56, 55, 66]
assert len(y) == len(design)
def mean(values):
return sum(values) / len(values)
def main_effect(factor_index):
high_level = max(levels[factor_index])
high = [response for row, response in zip(design, y)
if row[factor_index] == high_level]
low = [response for row, response in zip(design, y)
if row[factor_index] != high_level]
return mean(high) - mean(low)
for i, name in enumerate(names):
print(name, f"{main_effect(i):.2f}")
输出:
A_temp 5.25
B_time 5.25
C_speed 6.75
以A为例,主效应的计算五步为:
- 公式:A主效应=A高水平时Y均值-A低水平时Y均值。
- 代入:
(50+57+55+66)÷4-(48+52+51+56)÷4。 - 结果:
57.00-51.75=5.25。 - 单位:与Y一致;本例Y仅为无单位教学值。
- 工程含义:它描述这组合成数据在该设计区域内的平均差异,不证明真实因果关系,也不能外推到160---180之外。
B的主效应同为5.25,C为6.75。这里只演示计算,不凭这8个无重复点做显著性断言。

5. 交互作用不能只靠三个主效应回答
主效应是跨其他因子水平的平均结果。如果A的效果随B水平变化,就存在交互作用。可以计算AB交互对比,帮助理解"组合"与"单因子平均值"的区别:
def interaction_effect(i, j):
same = []
different = []
for row, response in zip(design, y):
# 将低/高编码为-1/+1,乘积为+1表示同侧组合
code_i = 1 if row[i] == max(levels[i]) else -1
code_j = 1 if row[j] == max(levels[j]) else -1
(same if code_i * code_j == 1 else different).append(response)
return mean(same) - mean(different)
print("AB interaction contrast:",
f"{interaction_effect(0, 1):.2f}")
本例AB交互效应为55.25-53.50=1.75。其中,同侧组合为第1、2、7、8行,Y均值为55.25;异侧组合为第3、4、5、6行,Y均值为53.50。是否重要不能只看这个数或某个P值,还要结合效应大小、测量与过程误差、残差、工程意义和确认试验。若存在重要交互,单独报告A或B主效应可能不足以支持选参。
6. 保存现场执行表时还应增加哪些列
run_order:实际运行顺序
std_order:设计标准序
block:批次、日期或设备等区组
A_actual/B_actual/C_actual:实际达到的因子值
Y:按定义测得的响应
operator/material_lot:必要执行信息
deviation:未按方案执行的偏差与处理
不要把"同一样品重复测量三次"直接复制成三行独立试验。独立重复通常需要重新设置并运行过程;重复测量主要提供测量重复性信息,两者误差含义不同。
7. 两水平矩阵的适用边界
- 适合筛选和局部线性判断,不等于能完整估计二次弯曲。
- 数字因子可评估加入中心点检查弯曲迹象;中心点不等于完整响应曲面。
- 含类别因子时不能机械计算全部因子的数值中点。
- 结论只覆盖研究区域与执行条件,确认试验仍需独立安排。
两个技术问题
**Python生成8行后就能直接做试验吗?**不能。还要确认Y与测量、因子水平依据、固定条件、随机化、区组、重复、风险与确认试验。
**主效应最大就优先选这个因子吗?**不一定。要同时看交互作用、效应单位、工程意义、误差、可控性和成本,不能只看排序。
信息截至2026年10月30日。代码使用合成教学数据复算;技术结论须结合真实试验设计与现场验证。