偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

用Scikit-Learn構建K-近鄰算法,分類MNIST數(shù)據(jù)集

開發(fā) 開發(fā)工具 算法
本篇教程將帶你使用 Scikit-Learn 構建 K 近鄰算法,并應用于 MNIST 數(shù)據(jù)集。然后,作者將帶你構建自己的 K-NN 算法,開發(fā)出比 Scikit-Learn K-NN 更準更快的算法。

K 近鄰算法,簡稱 K-NN。在如今深度學習盛行的時代,這個經典的機器學習算法經常被輕視。本篇教程將帶你使用 Scikit-Learn 構建 K 近鄰算法,并應用于 MNIST 數(shù)據(jù)集。然后,作者將帶你構建自己的 K-NN 算法,開發(fā)出比 Scikit-Learn K-NN 更準更快的算法。

一、K 近鄰分類模型

K 近鄰分類模型

K 近鄰算法是一種容易實現(xiàn)的監(jiān)督機器學習算法,并且其分類性能的魯棒性還不錯。K-NN ***的優(yōu)點之一就是它是一個惰性算法,即該模型無須訓練就可以對數(shù)據(jù)進行分類,而不像其他需要訓練的 ML 算法,如 SVM、回歸和多層感知機。

K-NN 如何工作

為了對給定的數(shù)據(jù)點 p 進行分類,K-NN 模型首先使用某個距離度量將 p 與其數(shù)據(jù)庫中其它點進行比較。

距離度量就是類似歐幾里得距離之類的標準,以兩個點為輸入并返回這兩個點之間距離的簡單函數(shù)。

因此,可以假設距離較小的兩個點比距離較大的兩個點相似度更高。這是 K-NN 的核心思想。

該過程將返回一個無序數(shù)組,其中數(shù)組中的每一項都表示 p 與模型數(shù)據(jù)庫中 n 個數(shù)據(jù)點之間的距離。所以返回數(shù)組的大小為 n。

K 近鄰的 K 的含義是:k 是一個任意值(通常在 3-11 之間),表示模型在對 p 分類時應該考慮多少個最相似的點。然后模型將記錄這 k 個最相似的值,并使用投票算法來決定 p 屬于哪一類,如下圖所示。

K-NN 模型

上圖中的 K-NN 模型的 k 值為 3,箭頭指向的中心點為 p,算法將對這個點進行分類。

如你所見,圓圈中的三個點是與 p 最接近或最相似的三個點。因此,使用簡單的投票算法,p 將被歸為「白色」,因為白色在 k 個最相似值中占大多數(shù)。

酷炫!但令人驚訝的是,這個簡單的算法可以在某些情況下實現(xiàn)不俗的結果,并且可以應用于各種各樣的問題,我們將在下面介紹。

二、在 Scikit-Learn 中實現(xiàn) K-NN 算法用來分類 MNIST 圖像

1. 數(shù)據(jù)

對于這個例子,我們將使用常見的 MNIST 數(shù)據(jù)集。MNIST 數(shù)據(jù)集是機器學習中最常用的數(shù)據(jù)集之一,因為它很容易實現(xiàn),而且是驗證我們模型的可靠方法。

 數(shù)據(jù)

MNIST 是一組包含 70,000 個手寫數(shù)字 0-9 的數(shù)據(jù)集。任意兩個手寫數(shù)字都不相同,有些可能很難正確分類。

2. 算法

我們從 Scikit-Learn 的 Python 庫的 KNeighborsClassifier() 函數(shù)入手。這個函數(shù)有很多參數(shù),但在這個例子中我們只需用少量幾個參數(shù)。具體來說,我們只會傳遞 n_neighbors 參數(shù)的值(就是 k 值啦)。

weights 參數(shù)給出了模型使用的投票算法的類型,其中默認值是 uniform。這意味著在對 p 進行分類時,k 個點中的每一個的權重都一樣。algorithm 參數(shù)也將使用默認值 auto,因為我們希望 Scikit-Learn 自動找到對 MNIST 數(shù)據(jù)進行分類的***算法。

以下是一個用 Scikit-Learn 構建 K-NN 分類器的 Jupyter Notebook:Scikit-Learn 實現(xiàn)的用于 MNIST 的 K 近鄰算法

Notebook 地址:https://gist.github.com/samgrassi01/82d0e5f89daac3e65531a6ef497cc129#file-skl-knn-ipynb

我們通過導入所需的庫直接開始。

  1. In [1]: 
  2. import numpy as np 
  3.  
  4. from sklearn import datasets, model_selection 
  5. from sklearn.neighbors import KNeighborsClassifier 
  6. from sklearn.metrics import classification_report 
  7.  
  8. mnist = datasets.fetch_mldata('MNIST original') 
  9. data, target = mnist.data, mnist.target 
  10.  
  11. # make sure everything was correctly imported 
  12. data.shape, target.shape 
  13. Out[1]: 
  14. ((70000, 784), (70000,)) 

(1) 構建數(shù)據(jù)集

我們通過制作不同的數(shù)據(jù)集來構建 K-NN 模型。我們將創(chuàng)建一個可以獲取特定大小數(shù)據(jù)集、返回數(shù)據(jù)集大小的函數(shù)。

  1. In [2]: 
  2. # make an array of indices the size of MNIST to use for making the data sets. 
  3. # This array is in random order, so we can use it to scramble up the MNIST data 
  4. indx = np.random.choice(len(target), 70000, replace=False
  5.  
  6. # method for building datasets to test with 
  7. def mk_dataset(size): 
  8.     """makes a dataset of size "size", and returns that datasets images and targets 
  9.     This is used to make the dataset that will be stored by a model and used in  
  10.     experimenting with different stored dataset sizes 
  11.     """ 
  12.     train_img = [data[i] for i in indx[:size]] 
  13.     train_img = np.array(train_img) 
  14.     train_target = [target[i] for i in indx[:size]] 
  15.     train_target = np.array(train_target) 

不錯?,F(xiàn)在我們將使用這個函數(shù)來構建兩個不同大小的數(shù)據(jù)集,來看看模型在不同數(shù)據(jù)量上的分類性能怎么樣。

提示:制作較小的數(shù)據(jù)集時,你仍然可以進行分類,但模型畢竟少了一些數(shù)據(jù),這可能會導致分類錯誤。

  1. In [3]: 
  2. # lets make a dataset of size 50,000, meaning the model will have 50,000 data points to compare each  
  3. # new point it is to classify to 
  4. fifty_x, fifty_y = mk_dataset(50000) 
  5. fifty_x.shape, fifty_y.shape 
  6. Out[3]: 
  7. ((50000, 784), (50000,)) 
  8. In [4]: 
  9. # lets make one more of size 20,000 and see how classification accuracy decreases when we use that one 
  10. twenty_x, twenty_y = mk_dataset(20000) 
  11. twenty_x.shape, twenty_y.shape 
  12. Out[4]: 
  13. ((20000, 784), (20000,)) 

注意這些數(shù)據(jù)是如何為模型匹配標簽的。模型需要這些標簽來理解每一個點代表什么,因此可以把我們要分類的點放在一個特定的類中,而不是說「這是與待分類點最相似的類」。

現(xiàn)在我們將構建一個大小為 10000 的測試集。

  1. In [5]: 
  2. # build model testing dataset 
  3. test_img = [data[i] for i in indx[60000:70000]] 
  4. test_img1 = np.array(test_img) 
  5. test_target = [target[i] for i in indx[60000:70000]] 
  6. test_target1 = np.array(test_target) 
  7. test_img1.shape, test_target1.shape 
  8. Out[5]: 
  9. ((10000, 784), (10000,)) 

不錯!現(xiàn)在我們已經完成了所有的數(shù)據(jù)處理,可以開始搭建 K-NN 模型了!

(2) 構建模型

我們首先將 Scikit-Learn K-NN 模型放在函數(shù)中,以便可以輕松調用它并對其進行調整。

  1. In [6]: 
  2. def skl_knn(k, test_data, test_target, stored_data, stored_target): 
  3.     """k: number of neighbors to use in classication 
  4.     test_data: the data/targets used to test the classifier 
  5.     stored_data: the data/targets used to classify the test_data 
  6.     """ 
  7.  
  8.     classifier = KNeighborsClassifier(n_neighbors=k)   
  9.     classifier.fit(stored_data, stored_target) 
  10.  
  11.     y_pred = classifier.predict(test_data)  
  12.  
  13.     print(classification_report(test_target, y_pred)) 

(3) 測試

現(xiàn)在我們看看這個模型在兩個不同的測試集上的運行效果。

  1. In [7]: 
  2. %%time 
  3. # stored data set size of 50,000 
  4. skl_knn(5, test_img1, test_target1, fifty_x, fifty_y) 

  1. In [8]: 
  2. %%time 
  3. # stored data set size of 20,000 
  4. skl_knn(5, test_img1, test_target1, twenty_x, twenty_y) 

 

可以的!我們的模型與人眼識別差不多!如你所見,當模型有更多的數(shù)據(jù)可以使用時(50,000 而不是 20,000 個點),它的性能會更好。更加引人注目的是,它非常簡單,并且能以人類水平來獲取不同圖像之間的復雜關系。更多的細節(jié)分析請訪問這個 GitHub repo:

https://github.com/samgrassi01/Cosine-Similarity-Classifier。

厲害了!我們使用 Scikit-Learn 構建了一個非常簡單的 K 近鄰模型,該模型在 MNIST 數(shù)據(jù)集上表現(xiàn)非凡。

不足之處?分類這些點需要很長時間(兩個數(shù)據(jù)集分別耗時 8 分鐘和 4 分鐘),諷刺的是,K-NN 仍然是最快的分類方法之一。我們必須有一個更快的方法。

三、構建一個更快的模型

大多數(shù) K-NN 模型使用歐幾里德距離或曼哈頓距離作為 go-to 距離度量。這些指標非常簡單,而且在各種各樣的情況中都表現(xiàn)不錯。

還有一個很少用到的距離標準度量是余弦相似度。余弦相似度通常不是 go-to 距離度量標準,這是因為它違反了三角不等式,而且對負數(shù)無效。但是,余弦相似度對于 MNIST 來說很***。它速度快、算法簡單,而且比 MNIST 中應用其他距離度量的準確率稍高一些。

但是,為了得到***性能,我們需要自己編寫 K-NN 模型。然后,我們應該能得到比 Scikit-Learn 模型更高的性能,甚至能得到更高的準確度。讓我們看看以下建立的 K-NN 模型的 Notebook 吧:

構建一個更快的 KNN 分類器

Notebook 地址:

https://gist.github.com/samgrassi01/15a1fe53dcde8813eed9367b103676b2#file-cos-knn-ipynb

在這個 notebook 中,我們將構建一個簡單的 K-NN 模型,該模型使用余弦相似度作為距離度量對 MNIST 圖像進行分類,試圖找到更快或更加準確的模型。

首先,需要導入所需的庫,然后構建與 Scikit-Learn K-NN notebook 相同的數(shù)據(jù)集。

  1. In [1]: 
  2. import numpy as np 
  3. import heapq 
  4. from collections import Counter 
  5. from sklearn.metrics.pairwise import cosine_similarity 
  6. from sklearn import datasets, model_selection 
  7. from sklearn.metrics import classification_report 
  8.  
  9. mnist = datasets.fetch_mldata('MNIST original') 
  10. data, target = mnist.data, mnist.target 
  11.  
  12. # make sure everything was correctly imported 
  13. data.shape, target.shape 
  14. Out[1]: 
  15. ((70000, 784), (70000,)) 

使用與 Scikit-Learn K-NN notebook 相同的方法,設置完全相同的數(shù)據(jù)集。

  1. In [2]: 
  2. # make an array of indices the size of MNIST to use for making the data sets. 
  3. # This array is in random order, so we can use it to scramble up the MNIST data 
  4. indx = np.random.choice(len(target), 70000, replace=False
  5.  
  6. # method for building datasets to test with 
  7. def mk_dataset(size): 
  8.     """makes a dataset of size "size", and returns that datasets images and targets 
  9.     This is used to make the dataset that will be stored by a model and used in  
  10.     experimenting with different stored dataset sizes 
  11.     """ 
  12.     train_img = [data[i] for i in indx[:size]] 
  13.     train_img = np.array(train_img) 
  14.     train_target = [target[i] for i in indx[:size]] 
  15.     train_target = np.array(train_target) 
  16.  
  17.     return train_img, train_target 
  18. In [3]: 
  19. # lets make a dataset of size 50,000, meaning the model will have 50,000 data points to compare each  
  20. # new point it is to classify to 
  21. fifty_x, fifty_y = mk_dataset(50000) 
  22. fifty_x.shape, fifty_y.shape 
  23. Out[3]: 
  24. ((50000, 784), (50000,)) 
  25. In [4]: 
  26. # lets make one more of size 20,000 and see how classification accuracy decreases when we use that one 
  27. twenty_x, twenty_y = mk_dataset(20000) 
  28. twenty_x.shape, twenty_y.shape 
  29. Out[4]: 
  30. ((20000, 784), (20000,)) 
  31. In [5]: 
  32. # build model testing dataset 
  33. test_img = [data[i] for i in indx[60000:70000]] 
  34. test_img1 = np.array(test_img) 
  35. test_target = [target[i] for i in indx[60000:70000]] 
  36. test_target1 = np.array(test_target) 
  37. test_img1.shape, test_target1.shape 
  38. Out[5]: 
  39. ((10000, 784), (10000,)) 

1. . 構建模型

下面,我們創(chuàng)建函數(shù) cos_knn(),作為用于 MNIST 數(shù)據(jù)集的分類器。你可以利用函數(shù)的注釋了解其工作原理。

  1. In [6]: 
  2. def cos_knn(k, test_data, test_target, stored_data, stored_target): 
  3.     """k: number of neighbors to use for voting 
  4.     test_data: a set of unobserved images to classify 
  5.     test_target: the labels for the test_data (for calculating accuracy) 
  6.     stored_data: the images already observed and available to the model 
  7.     stored_target: labels for stored_data 
  8.     """ 
  9.  
  10.     # find cosine similarity for every point in test_data between every other point in stored_data 
  11.     cosim = cosine_similarity(test_data, stored_data) 
  12.  
  13.     # get top k indices of images in stored_data that are most similar to any given test_data point 
  14.     top = [(heapq.nlargest((k), range(len(i)), i.take)) for i in cosim] 
  15.     # convert indices to numbers using stored target values 
  16.     top = [[stored_target[j] for j in i[:k]] for i in top] 
  17.  
  18.     # vote, and return prediction for every image in test_data 
  19.     pred = [max(set(i), key=i.count) for i in top] 
  20.     pred = np.array(pred) 
  21.  
  22.     # print table giving classifier accuracy using test_target 
  23.     print(classification_report(test_target, pred)) 

2. 測試模型

現(xiàn)在,就像 Scikit-Learn K-NN 模型一樣,我們對 cos_knn() 模型在兩個數(shù)據(jù)集上分別測試,并看看它的性能如何。

  1. In [7]: 
  2. %%time 
  3. # stored data set size of 50,000 
  4. cos_knn(5, test_img1, test_target1, fifty_x, fifty_y) 

  1. In [8]: 
  2. %%time 
  3. # stored data set size of 20,000 
  4. cos_knn(5, test_img1, test_target1, twenty_x, twenty_y) 

 

太棒了!余弦相似度模型性能超過了 Scikit-Learn K-NN!值得一提的是,該模型的分類速度和準確率都優(yōu)于 Scikit-Learn K-NN(其中速度獲得了很大提升),而模型卻非常簡單!

為了進一步分析模型的工作原理,同時了解該模型為何在許多不同情況下比 Scikit-Learn K-NN 模型要性能更優(yōu),請參閱這個 GitHub repo:

https://github.com/samgrassi01/Cosine-Similarity-Classifier。

正如 notebook 所示,該 K-NN 模型在分類速度和準確率方面都勝過了 Scikit-Learn K-NN,其中速度獲得了大幅提升,而在一個數(shù)據(jù)集上的準確率提高了 1%。既然如此,我們可以在實踐中繼續(xù)使用這個模型了。

四、結論

首先,我們知道了 K-NN 的工作機制,以及如何輕松地實現(xiàn)它。但最重要的是,我們發(fā)現(xiàn),始終考慮需要解決的問題以及解決問題的工具非常重要。有時候,在解決問題的過程中,***花一些時間來實踐——當然,也需要建立自己的模型。正如 notebook 中所展示的那樣,它可以帶來極大的益處:我們第二個專有模型獲得了 1.5 - 2 倍的加速,節(jié)省了很多時間。

原文鏈接:

https://towardsdatascience.com/building-improving-a-k-nearest-neighbors-algorithm-in-python-3b6b5320d2f8

【本文是51CTO專欄機構“機器之心”的原創(chuàng)譯文,微信公眾號“機器之心( id: almosthuman2014)”】

戳這里,看該作者更多好文

責任編輯:趙寧寧 來源: 51CTO專欄
相關推薦

2018-09-06 08:00:00

深度學習TensorFlowPython

2018-10-15 09:10:09

Python編程語言數(shù)據(jù)科學

2015-07-22 16:16:47

PythonScikit-Lear機器學習

2023-05-26 12:45:22

predict?方法數(shù)據(jù)

2021-05-12 09:58:09

PythonXGBoostscikit-lear

2022-04-15 10:11:03

機器學習scikit-lea

2023-02-13 15:00:13

機器學習scikit-leaPyTorch

2017-07-20 10:23:20

pythonscikit-lear垃圾郵件過濾

2017-11-03 12:57:06

機器學習文本數(shù)據(jù)Python

2023-11-13 18:05:53

處理數(shù)據(jù)搭建模型

2018-05-15 08:27:20

Scikit-lear機器學習Python

2022-04-26 10:27:52

機器算法KNN數(shù)據(jù)

2021-06-09 16:00:05

近鄰算法數(shù)據(jù)

2017-01-05 10:07:33

大數(shù)據(jù)TheanoCaffe

2017-04-21 09:59:11

開源機器學習框架

2024-02-01 09:43:32

模型人工智能

2016-12-18 15:03:57

Python Scikit Lea數(shù)據(jù)

2016-12-20 16:07:13

Python數(shù)據(jù)預處理

2023-07-27 15:38:52

數(shù)據(jù)集

2017-10-10 14:20:11

隨機森林分類算法
點贊
收藏

51CTO技術棧公眾號