遺傳編程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;

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; }  

 

 下面就是整個算法的架子了:

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)); }

  

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM