導航:首頁 > 源碼編譯 > 基於數據挖掘的k近鄰演算法

基於數據挖掘的k近鄰演算法

發布時間:2023-07-22 13:34:30

A. K-近鄰演算法簡介

1.K-近鄰(KNearestNeighbor,KNN)演算法簡介 :對於一個未知的樣本,我們可以根據離它最近的k個樣本的類別來判斷它的類別。

以下圖為例,對於一個未知樣本綠色小圓,我們可以選取離它最近的3的樣本,其中包含了2個紅色三角形,1個藍色正方形,那麼我們可以判斷綠色小圓屬於紅色三角形這一類。
我們也可以選取離它最近的5個樣本,其中包含了3個藍色正方形,2個紅色三角形,那麼我們可以判斷綠色小圓屬於藍色正方形這一類。

3.API文檔

下面我們來對KNN演算法中的參數項做一個解釋說明:

'n_neighbors':選取的參考對象的個數(鄰居個數),默認值為5,也可以自己指定數值,但不是n_neighbors的值越大分類效果越好,最佳值需要我們做一個驗證。
'weights': 距離的權重參數,默認uniform。
'uniform': 均勻的權重,所有的點在每一個類別中的權重是一樣的。簡單的說,就是每個點的重要性都是一樣的。
'distance':權重與距離的倒數成正比,距離近的點重要性更高,對於結果的影響也更大。
'algorithm':運算方法,默認auto。
'auto':根絕模型fit的數據自動選擇最合適的運算方法。
'ball_tree':樹模型演算法BallTree
'kd_tree':樹模型演算法KDTree
'brute':暴力演算法
'leaf_size':葉子的尺寸,默認30。只有當algorithm = 'ball_tree' or 'kd_tree',這個參數需要設定。
'p':閔可斯基距離,當p = 1時,選擇曼哈頓距離;當p = 2時,選擇歐式距離。
n_jobs:使用計算機處理器數目,默認為1。當n=-1時,使用所有的處理器進行運算。

4.應用案例演示
下面以Sklearn庫中自帶的數據集--手寫數字識別數據集為例,來測試下kNN演算法。上一章,我們簡單的介紹了機器學習的一般步驟:載入數據集 - 訓練模型 - 結果預測 - 保存模型。這一章我們還是按照這個步驟來執行。
[手寫數字識別數據集] https://scikit-learn.org/stable/moles/generated/sklearn.datasets.load_digits.html#sklearn.datasets.load_digits

5.模型的方法
每一種模型都有一些它獨有的屬性方法(模型的技能,能做些什麼事),下面我們來了解下knn演算法常用的的屬性方法。

6.knn演算法的優缺點
優點:
簡單,效果還不錯,適合多分類問題
缺點:
效率低(因為要計算預測樣本距離每個樣本點的距離,然後排序),效率會隨著樣本量的增加而降低。

B. K-近鄰演算法(KNN)

簡單地說,K-近鄰演算法採用測量不同特徵值之間的距離方法進行分類。

歐氏距離是最常見的距離度量,衡量的是多維空間中各個點之間的絕對距離。公式如下:

身高、體重、鞋子尺碼數據對應性別

導包,機器學習的演算法KNN、數據鳶尾花

獲取訓練樣本 datasets.load_iris()

畫圖研究前兩個特徵和分類之間的關系(二維散點圖只能展示兩個維度)

第二步預測數據:所預測的數據,自己創造,就是上面所顯示圖片的背景點

生成預測數據

對數據進行預測

ocr 光學字元識別(Optical Character Recognition) 我們先做一個基礎班:識別數字

C. k近鄰演算法中關鍵的要素是

k近鄰演算法中關鍵的要素是:k值的選取、鄰居距離的度量和分類決策的制訂。

1.k值的選取:

k近鄰演算法優點很明顯,簡單易用,可解釋性強,但也有其不足之處。例如,「多數表決」會在類別分布偏斜時浮現缺陷。也就是說,k值的選取非常重要,出現頻率較多的樣本將會主導測試點的預測結果。

3.分類決策的制訂:

本質上,分類器就是一個由特徵向量,到預測類別的映射函數。k近鄰演算法的分類流程大致如下三步走:(1)計算待測試樣本與訓練集合中每一個樣本的歐式距離;(2)對每一個距離從小到大排序;(3)選擇前k個距離最短的樣本,分類任務採用「少數服從多數」的表決規則。回歸任務則可採用k個近鄰的平均值舉茄作為預測值。

D. 使用Node.js如何實現K最近鄰分類演算法

源於數據挖掘的一個作業, 這里用Node.js技術來實現一下這個機器學習中最簡單的演算法之一k-nearest-neighbor演算法(k最近鄰分類法)。
k-nearest-neighbor-classifier
還是先嚴謹的介紹下。急切學習法(eager learner)是在接受待分類的新元組之前就構造了分類模型,學習後的模型已經就緒,急著對未知的元組進行分類,所以稱為急切學習法,諸如決策樹歸納,貝葉斯分類等都是急切學習法的例子。惰性學習法(lazy learner)正好與其相反,直到給定一個待接受分類的新元組之後,才開始根據訓練元組構建分類模型,在此之前只是存儲著訓練元組,所以稱為惰性學習法,惰性學習法在分類進行時做更多的工作。
本文的knn演算法就是一種惰性學習法,它被廣泛應用於模式識別。knn基於類比學習,將未知的新元組與訓練元組進行對比,搜索模式空間,找出最接近未知元組的k個訓練元組,這里的k即是knn中的k。這k個訓練元祖就是待預測元組的k個最近鄰。
balabala了這么多,是不是某些同學想大喊一聲..speak Chinese! 還是來通俗的解釋下,然後再來看上面的理論應該會明白很多。小時候媽媽會指著各種各樣的東西教我們,這是小鴨子,這個紅的是蘋果等等,那我們哼哧哼哧的看著應答著,多次被教後再看到的時候我們自己就能認出來這些事物了。主要是因為我們在腦海像給這個蘋果貼了很多標簽一樣,不只是顏色這一個標簽,可能還有蘋果的形狀大小等等。這些標簽讓我們看到蘋果的時候不會誤認為是橘子。其實這些標簽就對應於機器學習中的特徵這一重要概念,而訓練我們識別的過程就對應於泛化這一概念。一台iphone戴了一個殼或者屏幕上有一道劃痕,我們還是能認得出來它,這對於我們人來說非常簡單,但蠢計算機就不知道怎麼做了,需要我們好好調教它,當然也不能過度調教2333,過度調教它要把其他手機也認成iphone那就不好了,其實這就叫過度泛化。
所以特徵就是提取對象的信息,泛化就是學習到隱含在這些特徵背後的規律,並對新的輸入給出合理的判斷。
我們可以看上圖,綠色的圓代表未知樣本,我們選取距離其最近的k個幾何圖形,這k個幾何圖形就是未知類型樣本的鄰居,如果k=3,我們可以看到有兩個紅色的三角形,有一個藍色的三正方形,由於紅色三角形所佔比例高,所以我們可以判斷未知樣本類型為紅色三角形。擴展到一般情況時,這里的距離就是我們根據樣本的特徵所計算出來的數值,再找出距離未知類型樣本最近的K個樣本,即可預測樣本類型。那麼求距離其實不同情況適合不同的方法,我們這里採用歐式距離。
綜上所述knn分類的關鍵點就是k的選取和距離的計算。
2. 實現
我的數據是一個xls文件,那麼我去npm搜了一下選了一個叫node-xlrd的包直接拿來用。
// node.js用來讀取xls文件的包
var xls = require('node-xlrd');
然後直接看文檔實例即可,把數據解析後插入到自己的數據結構里。
var data = [];// 將文件中的數據映射到樣本的屬性var map = ['a','b','c','d','e','f','g','h','i','j','k'];// 讀取文件
xls.open('data.xls', function(err,bk){
if(err) {console.log(err.name, err.message); return;}
var shtCount = bk.sheet.count;
for(var sIdx = 0; sIdx < shtCount; sIdx++ ){
var sht = bk.sheets[sIdx],
rCount = sht.row.count,
cCount = sht.column.count;
for(var rIdx = 0; rIdx < rCount; rIdx++){
var item = {};
for(var cIdx = 0; cIdx < cCount; cIdx++){
item[map[cIdx]] = sht.cell(rIdx,cIdx);
}
data.push(item);
}
}
// 等文件讀取完畢後 執行測試
run();
});
然後定義一個構造函數Sample表示一個樣本,這里是把剛生成的數據結構里的對象傳入,生成一個新的樣本。
// Sample表示一個樣本
var Sample = function (object) {
// 把傳過來的對象上的屬性克隆到新創建的樣本上
for (var key in object)
{
// 檢驗屬性是否屬於對象自身
if (object.hasOwnProperty(key)) {
this[key] = object[key];
}
}
}
再定義一個樣本集的構造函數
// SampleSet管理所有樣本 參數k表示KNN中的kvar SampleSet = function(k) {
this.samples = [];
this.k = k;
};
// 將樣本加入樣本數組
SampleSet.prototype.add = function(sample) {
this.samples.push(sample);
}
然後我們會在樣本的原型上定義很多方法,這樣每個樣本都可以用這些方法。
// 計算樣本間距離 採用歐式距離
Sample.prototype.measureDistances = function(a, b, c, d, e, f, g, h, i, j, k) {
for (var i in this.neighbors)
{
var neighbor = this.neighbors[i];
var a = neighbor.a - this.a;
var b = neighbor.b - this.b;
var c = neighbor.c - this.c;
var d = neighbor.d - this.d;
var e = neighbor.e - this.e;
var f = neighbor.f - this.f;
var g = neighbor.g - this.g;
var h = neighbor.h - this.h;
var i = neighbor.i - this.i;
var j = neighbor.j - this.j;
var k = neighbor.k - this.k;
// 計算歐式距離
neighbor.distance = Math.sqrt(a*a + b*b + c*c + d*d + e*e + f*f + g*g + h*h + i*i + j*j + k*k);
}
};
// 將鄰居樣本根據與預測樣本間距離排序
Sample.prototype.sortByDistance = function() {
this.neighbors.sort(function (a, b) {
return a.distance - b.distance;
});
};
// 判斷被預測樣本類別
Sample.prototype.guessType = function(k) {
// 有兩種類別 1和-1
var types = { '1': 0, '-1': 0 };
// 根據k值截取鄰居裡面前k個
for (var i in this.neighbors.slice(0, k))
{
var neighbor = this.neighbors[i];
types[neighbor.trueType] += 1;
}
// 判斷鄰居里哪個樣本類型多
if(types['1']>types['-1']){
this.type = '1';
} else {
this.type = '-1';
}
}
注意到我這里的數據有a-k共11個屬性,樣本有1和-1兩種類型,使用truetype和type來預測樣本類型和對比判斷是否分類成功。
最後是樣本集的原型上定義一個方法,該方法可以在整個樣本集里尋找未知類型的樣本,並生成他們的鄰居集,調用未知樣本原型上的方法來計算鄰居到它的距離,把所有鄰居按距離排序,最後猜測類型。
// 構建總樣本數組,包含未知類型樣本
SampleSet.prototype.determineUnknown = function() {

for (var i in this.samples)
{
// 如果發現沒有類型的樣本
if ( ! this.samples[i].type)
{
// 初始化未知樣本的鄰居
this.samples[i].neighbors = [];
// 生成鄰居集
for (var j in this.samples)
{
// 如果碰到未知樣本 跳過
if ( ! this.samples[j].type)
continue;
this.samples[i].neighbors.push( new Sample(this.samples[j]) );
}
// 計算所有鄰居與預測樣本的距離
this.samples[i].measureDistances(this.a, this.b, this.c, this.d, this.e, this.f, this.g, this.h, this.k);
// 把所有鄰居按距離排序
this.samples[i].sortByDistance();
// 猜測預測樣本類型
this.samples[i].guessType(this.k);
}
}
};
最後分別計算10倍交叉驗證和留一法交叉驗證的精度。
留一法就是每次只留下一個樣本做測試集,其它樣本做訓練集。
K倍交叉驗證將所有樣本分成K份,一般均分。取一份作為測試樣本,剩餘K-1份作為訓練樣本。這個過程重復K次,最後的平均測試結果可以衡量模型的性能。
k倍驗證時定義了個方法先把數組打亂隨機擺放。
// helper函數 將數組里的元素隨機擺放
function ruffle(array) {
array.sort(function (a, b) {
return Math.random() - 0.5;
})
}
剩餘測試代碼好寫,這里就不貼了。
測試結果為
用餘弦距離等計算方式可能精度會更高。
3. 總結
knn演算法非常簡單,但卻能在很多關鍵的地方發揮作用並且效果非常好。缺點就是進行分類時要掃描所有訓練樣本得到距離,訓練集大的話會很慢。
可以用這個最簡單的分類演算法來入高大上的ML的門,會有點小小的成就感。

E. K-近鄰演算法(K-NN)

給定一個訓練數據集,對於新的輸入實例, 根據這個實例最近的 k 個實例所屬的類別來決定其屬於哪一類 。所以相對於其它機器學習模型和演算法,k 近鄰總體上而言是一種非常簡單的方法。

找到與該實例最近鄰的實例,這里就涉及到如何找到,即在特徵向量空間中,我們要採取 何種方式來對距離進行度量

距離的度量用在 k 近鄰中我們也可以稱之為 相似性度量 ,即特徵空間中兩個實例點相似程度的反映。在機器學習中,常用的距離度量方式包括歐式距離、曼哈頓距離、餘弦距離以及切比雪夫距離等。 在 k 近鄰演算法中常用的距離度量方式是歐式距離,也即 L2 距離, L2 距離計算公式如下:

一般而言,k 值的大小對分類結果有著重大的影響。 當選擇的 k 值較小的情況下,就相當於用較小的鄰域中的訓練實例進行預測,只有當與輸入實例較近的訓練實例才會對預測結果起作用。但與此同時預測結果會對實例點非常敏感,分類器抗噪能力較差,因而容易產生過擬合 ,所以一般而言,k 值的選擇不宜過小。但如果選擇較大的 k 值,就相當於在用較大鄰域中的悶鄭握訓練實例進行預測,但相應的分類誤差也會增大,模型整體變得簡單,會產生一定程度的欠擬合。所以一般而言,我們需要 採用交叉驗證的方式來選擇合適的 k 值

k 個實例的多數屬於哪叢褲個類,明顯是多數表決的歸類規則。當然還可能使用其他規則,所以第三個關鍵就是 分類決策規則。

回歸:k個實例該屬性值的平均值

它是一個二叉樹的數據結構,方便存儲 K 維空間的數據

KNN 的計算過程是大量計算樣本點之間的距離。為了減少計算距離次數,提升 KNN 的搜索效率,人們提出了 KD 樹(K-Dimensional 的縮寫)。KD 樹是對數據點在 K 維空間中劃分的一種數據結構。在 KD 樹的構造中,每個節點都是 k 維數值點的二叉樹。螞慶既然是二叉樹,就可以採用二叉樹的增刪改查操作,這樣就大大提升了搜索效率。

如果是做分類,你需要引用:from sklearn.neihbors import KNeighborsClassifier
如果是回歸, 需要引用:from sklearn.neighbors import KNeighborsRegressor

sklearn.neighbors.KNeighborsClassifier(n_neighbors=5, weights='uniform', algorithm='auto', leaf_size=30, p=2, metric='minkowski', metric_params=None, n_jobs=None, **kwargs)

F. 鄰近演算法的介紹

鄰近演算法,或者說K最近鄰(kNN,k-NearestNeighbor)分類演算法是數據挖掘分類技術中最簡單的方法之一。所謂K最近鄰,就是k個最近的鄰居的意思,說的是每個樣本都可以用它最接近的k個鄰居來代表。kNN演算法的核心思想是如果一個樣本在特徵空間中的k個最相鄰的樣本中的大多數屬於某一個類別,則該樣本也屬於這個類別,並具有這個類別上樣本的特性。該方法在確定分類決策上只依據最鄰近的一個或者幾個樣本的類別來決定待分樣本所屬的類別。 kNN方法在類別決策時,只與極少量的相鄰樣本有關。由於kNN方法主要靠周圍有限的鄰近的樣本,而不是靠判別類域的方法來確定所屬類別的,因此對於類域的交叉或重疊較多的待分樣本集來說,kNN方法較其他方法更為適合。

閱讀全文

與基於數據挖掘的k近鄰演算法相關的資料

熱點內容
dvd光碟存儲漢子演算法 瀏覽:757
蘋果郵件無法連接伺服器地址 瀏覽:962
phpffmpeg轉碼 瀏覽:671
長沙好玩的解壓項目 瀏覽:142
專屬學情分析報告是什麼app 瀏覽:564
php工程部署 瀏覽:833
android全屏透明 瀏覽:732
阿里雲伺服器已開通怎麼辦 瀏覽:803
光遇為什麼登錄時伺服器已滿 瀏覽:301
PDF分析 瀏覽:484
h3c光纖全工半全工設置命令 瀏覽:141
公司法pdf下載 瀏覽:381
linuxmarkdown 瀏覽:350
華為手機怎麼多選文件夾 瀏覽:683
如何取消命令方塊指令 瀏覽:349
風翼app為什麼進不去了 瀏覽:778
im4java壓縮圖片 瀏覽:362
數據查詢網站源碼 瀏覽:150
伊克塞爾文檔怎麼進行加密 瀏覽:890
app轉賬是什麼 瀏覽:163