k近邻法matlab_机器学习系列(一)K近邻算法(KNN,KNearestNeigh
本文源自微信公眾號(hào)【Python編程和深度學(xué)習(xí)】原文鏈接:機(jī)器學(xué)習(xí)系列(一)K-近鄰算法(KNN,K-Nearest-Neighbor),歡迎掃碼關(guān)注鴨!
目錄
一、算法概述
二、Python代碼
三、Matlab 代碼
一、算法概述
K-近鄰算法是最簡單的分類器,沒有顯式的學(xué)習(xí)過程或訓(xùn)練過程,是懶惰學(xué)習(xí)(Lazy Learning),數(shù)據(jù)集事先已經(jīng)有了分類標(biāo)簽和數(shù)據(jù)特征值,對測試數(shù)據(jù)可以直接處理,其處理機(jī)制就是通過測量不同特征值之間的距離來進(jìn)行分類,簡單說就是如果測試樣本在特征空間中的k個(gè)最鄰近的樣本中,大多數(shù)樣本屬于某個(gè)類別,則該測試樣本也劃分到這個(gè)類別,KNN里的K就是最鄰近的K個(gè)數(shù)據(jù)樣本。
要確定綠圓屬于哪個(gè)類別,如果k=3,在其最近的3個(gè)樣本中紅色三角形數(shù)量最多,綠圓屬于紅色三角形類別,如果k=5,在其最近的5個(gè)樣本中藍(lán)色矩形數(shù)量最多,綠圓屬于藍(lán)色矩形類別,可見k的選擇很重要。
當(dāng)k很小時(shí),結(jié)果很容易受噪聲影響,容易發(fā)生過擬合。當(dāng)k很大時(shí),與測試樣本差別很大的樣本也會(huì)對預(yù)測結(jié)果產(chǎn)生影響,k通常取奇數(shù),避免產(chǎn)生相等占比的情況。
我們在計(jì)算相鄰樣本的距離時(shí)一般采用歐式距離或者曼哈頓距離,公式如下:
歐式距離:
麥哈頓距離:
詳細(xì)的算法過程:
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ù)測分類。
KNN的缺點(diǎn):
當(dāng)樣本數(shù)據(jù)量很大時(shí),需要大量的存儲(chǔ)空間,而且計(jì)算距離也會(huì)耗時(shí),不適用于隨機(jī)分布的數(shù)據(jù)和樣本不均衡的數(shù)據(jù)。
二、Python代碼
#!/usr/bin/env?python#?-*-?coding:utf-8?-*-
import?csv
import?random
import?math
import?operator
#?加載數(shù)據(jù)集
def?loadDataset(filename,?split,?trainingSet?=?[],?testSet?=?[]):
????with?open(filename,?'r')?as?csvfile:
????????lines?=?csv.reader(csvfile)
????????dataset?=?list(lines)
????????for?x?in?range(len(dataset)-1):
????????????for?y?in?range(4):
????????????????dataset[x][y]?=?float(dataset[x][y])
????????????if?random.random()?#將數(shù)據(jù)集隨機(jī)劃分
????????????????trainingSet.append(dataset[x])
????????????else:
????????????????testSet.append(dataset[x])
#?計(jì)算點(diǎn)之間的距離,多維度的
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))???#獲取到測試點(diǎn)到其他點(diǎn)的距離
????distances.sort(key=operator.itemgetter(1))????#對所有的距離進(jìn)行排序
????neighbors?=?[]
????for?x?in?range(k):???#獲取到距離最近的k個(gè)點(diǎn)
????????neighbors.append(distances[x][0])
????????return?neighbors
#?得到這k個(gè)鄰居的分類中最多的那一類
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
????sortedVotes?=?sorted(classVotes.items(),?key=operator.itemgetter(1),?reverse=True)
????return?sortedVotes[0][0]???#獲取到票數(shù)最多的類別
#計(jì)算預(yù)測的準(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
def?main():
????#prepare?data
????trainingSet?=?[]
????testSet?=?[]
????split?=?0.67
????loadDataset(r'irisdata.txt',?split,?trainingSet,?testSet)
????print('Trainset:?'?+?repr(len(trainingSet)))
????print('Testset:?'?+?repr(len(testSet)))
????#generate?predictions
????predictions?=?[]
????k?=?3
????for?x?in?range(len(testSet)):
????????#?trainingsettrainingSet[x]
????????neighbors?=?getNeighbors(trainingSet,?testSet[x],?k)
????????result?=?getResponse(neighbors)
????????predictions.append(result)
????????print?('predicted='?+?repr(result)?+?',?actual='?+?repr(testSet[x][-1]))
????print('predictions:?'?+?repr(predictions))
????accuracy?=?getAccuracy(testSet,?predictions)
????print('Accuracy:?'?+?repr(accuracy)?+?'%')
if?__name__?==?'__main__':
main()
在實(shí)際使用時(shí),可以用sklearn庫,簡單易用,例如
from?sklearn?import?neighbors???//包含有kNN算法的模塊
knn?=?neighbors.KNeighborsClassifier()
knn.fit(data,?target)
predictedLabel?=?knn.predict(testdata)
三、Matlab 代碼
%%?KNNclear?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)
部分轉(zhuǎn)自:https://www.cnblogs.com/jyroy/p/9427977.html
https://www.cnblogs.com/ybjourney/p/4702562.html
總結(jié)
以上是生活随笔為你收集整理的k近邻法matlab_机器学习系列(一)K近邻算法(KNN,KNearestNeigh的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hbase 读写调优_hbase优化操作
- 下一篇: oem718d 基准站设置_RTK基站设