文档章节

在Ignite中使用遗传算法

李玉珏
 李玉珏
发布于 2018/10/24 16:40
字数 1556
阅读 159
收藏 0

本系列共6篇文章,会通过一些代码示例,讲解如何在Ignite中使用机器学习库。

在第二篇中主要讲解遗传算法,这个算法是今年早些时候(2018)捐赠给Apache基金会的。

遗传算法是一种通过模拟生物进化过程来解决优化问题的一种方法。 非常适合于以最优的方式检索大量复杂的数据集,在现实世界中,遗传算法的典型应用场景包括:

  • 汽车设计
  • 计算机游戏
  • 机器人技术
  • 金融投资
  • 物流配送

遗传算法中通常使用生物学术语。比如,一个种群染色体组成。染色体是解决问题的可能方法。染色体由基因组成。基因可以结合以获得新的染色体,等等。一个完整的词汇表可以在Apache Ignite 遗传算法文档中找到。

遗传算法中,有几个主要的操作,称为适应度计算交叉变异,染色体包含适应度得分,用于比较不同的解。结合基因产生新染色体的过程称为交叉。变异是染色体内某些基因被更新以产生新特性的过程,如图1所示: 遗传算法使用ComputeTask执行操作,并且注意图1和Ignite的计算网格之间的相似度,如图2所示: 在Ignite中,遗传算法是更大的机器学习库的一部分。

在图3中,可以看到遗传算法中各个操作的执行顺序: 在图3中会看到有一个终止步骤,这对整个过程至关重要。

通常的编程示例中,都会有一个“Hello World”应用,Ignite的遗传算法中,也有这样一个应用,下面就一步步看看这个应用,看看它是如何工作的。

"Hello World"示例

这个示例的目标是产生"HELLO WORLD"这样的输出,注意这里都是大写字母。

下面的部分会遵循图3中的步骤,通过一些小的代码片段来聚焦,完整的代码在GitHub上,这也是整个Ignite机器学习库的一部分。

初始化

首先,执行一些初始化操作:

ignite = Ignition.start("examples/config/example-ignite.xml");
gaConfig = new GAConfiguration();

在上面的代码中,可以通过GAConfiguration()来对遗传算法的行为进行配置。

下一步,需要定义一个基因池,如下所示:

List<Gene> genes = getGenePool();

"HELLO WORLD"这个目标短语由A-Z和空格字符组成,因此,将每个基因建模为字符,然后创建大小为27的基因池,然后像下面这样对基因池进行初始化:

private static List<Gene> getGenePool() {
   List<Gene> list = new ArrayList();

   char[] chars = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
      'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
      'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' '};

   for (int i = 0; i < chars.length; i++) {
      Gene gene = new Gene(new Character(chars[i]));
      list.add(gene);
   }
   return list;
}

之前已经提过,染色体是一个优化解,由若干基因组成。在本示例中,这个优化解是短语“HELLO WORLD”,它由11个基因组成,因此可以将染色体的长度设定为11,如下所示:

gaConfig.setChromosomeLength(11);

适应度计算

要比较各个不同的解然后找到最优解,需要为每个染色体确定一个适应度得分,下面的代码可以做到这一点:

public class HelloWorldFitnessFunction implements IFitnessFunction {
    private String targetString = "HELLO WORLD";

    public double evaluate(List<Gene> genes) {

        double matches = 0;

        for (int i = 0; i < genes.size(); i++) {
            if (((Character)(genes.get(i).getValue())).equals(targetString.charAt(i))) {
                matches = matches + 1;
            }
        }
        return matches;
    }
}

可以看到,目标染色体为“HELLO WORLD”,然后代码一个个基因进行检查,来确认其是否匹配目标值。

终止条件

本示例中,当染色体匹配"HELLO WORLD"时,就会发现已经找到了最优解,这时代码会检查这个条件,如下所示:

boolean isTerminate = true;

...

if (!(fittestChromosome.getFitnessScore() > 10)) {
   isTerminate = false;
}

return isTerminate;

交叉和变异

最后一步是种群的进化,如下所示:

Chromosome fittestChromosome = gaGrid.evolve();

运行遗传算法

最后,可以运行下代码,大概输出如下:

##########################################################################################
Generation: 255
Fittest is Chromosome Key: Chromosome [fitnessScore=11.0, id=131, genes=[8, 5, 12, 12, 15, 27, 23, 15, 18, 12, 4]]
Chromosome: Chromosome [fitnessScore=11.0, id=131, genes=[8, 5, 12, 12, 15, 27, 23, 15, 18, 12, 4]]
HELLO WORLD
Avg Chromosome Fitness: 5.668
##########################################################################################

Web控制台

也可以通过Ignite的Web控制台执行一些遗传算法的查询,怎么弄呢?可以通过命令行或者IDE启动一个集群节点,节点启动之后,启动Ignite的Web代理,图4中显示了Web代理正在运行: 下一步,使用一个Web浏览器接入http://console.gridgain.com,登录之后,转到Queries > Create new notebook,命名并且创建新的记事本之后,就有了一个执行SQL查询的接口,如图5所示: 在遗传算法的文档中提到:

通过添加自定义的SQL函数来改进遗传优化结果,遗传算法改进了知识的发现。结果集中的列是由单个遗传样本的染色体大小动态驱动的。

下面的SQL函数可以使用:

  • getSolutionsDesc():根据适应度得分降序获取优化解;
  • getSolutionsAsc():根据适应度得分升序获取优化解;
  • getSolutionById(key):通过染色体主键获取优化解。

可以尝试下下面的示例:

select * from "geneCache".getSolutionsDesc();

产生的输出如图6所示: 通过输出可以看出,第一个解最优,适应度得分为11。

总结

通过模拟生物进化的过程,遗传算法为解决一些复杂的问题提供了一个强大的机制,通过一个简单的示例,可以看到可以运行的遗传算法,如果想更进一步,具体的代码示例可以从Ignite的机器学习库获得。

© 著作权归作者所有

李玉珏

李玉珏

粉丝 387
博文 79
码字总数 149758
作品 0
沈阳
架构师
私信 提问
Apache Ignite 2.5.0 版本发布,千级节点伸缩性

Apache Ignite 2.5: 千级节点伸缩性 Apache Ignite的用户通常知道的两个关键点是-扩展性和性能。在很多分布式系统的整个生命周期中,通常会不停地改进性能,而对扩展性相关的改进次数,会比较...

李玉珏
2018/06/01
1K
10
内存数据组织 - Apache Ignite

1.Ignite是什么? Apache Ignite是一个以内存为中心的分布式数据库、缓存和处理平台,支持事务、分析以及流式负载,可以在PB级数据上享有内存级的性能。 1.1.Ignite定位 Ignite是不是内存数据...

匿名
2015/01/10
29K
8
在Ignite中使用线性回归算法

在本系列前面的文章中,简单介绍了一下Ignite的机器学习网格,下面会趁热打铁,结合一些示例,深入介绍Ignite支持的一些机器学习算法。 如果要找合适的数据集,会发现可用的有很多,但是对于...

李玉珏
2018/11/22
267
0
全面对比,深度解析 Ignite 与 Spark

经常有人拿 Ignite 和 Spark 进行比较,然后搞不清两者的区别和联系。Ignite 和 Spark,如果笼统归类,都可以归于内存计算平台,然而两者功能上虽然有交集,并且 Ignite 也会对 Spark 进行支...

编辑部的故事
2018/09/13
3.6K
6
Apache Ignite的Node.js客户端使用入门

介绍 Ignite原生提供了若干种主要编程语言的支持,最近,还通过瘦客户端技术对其它的编程语言提供了支持,其中在2.7版本中新增加的瘦客户端包括Python、PHP和Node.js。 瘦客户端具有如下的特...

李玉珏
02/13
267
0

没有更多内容

加载失败,请刷新页面

加载更多

DDD(十)--仓储

1、引言 DDD中的Repository(仓储):协调领域和数据映射层,利用类似与集合的接口来访问领域对象。——《领域驱动设计-软件核心复杂性应对之道》 仓储是DDD中产生的概念,也就是说,如果应...

MrYuZixian
19分钟前
8
0
Jenkins的多种迁移方法

说明 Jenkins有时需要进行迁移,主目录会发生改变,本文主要讲解如何更改主目录。由于jenkins安装方式的不同,主目录也不一样。 本测试环境:Centos7.6 X64。注意:在更改主目录之前,请一定...

Elson
20分钟前
8
0
好程序员web前端教程分享前端javascript练习题三

好程序员web前端教程分享前端javascript练习题三,cookie 一周内免登录 样式代码: <form action=""> 姓名:<input type="text" id="usename"/><br /> 密码:<input type="text" i="mima"/>......

好程序员官网
39分钟前
8
0
Table 信息转成pojo属性

import com.google.common.base.CaseFormat;import java.sql.*;/** * @author: liyhu * @date: 2019/11/22 */public class TableToPojo { static String url="jdbc:mys......

暗中观察
今天
10
0
Access数据库-C#操作类

//Access数据库-C# 操作类 代码using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Data.OleDb;using System.Data;namespace XXX{......

芳缘
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部