在本系列前面的文章中,简单介绍了一下Ignite的线性回归算法,下面会尝试另外一个机器学习算法,即k-最近邻(k-NN)分类。该算法基于对象k个最近邻中最多见的类来对对象进行分类,可用于肯定类成员的关系。java
一个适合k-NN分类的数据集是鸢尾花数据集,它能够很容易地经过UCI网站得到。python
鸢尾花数据集由150个样本组成,来自3种不一样种类的鸢尾花各有50朵(Iris Setosa, Iris Versicolour和Iris Virginica)。如下四个特征可供每一个样本使用:算法
下面会建立一个模型,利用这四个特征区分不一样的物种。app
首先,要获取原始数据并将其拆分红训练数据(60%)和测试数据(40%)。而后再次使用Scikit-learn来执行这个任务,下面修改一下前一篇文章中使用的代码,以下:dom
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)
当训练和测试数据准备好以后,就能够写应用了,本文的算法是:机器学习
须要读取两个有5列的CSV文件,一个是训练数据,一个是测试数据,5列分别为:ide
经过下面的代码,能够从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存储,以下:网站
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; }
数据存储以后,能够像下面这样建立训练器:
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分类示例,能够看到建立模型、测试模型和肯定准确性的简单性。
在机器学习系列的下一篇中,将研究另外一种机器学习算法。敬请期待!