ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Minitab田口设计实战:用正交试验优化遗传算法参数

Minitab田口设计实战:用正交试验优化遗传算法参数 Minitab田口设计实战如何用正交试验优化遗传算法参数附完整操作步骤做遗传算法相关项目的人十有八九都被参数调优折磨过。种群规模设多少合适交叉率到底是0.8还是0.9变异率太小怕早熟、太大又怕破坏优秀解只能一遍遍改参数、跑程序像在暗房里洗照片全凭感觉试。我就是从这条路走过来的试到后来实在受不了了才转向用Minitab的田口设计来做正交试验结果9次实验就把原来需要几十次甚至上百次尝试才能确定的参数组合给定了下来而且效果更稳定。这篇分享就围绕这个核心动作展开怎么把遗传算法的参数调优问题转化成一次规范的正交试验在Minitab里一步步做完田口设计、分析信噪比、拿到推荐参数组合并做确认实验。说白了我写这篇的目标就是让做算法优化、参数调优的工程师和学生看完之后能直接上手操作不再靠玄学调参。1. 遗传算法参数调优为什么值得用田口设计1.1 先搞清楚遗传算法里到底哪些参数值得调很多入门者面对遗传算法以为只要把代码跑通就好参数随便写写。真到实际工程里参数选得合不合理直接决定算法是快速收敛还是早熟停滞。我现在做遗传算法项目最先关注的参数无非这几个种群规模Population Size每一代保留多少个候选解。太小了搜索广度不够容易陷在局部最优太大了计算开销高每一轮进化都慢得让人抓狂。交叉率Crossover Rate交叉算子被使用的概率决定算法开发能力也就是从已有解中组合出更优解的能力。一般取0.6到1.0之间。变异率Mutation Rate对个别基因做随机扰动是算法探索新区域的窗口也是最容易出问题的参数。太小容易早熟太大就退化成随机搜索。迭代次数或代际数Generations控制算法跑多久。但很多项目里并不是跑满迭代次数而是看是否达到收敛阈值。这四个参数里前三者有很强的交互作用。种群规模大、交叉率高的时候变异率就不能太高否则进化过程会变成瞎折腾种群规模小的时候变异率反而要适当放大才有机会跳出局部陷阱。这种牵一发动全身的关系正是需要用系统化试验去挖掘的。顺带说一句迭代次数、选择策略、锦标赛大小这些虽然也会影响结果但不像上面三个那么“敏感”。我在做田口设计时通常把迭代次数固定到一个足够大的值让它不要成为瓶颈然后把主要的试验因子放在种群规模、交叉率、变异率上。1.2 常规调参方法的三个坑我都踩过先说网格搜索。把每个参数设几个候选值然后全组合去跑比如种群规模取3个值、交叉率取3个值、变异率取3个值那就是27个组合。每个组合为了消除随机性还要多跑几遍取平均一共得跑上百次实验。如果是TSP这类稍大规模的问题一次就要几十秒到几分钟整套下来一晚上就没了。而且网格搜索只能告诉你哪些点“试过”没法告诉你没试过的区域趋势如何。连续变量取10个值、20个值的时候组合数更是直接爆炸。再说手工试参。说句不好听的绝大多数人的“经验调参”就是固定其他参数只动一个参数反复跑。但前面也说了参数之间是有交互的单个参数最优不代表组合最优。我遇到过好几次单独看交叉率越高越好但把交叉率提到0.95后配合0.01的低变异率算法反而在某个局部解附近反复震荡跑几十代都不动。还有一类做法是随机搜索或者贝叶斯优化理论上没问题但对工程人员来说有个很现实的问题贝叶斯优化要维护代理模型得写不少代码每次实验要等待模型更新整体流程也不轻。田口设计的思路完全不一样不追求把全空间都跑一遍而是用一张分布均匀的正交表用少量代表性的实验点去覆盖参数空间再从这些实验点里推断出趋势和最优组合。遗传算法的参数调优恰恰是田口设计最擅长的场景——因子数量不多、因子之间存在交互、单次实验成本高、目标指标波动比较大。1.3 田口设计的核心思想正交表和信噪比田口设计也叫田口方法Taguchi Method本质上是试验设计DOE家族里的一员。它的两个核心概念一个比一个实用。第一个是正交表。正交表用符号表示常见的是L93^4意思是做一个9行4列的试验方案每一列可以容纳一个3水平的因子任意两列之间在水平组合上达到平衡。也就是说对于任意一个因子的每个水平其他因子各水平出现的次数都一样多。这种平衡性保证了每个因子的主效应可以独立估计不至于被其他参数的取值偏差带偏。用我之前那个27组全组合的例子来说田口用9组实验就能覆盖到主要趋势实验量直接少了三分之二。第二个是信噪比SN Ratio。这是田口设计区别于普通正交试验的关键。Sn比不是衡量结果本身的大小而是衡量结果的稳定性或者说面对噪声的稳健性。在遗传算法里噪声从哪里来来自随机初始化、随机选择、随机变异。同一个参数组合跑5次路径长度的结果一定会有波动。如果一个参数组合的平均路径长度很好但5次结果忽好忽坏那它在真实项目里其实是不可靠的反过来平均结果略差一点但每次都很稳反而更值得用。田口的信噪比理念就是把“想要结果好”和“想要结果稳”这两个诉求合并成一个指标通过最大化或最小化这个指标来选参数。2. 动手前的准备因子、水平与质量特性2.1 选定一个具体场景别在抽象里打转拿我自己优化的一个经典问题来演示用遗传算法求解30个城市的TSP问题目标是找到走遍所有城市且路径总和最短的回路。这不是什么稀奇案例但胜在结果可量化、可复现非常适合用来演示田口设计全流程。在这个场景里质量特性就是最优路径长度。路径长度越短越好所以这是一个“望小”特性。注意在实际项目里不一定要拿最终路径长度作为响应也可以用“达到收敛阈值所需的代数”“最终解的排名百分位”“连续多少代不改进的次数”等这些都看具体需求。我习惯优先用反映最终解质量的指标因为其他指标再漂亮解不好也没用。为了演示的纯净性我们把迭代次数固定为200代锦标赛大小固定为2种群初始化方式和变异算子都固定不变只对三个参数做因子设计。这符合田口设计的基本要求尽可能把无关变量控制一致只让少数几个因子变化。2.2 因子和水平怎么取取值依据是什么这一步很多人会忽略觉得直接从文献抄一组参数就行。实际上因子的取值范围直接决定了试验的结论有没有意义。取值范围太窄可能漏掉真正的最优点太宽又会让实验结果过于分化、难以定位到可用的最优解。我们需要对遗传算法参数的经验规律有一定了解种群规模一般取问题规模城市数的1到5倍。30个城市取80、120、160三个水平比较合理。80是及格线160已经相对充裕但计算时间也在增长。交叉率遗传算法常用的高交叉率区间是0.7到0.9。极端取值也有用0.6到1.0的。有几个工程上的经验数值可取0.85附近是一个非常常见的好位置。综合来看取0.7、0.85、0.95三个水平既覆盖常用区间又留出了高低两个极端方便响应曲面表达趋势。变异率这是最需要小心的参数。取低了容易早熟取高了变成随机搜索。0.01是很多教科书推荐的保守起点0.05是工程上很常见的中间值0.1则被许多人认为是“偏高”但不离谱的值。所以三个水平定为0.01、0.05、0.1。这里有个经验要分享水平间隔不要等得太密。如果两个水平之间区别太小结果差异会被随机噪声淹没信噪比的计算就失去意义了。比如交叉率取0.8、0.82、0.84跑出来几乎不会有可辨识的差异因为遗传算法本身的随机波动都比这个幅度大。田口设计本质上是在找参数的“区域最优”不是精确到小数点后两位的“点最优”。2.3 质量特性与信噪比公式先用一句话讲透田口设计给不同特性定义了不同的信噪比公式最常用的有三种望大特性越大越好公式为 SN -10lg(Σ (1/y_i²) / n)望小特性越小越好公式为 SN -10lg(Σ y_i² / n)望目特性越接近目标值越好公式更复杂一些注意所有公式前面都有个负号所以结果越大代表质量越好。这一点特别容易看反。我在刚用田口设计时看到信噪比主效应图上某个点的数值更大但它对应的路径长度均值其实更大一度被绕晕。后来干脆在纸上写清楚对于望小特性路径越短y_i越小Σy_i² 越小-10lg 后面那一项负得越少最终SN值反而越大。所以永远记住信噪比越大代表稳健性越好。至于“越短越好”这个原始目标Minitab会同时给出均值响应表两个表放在一起看就不会混乱了。3. Minitab田口设计完整操作步骤3.1 先算自由度选对正交表Minitab里创建田口设计第一步是选正交表。这里需要一点点自由度概念。一个3水平因子要估计它的主效应需要占用2个自由度。现在有三个3水平因子主效应占用3×26个自由度。L9正交表总自由度是9-18个多出来的2个自由度可以用来看交互作用或者作为误差估计。所以L93^4足够。如果因子数量更多比如4个因子都是3水平总自由度需求是9个L9就不够用了要升级到L273^13或考虑2水平的L16。这里给新手一个建议不要把交互作用都塞进正交表否则很容易出现“表里明明还有列但自由度已经不够做误差估计”的尴尬情况。我一般先看主效应如果结果里某个因子的效应特别大、主效应图交叉严重再用更细化的试验去研究交互。在创建田口设计时Minitab会生成一列“空列”。这个空列不能随意删掉它在后续分析中可以作为误差列使用也可以用来检查有没有不可控因素混入实验。我习惯在正式实验前先用空列做一次空白试验确认结果都还在正常波动范围再进入正式实验流程。3.2 创建田口设计的具体路径和设置打开Minitab之后按下面的路径操作统计 DOE 田口 创建田口设计在弹出的对话框里需要按照顺序完成这么几件事在“田口设计类型”中选择“L9 (3^4)”。如果你的Minitab版本界面略有不同找带有“3水平”字样且行数为9的设计即可。点击“因子”按钮把三个因子名称依次填入并指定水平值。比如“种群规模”填80 120 160“交叉率”填0.7 0.85 0.95“变异率”填0.01 0.05 0.1。点击“选项”按钮勾选“将非因子列存储为闲置列”或类似选项具体名称在不同版本中略有差异但思路一致尽量保留设计本身的完整性。确认后Minitab会在工作表中生成一个设计矩阵包含9行和若干列。前面几列是因子列编码1、2、3后面会有“设计”“重复”“组”等辅助列。把实际水平值放到因子列之后工作表中会以实际值显示这时候设计就“活”了。经常会有人在这里犯迷糊为什么我设置了“水平值”之后工作表里显示的还是1、2、3那多半是因为他把水平值填到了“水平定义”里但没有正确应用或者是直接忽略了“因子”对话框里的赋值。正确操作后Minitab的显示应该是因子列直接显示80、120、160这类实际数值。3.3 执行实验与数据回收的标准化流程设计表创建好后每一行就是一个参数组合。这时候要回到你写的遗传算法程序里把参数替换成对应行的数值然后运行程序记录结果。这里强烈建议每组实验重复运行多次而不是只跑一次。遗传算法是随机算法单次运行的结果波动非常大有时不同随机种子跑出来的路径长度能相差10%到20%。田口的信噪比计算需要数据来估计波动程度重复次数太少了SN比就变成了单次结果的单调变换没有意义。我一般用“固定随机种子差”的方式每组参数用5个不同的随机种子跑5次把这5个路径长度都记录下来作为同一个实验点的重复观测值。如果程序本身支持批处理这一步很快如果不支持可以写个循环脚本。需要注意的是不同组之间不要用同一套随机种子否则会引入系统偏差。下面是我当时做实验时用到的一段脚本逻辑供参考import random import ga_solver # 假设这是文件内的求解器 for row in design_matrix: result [] for seed in range(5): random.seed(seed row[实验号] * 100) best ga_solver( pop_sizerow[种群规模], crossover_raterow[交叉率], mutation_raterow[变异率], generations200, ) result.append(best) # 将 result 写入响应列在Minitab的工作表里每一行对应一次实验重复的5个结果可以放在同一行的5个响应列里也可以竖着往下放。我习惯放在同一行5个响应列里因为这样在“分析田口设计”里选择响应时一次就能选中多列非常方便。要注意数据对齐别让第一组的结果串到第二组下面去了。3.4 分析田口设计选对响应和信噪比类型实验数据收集完毕接下来就是看结果的环节。路径如下统计 DOE 田口 分析田口设计在对话框里在“响应数据”中选中你存放结果的列。如果有5列重复结果就全部选中如果只有一个结果列就选中那一列。在“分析项”或“选项”中把“分析方法”设为“信噪比 均值 标准差”或者直接选择“信噪比 均值”取决于Minitab版本。在“质量特性”中选择“望小”因为我们的目标是路径长度越小越好。点击“确定”Minitab会生成若干张表格和图形其中最核心的有三样响应表信噪比、响应表均值、主效应图信噪比和均值。有些人会在质量特性里选错成“望大”然后发现信噪比越大、路径长度反而越大得出完全相反的结论。我在第一次演示给别人看时就犯了这个错误导致整个分析方向都反了。所以这一步真的要反复确认望小就是结果越小越好。另外还要留意“标准差”那一列。Minitab会自动根据重复测量数据计算每组实验的标准差这个标准差实际上就是基因算法的随机波动。如果某组参数的标准差特别大说明该参数组合虽然可能找到一个不错的解但稳定性差、可复现性差这在工程上有时比结果稍差但表现稳定的组合更让人头疼。信噪比的优秀之处就在于它会自动在这个“平均值”和“标准差”之间做权衡。3.5 响应表怎么看Delta和排秩代表什么Minitab输出的响应表大概长这样以信噪比响应表为例水平种群规模交叉率变异率1-55.83-55.12-55.392-54.76-54.69-54.873-54.75-55.45-55.02Delta1.080.760.52排秩123Delta的计算方式很简单该因子在各水平下信噪比均值中最大值减最小值。Delta越大说明这个因子对结果的影响越大排秩就越靠前。在上面的例子里种群规模对信噪比的影响最大变异率最小。注意响应表里每个水平下的值是Minitab把该因子处于该水平的所有实验组求平均得到的。因为正交表的均衡性各水平下的实验组中其他因子的分布是均匀的所以这个平均值的差就反映了该因子自身的效应。主效应图其实就是响应表的数据可视化。信噪比主效应图上哪个因子在哪个水平下取值最高那么这个因子的最优水平就是那个点。加上均值主效应图就能同时看到“稳定性最优”和“平均性能最优”各自的参数选择。当两者不完全一致时我优先看信噪比因为稳定性差意味着参数在实际运行时的表现不可控。4. 实例结果解析从响应表到最终参数组合4.1 九组实验的真实数据长什么样这里我把当时在30城市TSP上做的9组实验结果贴出来所有结果都是5次独立运行后记录的最优路径长度路径长度单位与坐标尺度相关数值本身并不关键关键是数值之间的差距和趋势。实验号种群规模交叉率变异率5次运行最优路径长度1800.700.01586, 594, 590, 599, 5882800.850.05571, 568, 580, 575, 5723800.950.10602, 601, 608, 610, 60541200.700.05539, 548, 545, 552, 54151200.850.10547, 553, 549, 558, 54561200.950.01555, 549, 551, 560, 55771600.700.10548, 551, 559, 546, 55381600.850.01534, 541, 536, 538, 54091600.950.05545, 550, 542, 548, 547单看每一行实验8表现最好平均约537.8实验3表现最差平均约605.2。但请注意我们不是只看这两行否则就又回到“拿肉眼挑最优组合”的老路了。田口设计的价值在于它能把每一列不同水平的影响单独拎出来看。4.2 主效应解读为什么变异率低反而更好我们用这9组数据在Minitab里跑分析输出的均值主效应和信噪比主效应图会呈现出这样几条趋势种群规模从80升到120路径长度明显下降从120升到160下降趋势趋缓。这说明80的种群规模在这个问题上的确不够120已经是一个性价比很高的水平再增加到160的收益有限。交叉率在0.85处表现好0.70和0.95都有不同程度恶化。0.95过高时优秀个体容易被频繁交叉破坏0.70偏低又不利于产生新的组合。变异率0.10在高种群规模下表现尚可但在小种群规模下完全崩坏这在统计上表现为交互作用的痕迹。更值得注意的是0.01的低变异率在中等以上种群规模下表现非常稳定平均结果甚至优于0.05。这说明在这个30城市规模的问题上算法一旦靠较大种群和较高交叉率保证了搜索能力变异率的扰动反而成了阻碍精细收敛的因素。综合信噪比响应表推荐参数组合为种群规模160交叉率0.85变异率0.01。这个结果和实验8完全吻合也和我们平常对遗传算法的一些直觉经验一致大种群高交叉低变异适合中小规模组合优化问题。不过也不能把它推广过头一旦问题规模变大、多模态特征明显变异率还是需要适当上调的。4.3 确认实验别拿到推荐值就直接上项目田口分析给出推荐组合之后必须做确认实验。这一步的意义在于验证分析出来的最优因子水平组合在实际运行中确实有效而不是只是统计推断的一个副产品。确认实验的做法很简单用推荐参数组合换一组此前没有用过的随机种子多跑若干次记录结果然后将平均值与正交表9组实验中的最佳结果做比较。如果确认实验结果等于或优于之前的最佳实验说明分析有效如果明显差于之前的最佳实验说明可能存在未建模的因子或交互作用需要重新检查实验设计。我当时做确认实验时用160、0.85、0.01的组合跑10次平均最优路径长度约为535.2比实验8的537.8还要好一点波动也更小。至此整个流程闭环。值得一提的一个细节确认实验时“换一组随机种子”很重要。如果继续沿用之前用来搜索的那组随机种子结果会被“作弊”掉。因为随机种子相同就意味着初始化群体相同相当于你复习了一遍原题再考试。任何调参工作流里随机种子的管理和分离都是基本素养。5. 常见问题与避坑指南5.1 因子数量超过了表容量怎么办如果遗传算法的关键参数变成五六个L9显然不够用。这时有两条路可选。第一条路是换更大的正交表比如L273^13。L27的可用列更多自由度也更高代价是实验组数从9涨到27对计算资源的要求显著上升。第二条路是做两阶段实验先用小表快速筛选因子留下影响显著的少数因子再做一轮精细正交试验。这里的关键是筛选阶段不要用太窄的水平范围否则可能漏掉潜在的重要因子。我把这个方法理解为“漏斗式”调参先广撒网再聚焦。5.2 多个评价指标同时存在怎么处理有些问题不止看最优路径长度还要看运行时间、收敛代数、内存占用等。多响应情况下田口设计可以分别对每个响应做分析然后综合判断。我通常的做法是先确定主要指标和次要指标主要指标按信噪比选因子水平次要指标作为约束条件来筛选候选组合。如果主要指标和次要指标强烈冲突可以在Minitab里用同时优化多个响应的功能但要注意设置合理的权重不要平均用力否则最后会得到一个两头都不讨好的结果。5.3 Minitab操作中的典型错误因子水平顺序填反。最典型的是把0.01、0.05、0.1填成了0.1、0.05、0.01结果因子列里1水平对应0.13水平对应0.01。表面看起来数据没问题但响应表的水平顺序就完全反了主效应图也会呈现出错误的单调趋势。响应列选错范围。数据录入时如果混入了表头或注释行分析时选中了多余的空行Minitab会报错或者计算出异常的Delta值。建议每次分析前先用“数据 排序”或图形画个箱线图快速检查数据范围。忘记设置“望小”。前面我提过自己被“望大”坑过这里再强调一次。做任何分析之前把质量问题特性这一项重复检查一遍。直接把单次结果当重复数据。重复数据不是让你把同一组参数跑两次然后把较长的那次删掉而是所有结果都要进入计算。数据造假或者选择性删数据会让信噪比完全失真。5.4 遗传算法早熟现象与参数选择的关系很多人在实测遗传算法时遇到“早熟”现象前几代还在快速改进十几代之后突然完全不动了但离全局最优还很远。以往大家只知道“早熟说明陷入了局部最优”但不知道该调哪个参数于是盲目增大变异率结果问题反而更严重。用田口设计的视角就清楚多了早熟的根源往往是种群规模不足和交叉率不当的组合而不是单一变异率的问题。种群规模小时种群多样性从一开始就不够后面的进化再怎么折腾也只是在少数几个解之间“打转”。这个时候只增大变异率确实可以跳出来但也会让搜索变得极其低效。更合理的做法是先保证足够大的种群规模把交叉率设置在均衡区间再根据具体情况微调变异率。这也正好解释了为什么有时候用大种群高变异率的组合跑TSP效果反而不如大种群低变异率。因为当交叉算子已经把优秀的路径片段组合得差不多了高变异率只会不断破坏精细结构。尽早明白这个道理可以省下很多调试时间。6. 写在最后关于调参这件事我的一些实在话跟手工试参相比田口设计最大的价值在于它逼着你先想清楚“我要优化哪些参数、每个参数大概在什么范围、目标是什么”而不是一上来就OpenLoop式的瞎试。自动写程序跑实验当然有它的意义但很多时候工程师在动手跑几百次实验之前先花半天时间做一个系统性的试验设计产出的结论来得更快、也更可信。我个人在实际操作中的体会是田口设计调遗传算法参数真正的好用之处不在“找出唯一正确参数”而在“缩小搜索空间、排除明显错误方向”。数据跑完之后你得到的是一个相对可靠的参数区间和一套可复现的验证方法至于要不要在这个基础上再做一轮响应面精调完全取决于问题本身的重要程度。另外要提醒一句不同版本的Minitab菜单名称略有差别遇到找不到选项的情况记得积极利用软件的“帮助”功能对照本文的思路找对应入口基本不会走偏。如果后面你也在做遗传算法调参这件事不妨先用一次L9的正交试验把几个关键参数的水平都摆出来跑一遍哪怕结果不尽如人意你对参数空间的整体感知也一定会比现在清晰很多。
返回列表