1. 程式人生 > >在Ignite中使用k-最近鄰(k-NN)分類演算法

在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分類示例,可以看到建立模型、測試模型和確定準確性的簡單性。
  
  在機器學習系列的下一篇中,將研究另一種機器學習演算法。敬請期待!