K-最近鄰分類算法(KNN)

前幾日男神說,要自學(xué)編程,?小姐姐經(jīng)歷了無數(shù)次從入門到放棄,最終還是沒能拿編程作為吃飯的本領(lǐng),能輕易帶別人入坑?不過,2周一個(gè)算法,機(jī)器學(xué)習(xí)算法帶python和R,數(shù)據(jù)結(jié)構(gòu)算法帶C、C++,一年下來也能拿出去跟非碼農(nóng)崗面試官吹牛了吧。
一、基本原理
問題:確定綠色圓是屬于紅色三角形、還是藍(lán)色正方形?

微信圖片_20180907184017.png

KNN的思想:k=3,看實(shí)線圓圈,紅色三角形占比2/3,故將綠色圓分給紅色三角形;K=5,看虛線圓圈,藍(lán)色正方形占比3/5,故將綠色圓分給藍(lán)色正方形。即如果一個(gè)樣本在特征空間中的k個(gè)最相鄰的樣本中,大多數(shù)屬于某一個(gè)類別,則該樣本也屬于這個(gè)類別
二、算法步驟
1)計(jì)算測試數(shù)據(jù)與各個(gè)訓(xùn)練數(shù)據(jù)之間的距離;
2)按照距離的遞增關(guān)系進(jìn)行排序;
3)選取距離最小的K個(gè)點(diǎn);
4)確定前K個(gè)點(diǎn)所在類別的出現(xiàn)頻率;
5)返回前K個(gè)點(diǎn)中出現(xiàn)頻率最高的類別作為測試數(shù)據(jù)的預(yù)測分類。
三、三種距離
三種距離公式

||r||=a時(shí)

四、鳶尾花數(shù)據(jù)
鳶尾花數(shù)據(jù)百度百科:
https://baike.baidu.com/item/IRIS/4061453
簡介與可視化:
https://www.cnblogs.com/Belter/p/8831216.html
另一種導(dǎo)入數(shù)據(jù)的方式與可視化與其他算法https://blog.csdn.net/Eastmount/article/details/78692227
親測無BUG
五、安裝Anaconda
如果對著小黑框編程,能堅(jiān)持學(xué)下去,若不是內(nèi)心強(qiáng)大,就是真愛了……為了不放棄的那么快,還是用Anaconda上手吧,安裝很簡單,官網(wǎng)下載一路next,然后在程序里找到Anaconda,打開Jupyter Notebook,就會(huì)自動(dòng)跳轉(zhuǎn),基本操作參照這個(gè)視頻吧,十多分鐘……
鏈接:https://pan.baidu.com/s/1k3IalyufbKMcMcnDK52xcg 密碼:7yw2
六、用Python自帶的KNN算法分類

from sklearn import neighbors
from sklearn import  datasets
#獲取KNN分類器
knn = neighbors.KNeighborsClassifier()
#加載數(shù)據(jù)
iris = datasets.load_iris()
print(iris)
#建立模型
knn.fit(iris.data,iris.target)
#輸入預(yù)測模型進(jìn)行預(yù)測
predictedLabel = knn.predict([[0.1,0.2,0.3,0.4]])
#輸出預(yù)測結(jié)果
print(predictedLabel)

七、算法的python實(shí)現(xiàn)

import csv
import random
import math
import operator
#加載數(shù)據(jù)集
def loadDataset(filename,split,traingSet,testSet):
    with open(filename,"r") as csvfile:
        lines = csv.reader(csvfile)
        #將讀入數(shù)據(jù)轉(zhuǎn)換為列表進(jìn)行處理
        dataset = list(lines)
        #print(dataset)
        #x?。?-149
        for x in range(len(dataset)-1):
            #y取:0-3
            for y in range(4):
                #將數(shù)據(jù)浮點(diǎn)化
                dataset[x][y] = float(dataset[x][y])
            #隨機(jī)函數(shù)產(chǎn)生0-1的值,將數(shù)據(jù)集分為訓(xùn)練集和測試集
            if random.random()<split:
                traingSet.append(dataset[x])
            else:
                testSet.append(dataset[x])
#計(jì)算最近距離
def euclideanDistance(instance1,instance2,length):
    distance = 0
    for x in range(length):
        distance += pow((instance1[x]-instance2[x]),2)
    return math.sqrt(distance)
#獲取最近的K個(gè)鄰居
def getNeighbors(trainingSet,testInstance,k):
    distances = []
    length = len(testInstance)-1
    for x in range(len(trainingSet)):
        dist = euclideanDistance(testInstance,trainingSet[x],length)
        distances.append((trainingSet[x],dist))
    distances.sort(key=operator.itemgetter(1))
    neighbors = []
    for x in range(k):
        neighbors.append(distances[x][0])
        return neighbors
#根據(jù)返回的鄰居,將其分類
def getResponse(neighbors):
    classVotes = {}
    for x in range(len(neighbors)):
        response = neighbors[x][-1]
        if response in classVotes:
            classVotes[response]+=1
        else:
            classVotes[response] = 1
    sortedNotes = sorted(classVotes.items(),key=operator.itemgetter(1),reverse=True)
    return sortedNotes[0][0]
#計(jì)算準(zhǔn)確率
def getAccuracy(testSet,predictions):
    correct = 0
    for x in range(len(testSet)):
        if(testSet[x][-1]==predictions[x]):
            correct+=1
    return (correct/float(len(testSet)))*100.0
#主函數(shù)
def main():
    trainingSet = []
    testSet = []
    #三分之二為訓(xùn)練集,三分之一為測試集
    split = 0.67
    #加入r代表忽略地址中的特殊符號的影響
    #########################################
    #C:\Users\Elise\Desktop\iris.data.txt是我下載到的鳶尾花數(shù)據(jù)的保存路徑
    #需要改成自己的
    loadDataset(r"C:\Users\Elise\Desktop\iris.data.txt",split,trainingSet,testSet)
    print("Train set:",repr(len(trainingSet)))
    print("Test set:", repr(len(testSet)))
    predictions = []
    k = 3
    for x in range(len(testSet)):
        neighbors = getNeighbors(trainingSet,testSet[x],k)
        result = getResponse(neighbors)
        predictions.append(result)
        print(">predicted="+repr(result)+", actual="+repr(testSet[x][-1]))
    accuracy = getAccuracy(testSet,predictions)
    print("Accuracy:"+repr(accuracy)+"%")
main()

八、算法的MATLAB實(shí)現(xiàn)

%% 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('最終的分類結(jié)果為:');
fprintf('%d\n',label)

OMG
小女不才……
還有好多想做但未能實(shí)現(xiàn)……
那你還是靠自己吧,看來還是不能去當(dāng)程序員,怕是會(huì)餓死……

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.分清「事實(shí)判斷」和「價(jià)值判斷」。事實(shí)判斷分對錯(cuò),可以越辯越明,在雙方不設(shè)立場的情況下。價(jià)值判斷是不分對錯(cuò),各有...
    曾曉超閱讀 688評論 0 0
  • 十四歲,我是個(gè)孩子。然而,生活對我說我要做個(gè)大人。 ** 01**上課的班級里,有一個(gè)女孩子常常引起我的注意。并不...
    蕭筱筱閱讀 1,168評論 9 14
  • 讀完這本清單革命發(fā)現(xiàn)原來自己在忙的過程浪費(fèi)了不少時(shí)間,而且效率和質(zhì)量都不高!作為一名樂器老師,如何讓孩子...
    馬日月日月閱讀 310評論 1 2

友情鏈接更多精彩內(nèi)容