文档章节

在Ignite中使用k-最近邻(k-NN)分类算法

李玉珏
 李玉珏
发布于 2018/11/28 16:53
字数 1276
阅读 315
收藏 4

在本系列前面的文章中,简单介绍了一下Ignite的线性回归算法,下面会尝试另一个机器学习算法,即k-最近邻(k-NN)分类。该算法基于对象k个最近邻中最常见的类来对对象进行分类,可用于确定类成员的关系。

一个适合k-NN分类的数据集是鸢尾花数据集,它可以很容易地通过UCI网站获得。

鸢尾花数据集由150个样本组成,来自3种不同种类的鸢尾花各有50朵(Iris Setosa, Iris Versicolour和Iris Virginica)。以下四个特征可供每个样本使用:

  • 萼片长度(cm)
  • 萼片宽度(cm)
  • 花瓣长度(cm)
  • 花瓣宽度(cm)

下面会创建一个模型,利用这四个特征区分不同的物种。

首先,要获取原始数据并将其拆分成训练数据(60%)和测试数据(40%)。然后再次使用Scikit-learn来执行这个任务,下面修改一下前一篇文章中使用的代码,如下:

from sklearn import datasets
import pandas as pd

# Load Iris dataset.
iris_dataset = datasets.load_iris()
x = iris_dataset.data
y = iris_dataset.target

# Split it into train and test subsets.
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.4, random_state=23)

# Save train set.
train_ds = pd.DataFrame(x_train, columns=iris_dataset.feature_names)
train_ds["TARGET"] = y_train
train_ds.to_csv("iris-train.csv", index=False, header=None)

# Save test set.
test_ds = pd.DataFrame(x_test, columns=iris_dataset.feature_names)
test_ds["TARGET"] = y_test
test_ds.to_csv("iris-test.csv", index=False, header=None)

当训练和测试数据准备好之后,就可以写应用了,本文的算法是:

  1. 读取训练数据和测试数据;
  2. 在Ignite中保存训练数据和测试数据;
  3. 使用训练数据拟合k-NN模型;
  4. 将模型应用于测试数据;
  5. 确定模型的准确性。

读取训练数据和测试数据

需要读取两个有5列的CSV文件,一个是训练数据,一个是测试数据,5列分别为:

  1. 萼片长度(cm)
  2. 萼片宽度(cm)
  3. 花瓣长度(cm)
  4. 花瓣宽度(cm)
  5. 花的种类(0:Iris Setosa,1:Iris Versicolour,2:Iris Virginica)

通过下面的代码,可以从CSV文件中读取数据:

private static void loadData(String fileName, IgniteCache<Integer, IrisObservation> cache)
        throws FileNotFoundException {

   Scanner scanner = new Scanner(new File(fileName));

   int cnt = 0;
   while (scanner.hasNextLine()) {
      String row = scanner.nextLine();
      String[] cells = row.split(",");
      double[] features = new double[cells.length - 1];

      for (int i = 0; i < cells.length - 1; i++)
         features[i] = Double.valueOf(cells[i]);
      double flowerClass = Double.valueOf(cells[cells.length - 1]);

      cache.put(cnt++, new IrisObservation(features, flowerClass));
   }
}

该代码简单地一行行的读取数据,然后对于每一行,使用CSV的分隔符拆分出字段,每个字段之后将转换成double类型并且存入Ignite。

将训练数据和测试数据存入Ignite

前面的代码将数据存入Ignite,要使用这个代码,首先要创建Ignite存储,如下:

IgniteCache<Integer, IrisObservation> trainData = getCache(ignite, "IRIS_TRAIN");
IgniteCache<Integer, IrisObservation> testData = getCache(ignite, "IRIS_TEST");
loadData("src/main/resources/iris-train.csv", trainData);
loadData("src/main/resources/iris-test.csv", testData);

getCache()的实现如下:

private static IgniteCache<Integer, IrisObservation> getCache(Ignite ignite, String cacheName) {

   CacheConfiguration<Integer, IrisObservation> cacheConfiguration = new CacheConfiguration<>();
   cacheConfiguration.setName(cacheName);
   cacheConfiguration.setAffinity(new RendezvousAffinityFunction(false, 10));

   IgniteCache<Integer, IrisObservation> cache = ignite.createCache(cacheConfiguration);

   return cache;
}

使用训练数据拟合k-NN分类模型

数据存储之后,可以像下面这样创建训练器:

KNNClassificationTrainer trainer = new KNNClassificationTrainer();

然后拟合训练数据,如下:

KNNClassificationModel mdl = trainer.fit(
        ignite,
        trainData,
        (k, v) -> v.getFeatures(),     
// Feature extractor.

        (k, v) -> v.getFlowerClass())  
// Label extractor.

        .withK(3)
        .withDistanceMeasure(new EuclideanDistance())
        .withStrategy(KNNStrategy.WEIGHTED);

Ignite将数据保存为键-值(K-V)格式,因此上面的代码使用了值部分,目标值是Flower类,特征在其它列中。将k的值设为3,代表3种。对于距离测量,可以有几个选择,如欧几里德、汉明或曼哈顿,在本例中使用欧几里德。最后要指定是使用SIMPLE算法还是使用WEIGHTED k-NN算法,在本例中使用WEIGHTED。

将模型应用于测试数据

下一步,就可以用训练好的分类模型测试测试数据了,可以这样做:

int amountOfErrors = 0;
int totalAmount = 0;

try (QueryCursor<Cache.Entry<Integer, IrisObservation>> cursor = testData.query(new ScanQuery<>())) {
   for (Cache.Entry<Integer, IrisObservation> testEntry : cursor) {
      IrisObservation observation = testEntry.getValue();

      double groundTruth = observation.getFlowerClass();
      double prediction = mdl.apply(new DenseLocalOnHeapVector(observation.getFeatures()));

      totalAmount++;
      if (groundTruth != prediction)
         amountOfErrors++;

      System.out.printf(">>> | %.0f\t\t\t | %.0f\t\t\t|\n", prediction, groundTruth);
   }

   System.out.println(">>> -----------------------------");

   System.out.println("\n>>> Absolute amount of errors " + amountOfErrors);
   System.out.printf("\n>>> Accuracy %.2f\n", (1 - amountOfErrors / (double) totalAmount));
}

确定模型的准确性

下面,就可以通过对测试数据中的真实分类和模型进行的分类进行对比,来确认模型的真确性。

代码运行之后,总结如下:

>>> Absolute amount of errors 2
>>> Accuracy 0.97

因此,Ignite能够将97%的测试数据正确地分类为3个不同的种类。

总结

Apache Ignite提供了一个机器学习算法库。通过k-NN分类示例,可以看到创建模型、测试模型和确定准确性的简单性。

在机器学习系列的下一篇中,将研究另一种机器学习算法。敬请期待!

© 著作权归作者所有

李玉珏

李玉珏

粉丝 387
博文 79
码字总数 149758
作品 0
沈阳
架构师
私信 提问
在Ignite中使用k-均值聚类算法

在本系列前面的文章中,简单介绍了一下Ignite的k-最近邻(k-NN)分类算法,下面会尝试另一个机器学习算法,即使用泰坦尼克数据集介绍k-均值聚类算法。正好,Kaggle提供了CSV格式的数据集,而要...

李玉珏
2018/12/03
1K
4
在Ignite中使用线性回归算法

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

李玉珏
2018/11/22
267
0
Apache Ignite 2.1.0 版本发布,全新的持久化存储

社区宣布,Apache Ignite 2.1.0版本正式发布。 这个版本包括了一个捐赠来的全新特性-Ignite持久化存储,他具有完全的内存持久化架构,使得应用同时具有基于内存的高性能以及基于磁盘的持久化...

李玉珏
2017/07/28
1K
6
Apache Ignite 2.4.0 发布,内存数据组织平台

Apache Ignite 2.4.0 发布了。更新内容如下: Apache Ignite 发行注记 =========================== Apache Ignite In-Memory Data Fabric 2.4 --------------------------------------- Ig......

李玉珏
2018/03/12
1K
4
Apache Ignite 2.5.0 版本发布,千级节点伸缩性

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

李玉珏
2018/06/01
1K
10

没有更多内容

加载失败,请刷新页面

加载更多

DDD(十)--仓储

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

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

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

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

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

好程序员官网
45分钟前
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

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部