遗传编程GP-拟合方程
一般都是用机器学习、梯度下降或sklearn、pytorch来做函数拟合运算,今天介绍遗传编程,或称基因编程/GP,来做这个计算
最终就是构造一棵树AST,来表示运算的先后、权重:
具体原理可以参考这篇文章:https://blog.csdn.net/ocd_with_naming/article/details/98901749
我们的目标是拟合这个函数:
np.sin(x) + np.log(x)
图像为:
先来一段java代码,是加载训练数据的,x、y的一个list;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | private static List<Sample<Double>> load训练数据() { List<Sample<Double>> samples= new ArrayList<>(); samples.add( new DoubleDataSample( new Double[]{ 1.0 , 0.8414709848078965 })); //第一个为x,第二个为y samples.add( new DoubleDataSample( new Double[]{ 1.1 , 0.9865175398657604 })); samples.add( new DoubleDataSample( new Double[]{ 1.2000000000000002 , 1.1143606427611812 })); samples.add( new DoubleDataSample( new Double[]{ 1.3000000000000003 , 1.2259224498846844 })); samples.add( new DoubleDataSample( new Double[]{ 1.4000000000000004 , 1.3219219666096733 })); samples.add( new DoubleDataSample( new Double[]{ 1.5000000000000004 , 1.4029600947122192 })); samples.add( new DoubleDataSample( new Double[]{ 1.6000000000000005 , 1.4695772322872411 })); samples.add( new DoubleDataSample( new Double[]{ 1.7000000000000006 , 1.5222930615146393 })); samples.add( new DoubleDataSample( new Double[]{ 1.8000000000000007 , 1.5616342957803144 })); samples.add( new DoubleDataSample( new Double[]{ 1.9000000000000008 , 1.5881539738598094 })); //省略很多x/y对 return samples; } |
下面就是整个算法的架子了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | public static void main(String[] args) { List<Op<Double>> terminals= new ArrayList<>(); terminals.add(Var.of( "x" , 0 )); //由于只有1个自变量,所以这里只有x //0代表第一个自变量 //如果是向量,则此处可以为x1/0, x2/1, x3/2 以此类推 List<Sample<Double>> samples=load训练数据(); final ISeq<Op<Double>> OPS = ISeq.of(MathOp.ADD, MathOp.SUB, MathOp.MUL, MathOp.SIN,MathOp.COS, MathOp.LOG); //这些是算法允许使用的操作算子 final ISeq<Op<Double>> TMS = ISeq.of(terminals); //上面的自变量在此处挂接上 final Regression<Double> REGRESSION = Regression.of( Regression.codecOf( OPS, TMS, 5 , t -> t.getGene().size() < 30 ), Error.of(LossFunction::mse), //MSE计算误差 samples ); final Engine<ProgramGene<Double>, Double> engine = Engine .builder(REGRESSION) .minimizing() .alterers( new SingleNodeCrossover<>( 0.1 ), new Mutator<>()) .build(); final EvolutionResult<ProgramGene<Double>, Double> er = engine.stream() .limit(Limits.byExecutionTime(Duration.ofSeconds( 5 ))) .collect(EvolutionResult.toBestEvolutionResult()); final ProgramGene<Double> program = er.getBestPhenotype() .getGenotype() .getGene(); final TreeNode<Op<Double>> tree = program.toTreeNode(); MathExpr.rewrite(tree); System.out.println( "G: " + er.getTotalGenerations()); System.out.println( "F: " + new MathExpr(tree)); System.out.println( "E: " + REGRESSION.error(tree)); } |
自省推动进步,视野决定未来。
心怀远大理想。
为了家庭幸福而努力。
商业合作请看此处:https://www.magicube.ai
心怀远大理想。
为了家庭幸福而努力。
商业合作请看此处:https://www.magicube.ai
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】