k近鄰法(k-nearest neighbor, k-nn)是2023年由cover t和hart p提出的一種基本分類與回歸方法。它的工作原理是:存在乙個樣本資料集合,也稱作為訓練樣本集,並且樣本集中每個資料都存在標籤,即我們知道樣本集中每乙個資料與所屬分類的對應關係。輸入沒有標籤的新資料後,將新的資料的每個特徵與樣本集中資料對應的特徵進行比較,然後演算法提取樣本最相似資料(最近鄰)的分類標籤。一般來說,我們只選擇樣本資料集中前k個最相似的資料,這就是k-近鄰演算法中k的出處,通常k是不大於20的整數。最後,選擇k個最相似資料中出現次數最多的分類,作為新資料的分類。
舉個簡單的例子,我們可以使用k-近鄰演算法分類乙個電影是愛情片還是動作片。
如上圖所示就是我們已有的資料集合。這個資料集有兩個特徵,即打鬥次數和接吻次數。同時我們也知道電影的分了標籤即是愛情片還是動作片。我們將打鬥次數和接吻次數轉為x軸的座標和y軸的座標。
為了判斷未知電影的類別,我們以所有已知電影的類別作為參照, 計算未知例項與所有已知例項的距離,然後根據距離的遠近排序,選擇最近k個已知的例項進行投票, 根據少數服從多數的投票法則(majority-voting),讓未知例項歸類為k個最鄰近樣本中最多數的類別
(就是歸為這k個例項中最多的那一類)。
關於距離的衡量方法:
3.2.1 euclidean distance 定義
通過計算,我們可以得到如下結果:
# -*- coding: utf-8 -*-
import numpy as np
import operator
"""函式說明:計算給定資料集的經驗熵(夏農熵)
parameters:
dataset - 資料集
returns:
shannonent - 經驗熵(夏農熵)
author:
aaron gao
modify:
2018-12-01
"""def createdata():
dataset=[[3,104,'愛情片'],
[2,100,'愛情片'],
[1,81,'愛情片'],
[101,10,'動作片'],
[99,5,'動作片'],
[98,2,'動作片']]
dataset=np.array(dataset)
labellist=dataset[:,-1]
featurelist=dataset[:,:2]
return featurelist,labellist
"""函式說明:knn演算法,分類器
parameters:
inx - 用於分類的資料(測試集)
dataset - 用於訓練的資料(訓練集)
labes - 分類標籤
k - knn演算法引數,選擇距離最小的k個點
returns:
sortedclasscount[0][0] - 分類結果
modify:
2018-12-02
"""def classify0(textdata, dataset, labels, k):
#numpy函式shape[0]返回dataset的行數
datasetsize = dataset.shape[0]
#在列向量方向上重複textdata共1次(橫向),行向量方向上重複textdata共datasetsize次(縱向)
testdatalist= np.tile(textdata, (datasetsize, 1))
#print(testdatalist.dtype)
#print(dataset.dtype)
dataset=dataset.astype('float64') #轉換型別
diffmat =testdatalist-dataset
#print(diffmat)
#二維特徵相減後平方
sqdiffmat = diffmat**2
#sum()所有元素相加,sum(0)列相加,sum(1)行相加
sqdistances = sqdiffmat.sum(axis=1)
#開方,計算出距離
distances = sqdistances**0.5
print(distances)
#返回distances中元素從小到大排序後的索引值
sorteddistindices = distances.argsort()
#定乙個記錄類別次數的字典
classcount = {}
for i in range(k):
#取出前k個元素的類別
voteilabel = labels[sorteddistindices[i]]
#dict.get(key,default=none),字典的get()方法,返回指定鍵的值,如果值不在字典中返回預設值。
#計算類別次數
classcount[voteilabel] = classcount.get(voteilabel,0) + 1
#python3中用items()替換python2中的iteritems()
#key=operator.itemgetter(1)根據字典的值進行排序
#key=operator.itemgetter(0)根據字典的鍵進行排序
print(classcount)
# reverse降序排序字典
sortedclasscount = sorted(classcount.items(),key=operator.itemgetter(1),reverse=true)
#返回次數最多的類別,即所要分類的類別
return sortedclasscount[0][0]
if __name__=="__main__":
featurelist,labellist=createdata()
test=[18,90]
currlablel=classify0(test,featurelist,labellist,4)
print('電影型別:'+str(currlablel))
演算法優缺點:
演算法優點
簡單易於理解
容易實現
通過對k的選擇可具備丟噪音資料的健壯性
演算法缺點
需要大量空間儲存所有已知例項
演算法複雜度高(需要比較所有已知例項與要分類的例項)
當其樣本分佈不平衡時,比如其中一類樣本過大(例項數量過多)佔主導的時候,新的未知例項容易被歸類為這個主導樣本,因為這類樣本例項的數量過大,但這個新的未知例項實際並木接近目標樣本
K NN演算法(K 近鄰演算法)
k nn 演算法是一種分類演算法。所謂 k近鄰演算法,即是 給定乙個 訓練資料集,對新的 輸入例項,在 訓練資料集中找到與 該例項最鄰近的 k個例項 也就是k個 鄰居 這k 個例項的多數屬於某個 類,就把該輸入 例項分類到 這個類中。例如 如果k 3,綠 色圓點的最近的3個 鄰居是2個 紅色小三角形...
K 近鄰演算法 KNN
knn k nearest neighbor 假設訓練集有記錄 r1 r2,rn共n條,訓練集的特徵向量及其對應的類別都是已知的,每個記錄的特徵向量為 t1 t2,tk共k個特徵,待測試的記錄為ru 1 計算ru 的特徵向量與訓練集的每條記錄 即r1 r2,rn 的特徵向量的歐式距離,選取距離最小的...
k近鄰演算法 kNN
核心思想 前k個最相似資料中出現次數最多的類別,作為新資料的類別。核心函式 計算距離函式,投票函式 coding utf 8 import random import sys from collections import counter from operator import itemgette...