在本系列前面的文章中, 简单介绍了一下 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 www.trgj888.com/ 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)
当训练和测试数据准备好之后, 就可以写应用了, 本文的算法是:
读取训练数据和测试数据;
在 Ignite 中保存训练数据和测试数据;
使用训练数据拟合 k-NN 模型;
将模型应用于测试数据;
确定模型的准确性.
读取训练数据和测试数据
需要读取两个有 5 列的 CSV 文件, 一个是训练数据, 一个是测试数据, 5 列分别为:
萼片长度(cm)
萼片宽度(cm)
花瓣长度(cm)
花瓣宽度(cm)
花的种类(0:Iris Setosa,1:Iris Versicolour,2:Iris Virginica)
通过下面的代码, 可以从 CSV 文件中读取数据:
- private static void loadData(String fileName, IgniteCache<Integer, IrisObservation> cache)
- throws FileNotFoundException {
- Scanner scanner =www.mingcheng178.com/ new Scanner(new File(fileName));
- int cnt www.gcyL157.com= 0;
- while (scanner.hasNextLine()) {
- String row = scanner.nextLine();
- String[] cells = row.split(",");
- double[] features = new double[cells.length - 1];
- for (int i = 0;www.mhylpt.com i www.yigouyule2.cn<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 分类示例, 可以看到创建模型, 测试模型和确定准确性的简单性.
在机器学习系列的下一篇中, 将研究另一种机器学习算法. 敬请期待!
来源: http://www.bubuko.com/infodetail-2874280.html