
基于 scikit-opt 遗传算法实现曲线拟合从残差最小化到参数寻优实战【免费下载链接】scikit-optGenetic Algorithm, Particle Swarm Optimization, Simulated Annealing, Ant Colony Optimization Algorithm,Immune Algorithm, Artificial Fish Swarm Algorithm, Differential Evolution and TSP(Traveling salesman)项目地址: https://gitcode.com/GitHub_Trending/sci/scikit-opt导读本文以 scikit-opt 仓库官方文档 docs/en/curve_fitting.md 为核心完整演示如何用遗传算法Genetic Algorithm, GA对带噪声的非线性数据做曲线拟合。核心思路是把曲线拟合等价转化为参数优化给定模型形式f(x) a·x³ b·x² c·x d用 GA 在参数空间(a, b, c, d)中搜索使残差平方和最小的最优解。读完本文你将掌握数据构造、目标函数设计、GA类核心参数的选取依据、结果输出与可视化并能结合仓库源码理解 GA 的二进制编码、锦标赛选择与适应度排名机制。一、原理曲线拟合为何可以交给遗传算法传统的曲线拟合如最小二乘法依赖模型对参数可导、目标函数连续等条件。而遗传算法是一种不依赖梯度的群体智能优化方法它只需一个能够度量当前参数组合有多差的目标函数即可工作定义模型形式先验地假设数据满足某个带参数的函数形式构造残差目标函数对一组候选参数计算模型预测值与真实观测值的偏差残差平方和用 GA 搜索最优参数目标函数值越小说明这组参数拟合得越好GA 在参数空间中不断进化逼近全局最优。scikit-opt 的GA类正是为最小化某个多变量函数设计的官方文档 docs/en/args.md 中明确func是目标函数objective functionn_dim是目标函数的输入维度即待优化参数个数返回值best_x即最优参数向量。二、Step 1生成带噪声的训练数据沿用官方文档的做法先生成一个三次多项式叠加随机噪声的 toy 数据集import numpy as np import matplotlib.pyplot as plt from sko.GA import GA x_true np.linspace(-1.2, 1.2, 30) y_true x_true ** 3 - x_true 0.4 * np.random.rand(30) plt.plot(x_true, y_true, o)x_true在[-1.2, 1.2]区间均匀取 30 个点真实关系为y x³ - x再加上0.4 * np.random.rand(30)的均匀噪声模拟真实世界中的观测误差先画出散点图便于后续与拟合曲线对比。这里的真实模型就是y a·x³ b·x² c·x d中a1, b0, c-1, d0的特例因此理想的拟合结果应逼近这组参数。三、Step 2构造残差目标函数曲线拟合的优化目标是让模型输出逼近观测值最常见的度量是残差平方和SSEdef f_fun(x, a, b, c, d): return a * x ** 3 b * x ** 2 c * x d def obj_fun(p): a, b, c, d p residuals np.square(f_fun(x_true, a, b, c, d) - y_true).sum() return residuals关键设计点模型函数f_fun固定结构为三次多项式待定的是系数a, b, c, d目标函数obj_fun接收一个 4 维参数向量p解包为a, b, c, d计算全样本残差平方和。obj_fun越小说明参数拟合越好从 sko/GA.py 的源码注释可以看出GA对func的要求是输入一个候选解向量、输出一个标量目标值obj_fun完全符合这一契约。需要说明的是GA内部通过 sko/tools.py 的func_transformer对目标函数做包装默认的common模式下会对种群中每个个体逐个调用obj_funnp.array([func(x) for x in X])因此你的obj_fun无需自己处理批量向量输入写清单点求值逻辑即可。四、Step 3实例化 GA 并运行ga GA(funcobj_fun, n_dim4, size_pop100, max_iter500, lb[-2] * 4, ub[2] * 4) best_params, residuals ga.run() print(best_x:, best_params, \n, best_y:, residuals)结合仓库源码 sko/GA.py 与官方参数文档 docs/en/args.md解释各参数参数本文取值默认值含义来自 docs/en/args.mdfuncobj_fun必填目标函数输入参数向量、输出标量n_dim4必填目标函数输入维度即待拟合参数个数(a,b,c,d)size_pop10050种群规模注意源码要求必须为偶数size_pop % 2 0max_iter500200最大迭代代数lb[-2]*4-1变量下界可以是 int/float/listub[2]*41变量上界可以是 int/float/listprecision未设置1e-7精度int/float 或 list下文详解prob_mut未设置0.001变异概率取值 0~1constraint_eq/constraint_ueq未设置tuple()等式 / 不等式约束n_processes未设置0并行进程数0 表示使用全部 CPU参数选取的实战含义lb[-2]*4, ub[2]*4把四个系数都限制在[-2, 2]区间。因为真实系数(1, 0, -1, 0)都落在这个区间内搜索空间小、收敛快。若不确定参数范围应适当放宽边界但要意识到搜索空间随区间指数级膨胀size_pop100与max_iter500是规模大一点、迭代多一点的稳健配置适合 4 维、单峰残差平方和的拟合问题结果中best_params为最优系数向量residuals为对应的最小残差平方和。真实参数为(1, 0, -1, 0)故期望输出接近该向量且residuals与噪声强度相关0.4倍均匀噪声。五、Step 4绘制拟合结果y_predict f_fun(x_true, *best_params) fig, ax plt.subplots() ax.plot(x_true, y_true, o) ax.plot(x_true, y_predict, -) plt.show()将 GA 返回的最优参数best_params解包进f_fun得到全部 30 个采样点上的预测值散点o为带噪观测数据折线-为拟合曲线两者越贴合说明拟合质量越高。若结果不理想可加大max_iter、size_pop或调整lb/ub收缩搜索范围。六、源码级解析GA 在后台做了什么6.1 从参数到二进制染色体GA采用二进制 Gray 码编码sko/GA.py。实例化时由lb、ub、precision计算每个变量的基因段长度Lind ceil(log2((ub - lb) / precision 1))sko/GA.py染色体总长len_chrom sum(Lind)crtbp()随机生成size_pop × len_chrom的 0/1 矩阵作为初始种群sko/GA.py每代进化时chrom2x()把二进制染色体解码回[lb, ub]区间内的实数解向量Xsko/GA.py。一个值得注意的细节当precision为整数且变量取值范围不是2^n时代码会进入int_mode分支自动扩展上界并把越界值截断到ub这正是 docs/en/more_ga.md 中整数规划一节所讲的机制——若想让某些变量取整数把对应precision设为整数即可如precision[2, 1, 1e-7]。6.2 每代进化的四大算子run()的主循环sko/GA.py每代依次执行self.X self.chrom2x(self.Chrom) # 染色体解码为实数解 self.Y self.x2y() # 计算目标函数值 self.ranking() # 适应度排名 self.selection() # 选择 self.crossover() # 交叉 self.mutation() # 变异其中GA默认绑定的算子为sko/GA.pyranking来自 sko/operators/ranking.py。因为 GA 约定适应度越大越好而我们要最小化残差所以直接取负FitV -Yselectionselection_tournament_fastersko/operators/selection.py即锦标赛选择默认每场tourn_size3个候选者中取适应度最高者进入下一代crossovercrossover_2point_bit两点交叉mutationmutation以prob_mut0.001的概率按位翻转。每代结束时代码记录generation_best_X、generation_best_Y、all_history_Y、all_history_FitV等历史数据sko/GA.py供收敛性分析和可视化使用。最终run()返回全局最优best_x与best_y。6.3 可利用的输出属性根据 docs/en/args.md 的 outputs 一节GA实例提供以下属性用于分析属性含义ga.generation_best_Y每一代的最优目标值ga.generation_best_X每一代最优值对应的解ga.all_history_FitV每一代每个个体的适应度ga.all_history_Y每一代每个个体的目标函数值ga.best_y/ga.best_x全局最优目标值与解例如可以这样绘制收敛曲线观察残差随代数的下降过程import pandas as pd Y_history pd.DataFrame(ga.all_history_Y) fig, ax plt.subplots(2, 1) ax[0].plot(Y_history.index, Y_history.values, ., colorred) Y_history.min(axis1).cummin().plot(kindline) # 每代最优值的累积最小值 plt.show()该可视化范式取自仓库 examples/demo_ga.py。七、实战进阶约束、整数精度与加速7.1 给目标函数叠加约束GA支持等式约束constraint_eq与不等式约束constraint_ueqsko/GA.py。底层通过罚函数实现sko/GA.py对违反约束的个体在目标值上加1e5量级的惩罚项迫使种群进化到可行域内。若拟合问题需要限定参数范围如b 0可直接传入约束函数元组。7.2 四种加速方式sko/tools.py 提供了set_run_mode(func, mode)可给目标函数打上运行模式标记支持vectorization要求func支持批量向量输入效率最高multithreading多线程并行评估个体multiprocessing多进程并行注意 Windows 下会自动降级为多线程见 sko/tools.pycached对相同输入缓存结果基于lru_cache。用法示例from sko.tools import set_run_mode set_run_mode(obj_fun, vectorization)同时在GA构造时可用n_processes指定并行进程数0表示使用全部 CPU见 sko/GA.py。对于本例 30 个样本的拟合默认串行模式已足够快当拟合大规模数据或目标函数计算昂贵时上述模式可显著缩短单代耗时。7.3 手动指定初始种群如需复现实验或注入先验知识可以在实例化后直接覆盖ga.Chromdocs/en/more_ga.md 的 How to set up starting point or initial population 一节ga GA(funcobj_fun, n_dim4, size_pop100, max_iter500, lb[-2] * 4, ub[2] * 4) ga.Chrom np.random.randint(0, 2, size(100, ga.len_chrom)) # 手动设置初始种群八、总结与延伸用 scikit-opt 的GA做曲线拟合本质是把参数估计抽象为黑盒函数最小化完整链条是构造模型 → 定义残差平方和 → 指定参数边界实例化 GA → run() 取回最优参数 → 可视化对比。本文沿官方文档 docs/en/curve_fitting.md 的完整流程展开并补充了源码层证据参数语义与默认值见 docs/en/args.md编码、进化主循环与算子绑定见 sko/GA.py适应度取负与锦标赛选择见 sko/operators/ranking.py 与 sko/operators/selection.py加速模式见 sko/tools.py。想进一步深入可参考同一文档体系下的 docs/en/more_ga.md整数规划、TSP 起点终点固定、初始种群设置、examples/demo_ga.pySchaffer 函数寻优与收敛曲线绘制以及 examples/demo_ga_udf.py自定义算子。说明原文档中附带的拟合效果图存储于仓库外的图床本文未转载任何外部图片读者运行上述代码即可在本地复现散点与拟合曲线。【免费下载链接】scikit-optGenetic Algorithm, Particle Swarm Optimization, Simulated Annealing, Ant Colony Optimization Algorithm,Immune Algorithm, Artificial Fish Swarm Algorithm, Differential Evolution and TSP(Traveling salesman)项目地址: https://gitcode.com/GitHub_Trending/sci/scikit-opt创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考