机器学习之kNN算法(纯python实现)
前面文章分別簡(jiǎn)單介紹了線性回歸,邏輯回歸,貝葉斯分類,并且用python簡(jiǎn)單實(shí)現(xiàn)。這篇文章介紹更簡(jiǎn)單的 knn, k-近鄰算法(kNN,k-NearestNeighbor)。 k-近鄰算法(kNN,k-NearestNeighbor),是最簡(jiǎn)單的機(jī)器學(xué)習(xí)分類算法之一,其核心思想在于用距離目標(biāo)最近的k個(gè)樣本數(shù)據(jù)的分類來(lái)代表目標(biāo)的分類(這k個(gè)樣本數(shù)據(jù)和目標(biāo)數(shù)據(jù)最為相似)。
原理
kNN算法的核心思想是用距離最近(多種衡量距離的方式)的k個(gè)樣本數(shù)據(jù)來(lái)代表目標(biāo)數(shù)據(jù)的分類。
具體講,存在訓(xùn)練樣本集, 每個(gè)樣本都包含數(shù)據(jù)特征和所屬分類值。 輸入新的數(shù)據(jù),將該數(shù)據(jù)和訓(xùn)練樣本集匯中每一個(gè)樣本比較,找到距離最近的k個(gè),在k個(gè)數(shù)據(jù)中,出現(xiàn)次數(shù)做多的那個(gè)分類,即可作為新數(shù)據(jù)的分類。
如上圖: 需要判斷綠色是什么形狀。當(dāng)k等于3時(shí),屬于三角。當(dāng)k等于5是,屬于方形。 因此該方法具有一下特點(diǎn):- 監(jiān)督學(xué)習(xí):訓(xùn)練樣本集中含有分類信息
- 算法簡(jiǎn)單, 易于理解實(shí)現(xiàn)
- 結(jié)果收到k值的影響,k一般不超過(guò)20.
- 計(jì)算量大,需要計(jì)算與樣本集中每個(gè)樣本的距離。
- 訓(xùn)練樣本集不平衡導(dǎo)致結(jié)果不準(zhǔn)確問(wèn)題
接下來(lái)用oython 做個(gè)簡(jiǎn)單實(shí)現(xiàn), 并且嘗試用于約會(huì)網(wǎng)站配對(duì)。
python簡(jiǎn)單實(shí)現(xiàn)
def classify(inX, dataSet, labels, k):"""定義knn算法分類器函數(shù):param inX: 測(cè)試數(shù)據(jù):param dataSet: 訓(xùn)練數(shù)據(jù):param labels: 分類類別:param k: k值:return: 所屬分類"""dataSetSize = dataSet.shape[0] #shape(m, n)m列n個(gè)特征diffMat = np.tile(inX, (dataSetSize, 1)) - dataSetsqDiffMat = diffMat ** 2sqDistances = sqDiffMat.sum(axis=1)distances = sqDistances ** 0.5 #歐式距離sortedDistIndicies = distances.argsort() #排序并返回indexclassCount = {}for i in range(k):voteIlabel = labels[sortedDistIndicies[i]]classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1 #default 0sortedClassCount = sorted(classCount.items(), key=lambda d:d[1], reverse=True)return sortedClassCount[0][0] 復(fù)制代碼算法的步驟上面有詳細(xì)的介紹,上面的計(jì)算是矩陣運(yùn)算,下面一個(gè)函數(shù)是代數(shù)運(yùn)算,做個(gè)比較理解。
def classify_two(inX, dataSet, labels, k):m, n = dataSet.shape # shape(m, n)m列n個(gè)特征# 計(jì)算測(cè)試數(shù)據(jù)到每個(gè)點(diǎn)的歐式距離distances = []for i in range(m):sum = 0for j in range(n):sum += (inX[j] - dataSet[i][j]) ** 2distances.append(sum ** 0.5)sortDist = sorted(distances)# k 個(gè)最近的值所屬的類別classCount = {}for i in range(k):voteLabel = labels[ distances.index(sortDist[i])]classCount[voteLabel] = classCount.get(voteLabel, 0) + 1 # 0:map defaultsortedClass = sorted(classCount.items(), key=lambda d:d[1], reverse=True)return sortedClass[0][0] 復(fù)制代碼有了上面的分類器,下面進(jìn)行最簡(jiǎn)單的實(shí)驗(yàn)來(lái)預(yù)測(cè)一下:
def createDataSet():group = np.array([[1, 1.1], [1, 1], [0, 0], [0, 0.1]])labels = ['A', 'A', 'B', 'B']return group, labels 復(fù)制代碼上面是一個(gè)簡(jiǎn)單的訓(xùn)練樣本集。
if __name__ == '__main__':dataSet, labels = createDataSet()r = classify_two([0, 0.2], dataSet, labels, 3)print(r) 復(fù)制代碼執(zhí)行上述函數(shù):可以看到輸出B, [0 ,0.2]應(yīng)該歸入b類。
上面就是一個(gè)最簡(jiǎn)單的kNN分類器,下面有個(gè)例子。
kNN用于判斷婚戀網(wǎng)站中人的受歡迎程度
訓(xùn)練樣本集中部分?jǐn)?shù)據(jù)如下:
40920 8.326976 0.953952 3 14488 7.153469 1.673904 2 26052 1.441871 0.805124 1 75136 13.147394 0.428964 1 38344 1.669788 0.134296 1 復(fù)制代碼第一列表示每年獲得的飛行常客里程數(shù), 第二列表示玩視頻游戲所耗時(shí)間百分比, 第三類表示每周消費(fèi)的冰淇淋公升數(shù)。第四列表示分類結(jié)果,1, 2, 3 分別是 不喜歡,魅力一般,極具魅力。
如上圖可以看到并無(wú)明顯的分類。
可以看到不同的人根據(jù)特征有明顯的區(qū)分。因此可以使用kNN算法來(lái)進(jìn)行分類和預(yù)測(cè)。
調(diào)整不同的測(cè)試比例,對(duì)比結(jié)果。
可以看到基本的得到所屬的分類。
完成代碼和數(shù)據(jù)請(qǐng)參考:
github:kNN
總結(jié)
- kNN
- 監(jiān)督學(xué)習(xí)
- 數(shù)據(jù)可視化
- 數(shù)據(jù)歸一化,不影響計(jì)算
總結(jié)
以上是生活随笔為你收集整理的机器学习之kNN算法(纯python实现)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 视频转码能力哪家强?腾讯云、阿里云、七牛
- 下一篇: 分页,主要用于python django