基于python實(shí)現(xiàn)KNN分類算法
kNN算法的核心思想是如果一個樣本在特征空間中的k個最相鄰的樣本中的大多數(shù)屬于某一個類別,則該樣本也屬于這個類別,并具有這個類別上樣本的特性。該方法在確定分類決策上只依據(jù)最鄰近的一個或者幾個樣本的類別來決定待分樣本所屬的類別。 kNN方法在類別決策時(shí),只與極少量的相鄰樣本有關(guān)。由于kNN方法主要靠周圍有限的鄰近的樣本,而不是靠判別類域的方法來確定所屬類別的,因此對于類域的交叉或重疊較多的待分樣本集來說,kNN方法較其他方法更為適合。
通俗簡單的說,就是將這個樣本進(jìn)行分類,怎么分類,就是用該樣本的特征與空間中其他樣本做計(jì)算距離,當(dāng)出現(xiàn)大多數(shù)距離偏向于某個樣本類時(shí),我們認(rèn)為該樣本屬于這個類別。
舉例說明:淘寶商品是按類進(jìn)行售賣的,對于零食類商品a,b,c,價(jià)格與銷量分別對應(yīng)(19,1000),(89,500),(9.9,3000)對與電器類商品d,e,f,價(jià)格與銷量分別為(1000,10),(499,30),(999,100),對于一個未知的產(chǎn)品(300,80),我們使用kNN算法進(jìn)行求解,我們假設(shè)k=3(k的值要時(shí)情況而定,沒有確定的),分別求出未知產(chǎn)品到這六個點(diǎn)的歐式距離,即:sqrt((x1-y1)**2+(x2-y2)**2)計(jì)算出結(jié)果進(jìn)行倒序排序,我們得出前三的點(diǎn)分別為:e,b,f。所以我們認(rèn)為未知產(chǎn)品是電器類產(chǎn)品,當(dāng)然實(shí)際生活中不能僅僅有價(jià)格,銷量這兩個二維數(shù)據(jù),可能是n維數(shù)據(jù),歐式距離的公式也是一樣的,現(xiàn)實(shí)中也不僅僅有這兩個分類,kNN提供了一種簡單的解決思路。其中a,b,c,d,e,f稱為訓(xùn)練數(shù)據(jù),未知數(shù)據(jù)稱為測試數(shù)據(jù)。
還有在進(jìn)行計(jì)算時(shí)有時(shí)需要格式化一下數(shù)據(jù),例如對于c產(chǎn)品與未知產(chǎn)品,明顯計(jì)算銷量所產(chǎn)生的數(shù)據(jù)要遠(yuǎn)大于價(jià)格,為了減小這個帶來的誤差,可以使用以下:
def normData(dataSet): maxVals = dataSet.max(axis=0)#按列獲取最大值,并返回?cái)?shù)組 minVals = dataSet.min(axis=0) ranges = maxVals - minVals retData = (dataSet - minVals) / ranges return retData, ranges, minVals
代碼
#?。痷ser/bin/env python #-*- coding:utf-8 -*- import numpy as np import operator as opt def normData(dataSet):#標(biāo)準(zhǔn)化訓(xùn)練集數(shù)據(jù) maxVals = dataSet.max(axis=0) minVals = dataSet.min(axis=0) ranges = maxVals - minVals retData = (dataSet - minVals) / ranges return retData, ranges, minVals def kNN(dataSet, labels, testData, k): distSquareMat = (dataSet - testData) ** 2 # 計(jì)算差值的平方 distSquareSums = distSquareMat.sum(axis=1) # 求每一行的差值平方和,axis=0則按列計(jì)算 distances = distSquareSums ** 0.5 # 開根號,得出每個樣本到測試點(diǎn)的距離 sortedIndices = distances.argsort() # 排序,得到排序后的下標(biāo) indices = sortedIndices[:k] # 取最小的k個 labelCount = {} # 存儲每個label的出現(xiàn)次數(shù),出現(xiàn)次數(shù)最多的就是我們要選擇的類別 for i in indices: label = labels[i] labelCount[label] = labelCount.get(label, 0) + 1 # 次數(shù)加一,使用字典的get方法,第一次出現(xiàn)時(shí)默認(rèn)值是0 sortedCount = sorted(labelCount.items(), key=opt.itemgetter(1), reverse=True) # 對label出現(xiàn)的次數(shù)從大到小進(jìn)行排序 return sortedCount[0][0] # 返回出現(xiàn)次數(shù)最大的label if __name__ == "__main__":#測試程序 dataSet = np.array([[2, 3], [6, 8]])#訓(xùn)練集 normDataSet, ranges, minVals = normData(dataSet) labels = ['a', 'b']#訓(xùn)練集分別為a和b類 testData = np.array([3.9, 5.5])#測試數(shù)據(jù) normTestData = (testData - minVals) / ranges#同樣需要將測試數(shù)據(jù)標(biāo)準(zhǔn)化 result = kNN(normDataSet, labels, normTestData, 1)#k=1 print(result)
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python實(shí)現(xiàn)爬取知乎神回復(fù)簡單爬蟲代碼分享
這篇文章主要介紹了Python實(shí)現(xiàn)爬取知乎神回復(fù)簡單爬蟲代碼分享,本文實(shí)現(xiàn)了爬取知乎的“如何正確地吐槽”收藏夾,是對個人的一個興趣實(shí)現(xiàn),需要的朋友可以參考下2015-01-01python?動態(tài)導(dǎo)入模塊實(shí)現(xiàn)模塊熱更新的方法
這篇文章主要介紹了python?動態(tài)導(dǎo)入模塊,實(shí)現(xiàn)模塊熱更新,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08Python實(shí)現(xiàn)計(jì)算兩個指定日期相差幾年幾月幾日
這篇文章主要為大家詳細(xì)介紹了如何使用Python實(shí)現(xiàn)計(jì)算兩個日期之間相差多少年,多少月,多少天,文中的的示例代碼講解詳細(xì),需要的可以參考下2024-02-02Python中TCP協(xié)議的探索與實(shí)例解析
網(wǎng)絡(luò)編程在當(dāng)今數(shù)字化世界中扮演著至關(guān)重要的角色,本文將帶你深入了解 Python 中的 TCP 協(xié)議,介紹網(wǎng)絡(luò)編程的基礎(chǔ)知識,并提供豐富的示例代碼,希望對大家有所幫助2023-12-12python機(jī)器學(xué)習(xí)實(shí)戰(zhàn)之K均值聚類
這篇文章主要為大家詳細(xì)介紹了python機(jī)器學(xué)習(xí)實(shí)戰(zhàn)之K均值聚類,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12詳解使用pymysql在python中對mysql的增刪改查操作(綜合)
本篇文章主要介紹了使用pymysql在python中對mysql的增刪改查操作,通過pymysql向數(shù)據(jù)庫進(jìn)行查刪增改,具有一定的參考價(jià)值,有興趣的可以了解一下。2017-01-01