KNN和K-means詳細介紹

在對於初學者來說的話,在學習這兩個算法的時候,容易搞混,下面將針對這兩個算法做了一個詳細的介紹。方便大家理解。

K近鄰算法(KNN):有監督的學習

        首先,KNN是通過測量不同特徵值之間的距離進行分類,它的一個基本思路是,如果一個樣本在特徵空間中的K個最相似的(可以理解爲特徵空間中最近的樣本)的樣本中的大多數屬於某一個類別,則樣本也屬於這個類別,通常在選取k值得時候一般選取K<20的值。

這裏特意說一下K值得選取問題:

1.我目前常用的是交叉驗證的方法。

2.基於經驗的方法

        下面通過一個簡單的例子說明一下:如下圖,綠色圓要被決定賦予哪個類,是紅色三角形還是藍色四方形?如果K=3,由於紅色三角形所佔比例爲2/3,綠色圓將被賦予紅色三角形那個類,如果K=5,由於藍色四方形比例爲3/5,因此綠色圓被賦予藍色四方形類。

                                                        

這也是說明了,對於KNN算法的結果很大程度上取決於K值得選取。

另外在KNN算法中距離的選取也是很重要的,通過計算對象間的距離來作爲各個對象之間的非相似性指標,避免了對象之間的匹配問題,在這裏距離的度量一般用歐式距離和曼哈頓距離:

在前面的博文中有對歐式距離做了一個介紹:https://blog.csdn.net/jodie123456/article/details/93741659

KNN算法的優點是根據K各對象中佔優的類別進行決策的,而不是單一的對象類別決策。

接下來對KNN算法的思想總結一下:就是在訓練集中數據和標籤已知的情況下,輸入測試數據,將測試數據的特徵與訓練集中對應的特徵進行相互比較,找到訓練集中與之最爲相似的前K個數據,則該測試數據對應的類別就是K個數據中出現次數最多的那個分類,其算法的描述爲:
1)計算測試數據與各個訓練數據之間的距離(歐式距離或者曼哈頓距離);
2)按照距離的遞增關係進行排序;
3)選取距離最小的K個點(注意K值得選取);
4)確定前K個點所在類別的出現頻率;
5)返回前K個點中出現頻率最高的類別作爲測試數據的預測分類。

matlab代碼如下:

%% KNN
clear all
clc
%% data
trainData = [1.0,2.0;1.2,0.1;0.1,1.4;0.3,3.5];
trainClass = [1,1,2,2];
testData = [0.5,2.3];
k = 3;

%% distance
row = size(trainData,1);
col = size(trainData,2);
test = repmat(testData,row,1);
dis = zeros(1,row);
for i = 1:row
    diff = 0;
    for j = 1:col
        diff = diff + (test(i,j) - trainData(i,j)).^2;
    end
    dis(1,i) = diff.^0.5;
end

%% sort
jointDis = [dis;trainClass];
sortDis= sortrows(jointDis');
sortDisClass = sortDis';

%% find
class = sort(2:1:k);
member = unique(class);
num = size(member);

max = 0;
for i = 1:num
    count = find(class == member(i));
    if count > max
        max = count;
        label = member(i);
    end
end

disp('最終的分類結果爲:');
fprintf('%d\n',label)

python代碼如下:

#coding:utf-8
from numpy import *
import operator
##set data
def createDataSet():
    group = array([[1.0,2.0],[1.2,0.1],[0.1,1.4],[0.3,3.5]])
    labels = ['A','A','B','B']
    return group,labels

###KNN
def classify(input,dataSe t,label,k):
    dataSize = dataSet.shape[0]

    ####calcute the distance
    diff = tile(input,(dataSize,1)) - dataSet
    sqdiff = diff ** 2
    squareDist = sum(sqdiff,axis = 1)###行向量分別相加,從而得到新的一個行向量
    dist = squareDist ** 0.5 
   
    ##sort
    sortedDistIndex = argsort(dist)##argsort()根據元素的值從大到小對元素進行排序,返回下標
    classCount={}
    for i in range(k):
        voteLabel = label[sortedDistIndex[i]]
        ###對選取的K個樣本所屬的類別個數進行統計
        classCount[voteLabel] = classCount.get(voteLabel,0) + 1
    ###選取出現的類別次數最多的類別
    maxCount = 0
    for key,value in classCount.items():
        if value > maxCount:
            maxCount = value
            classes = key
    return classes

k-means聚類算法參考博文:https://blog.csdn.net/jodie123456/article/details/101597370

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章