在Ignite中使用k-最近鄰(k-NN)分類算法
在本系列前面的文章中,簡單介紹了一下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分類示例,可以看到創建模型、測試模型和確定準確性的簡單性。
在機器學習系列的下一篇中,將研究另一種機器學習算法。敬請期待!
在Ignite中使用k-最近鄰(k-NN)分類算法