演算法二 K 近鄰(KNN)演算法

2021-09-02 10:55:17 字數 3479 閱讀 9214

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...