K近鄰算法


K-近鄰算法(KNN)是分類數(shù)據(jù)最簡(jiǎn)單最有效的算法。

核心思想

采用不同特征值之間的距離方法進(jìn)行分類
首先:

我們有一個(gè)樣本集(也稱訓(xùn)練樣本集)惹想,樣本中的每個(gè)數(shù)據(jù)都存在標(biāo)簽片任,即樣本集中每一個(gè)數(shù)據(jù)對(duì)應(yīng)與所屬分類的對(duì)應(yīng)關(guān)系稿茉。

之后:

輸入沒有標(biāo)簽的新數(shù)據(jù)時(shí),將新數(shù)據(jù)的每個(gè)特征與樣本集中數(shù)據(jù)的特征進(jìn)行比較拳亿,(一般是計(jì)算歐氏距離)然后算法提取樣本集中特征最相近數(shù)據(jù)(最近鄰)的分類標(biāo)簽

附:一本只選擇樣本數(shù)據(jù)集中前K個(gè)最相近的數(shù)據(jù),這就是k近鄰中的k愿伴。k一般不超過20的整數(shù)

KNN算法的過程為:

  • 選擇一種距離計(jì)算方式, 通過數(shù)據(jù)所有的特征計(jì)算新數(shù)據(jù)與已知類別數(shù)據(jù)集中的數(shù)據(jù)點(diǎn)的距離
  • 按照距離遞增次序進(jìn)行排序肺魁,選取與當(dāng)前距離最小的k個(gè)點(diǎn)
  • 對(duì)于離散分類,返回k個(gè)點(diǎn)出現(xiàn)頻率最多的類別作預(yù)測(cè)分類公般;對(duì)于回歸則返回k個(gè)點(diǎn)的加權(quán)值作為預(yù)測(cè)值

kNN的優(yōu)缺點(diǎn)

優(yōu)點(diǎn):簡(jiǎn)單有效
缺點(diǎn):
一是必須有接近實(shí)際數(shù)據(jù)的訓(xùn)練樣本數(shù)據(jù)万搔,且要保存全部數(shù)據(jù)集,占用存儲(chǔ)空間且計(jì)算耗時(shí)官帘;
二是無法給出任何數(shù)據(jù)的急促結(jié)構(gòu)信息瞬雹,無法知曉平均實(shí)例樣本和典型實(shí)例樣本具有什么特征。使用概率測(cè)量方法可以解決這個(gè)問題

算法實(shí)例

創(chuàng)建kNN.py
(1)創(chuàng)建數(shù)據(jù)集

#創(chuàng)造數(shù)據(jù)集
def createDataSet():
    group = array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])
    labels = ['A', 'A', 'B', 'B']
    return group, labels

有四個(gè)數(shù)據(jù)刽虹,其標(biāo)簽分別為(A,A,B,B)
(2) 構(gòu)照kNN分類器

#第一個(gè)kNN分類器  
#inX-測(cè)試數(shù)據(jù) dataSet-樣本數(shù)據(jù)  labels-標(biāo)簽 k-鄰近的k個(gè)樣本
def classify0(inX,dataSet,labels,k):  
    dataSetSize = dataSet.shape[0]  #dataSet.shape[0]是第一維的數(shù)目    
    '''
    計(jì)算與所有點(diǎn)的距離酗捌,并進(jìn)行排序
    '''
    diffMat = tile(inX,(dataSetSize,1)) - dataSet #要分類的新數(shù)據(jù)與原始數(shù)據(jù)做差 
    sqDiffMat = diffMat**2  #求差的平方  
    sqDistance = sqDiffMat.sum(axis=1)  #求差的平方的和    
    distances = sqDistance**0.5 #求標(biāo)準(zhǔn)差   
    sortDistIndicies = distances.argsort() #距離排序    
    classCount = {}  #定義元字典   
    '''
    遍歷前k個(gè)元素,選擇距離最小的k個(gè)點(diǎn)
    '''
    for i in range(k):  
        voteIlabel = labels[sortDistIndicies[i]]  #獲得前k個(gè)元素的標(biāo)簽 
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1#計(jì)算前k個(gè)數(shù)據(jù)標(biāo)簽出現(xiàn)的次數(shù)   
    '''
    排序
    '''
    sortedClassCount =sorted(classCount.iteritems(),key = operator.itemgetter(1),reverse = True) #對(duì)得到的標(biāo)簽字典按降序排列   
    return sortedClassCount[0][0] #返回出現(xiàn)次數(shù)最多的標(biāo)簽  

結(jié)果測(cè)試

group, labels = kNN.createDataSet( )
kNN.classfy0([0,0],group,labels,3)

結(jié)果為B

(3)讀取文本文件中的數(shù)據(jù)

def file2matrix(filename):

    fr = open(filename)# 打開文件
    numberOfLines = len(fr.readlines()) # 計(jì)算文本文件的行數(shù)
    returnMat = zeros((numberOfLines,3))# 創(chuàng)建返回的數(shù)據(jù)矩陣
    classLabelVector = []# 創(chuàng)建類標(biāo)簽
    fr = open(filename) # 打開文件
    index = 0 # 定義索引
    # 讀取文件的每一行并處理
    for line in fr.readlines():
        line = line.strip()# 去除行的尾部的換行符
        listFromLine = line.split('\t') # 將一行數(shù)據(jù)按空進(jìn)行分割
        returnMat[index,:] = listFromLine[0:3] # 0:3列為數(shù)據(jù)集的數(shù)據(jù)
        classLabelVector.append((listFromLine[-1])) # 最后一列為數(shù)據(jù)的分類標(biāo)簽
        index += 1# 索引加1
   
    return returnMat,classLabelVector # 返回?cái)?shù)據(jù)集和對(duì)應(yīng)的類標(biāo)簽

(4)顯示散點(diǎn)圖

import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(111)
datingDataMat,datingLabels = kNN.file2matrix('datingTestSet.txt')
#ax.scatter(datingDataMat[:,1], datingDataMat[:,2])

ax1.scatter(datingDataMat[:, 1], datingDataMat[:, 2], 15.0*array(datingLabels), 15.0*array(datingLabels))

ax.axis([-2, 25, -0.2, 2.0])
plt.xlabel(u"玩游戲視頻所耗時(shí)間百分比")
plt.ylabel(u"每周消費(fèi)的冰淇淋公升數(shù)")
plt.show()

(5)歸一化數(shù)值
為了防止特征值數(shù)量的差異對(duì)預(yù)測(cè)結(jié)果的影響(比如計(jì)算距離,量值較大的特征值影響肯定很大)涌哲,我們將所有的特征值都?xì)w一化到[0,1]

def autoNorm(dataSet):
    minVals = dataSet.min(0) # 求數(shù)據(jù)矩陣每一列的最小值
    maxVals = dataSet.max(0)# 求數(shù)據(jù)矩陣每一列的最大值
    ranges = maxVals - minVals# 求數(shù)據(jù)矩陣每一列的最大最小值差值
    #normDataSet = zeros(shape(dataSet))
    m = dataSet.shape[0] # 返回?cái)?shù)據(jù)矩陣第一維的數(shù)目
    normDataSet = dataSet - tile(minVals, (m, 1)) # 求矩陣每一列減去該列最小值胖缤,得出差值
    normDataSet = normDataSet / tile(ranges, (m, 1)) # 用求的差值除以最大最小值差值,即數(shù)據(jù)的變化范圍阀圾,即歸一化
    return normDataSet, ranges, minVals # 返回歸一化后的數(shù)據(jù)哪廓,最大最小值差值,最小值

附:numpy函數(shù)小結(jié)

#coding=utf-8
__author__ = 'Administrator'
from numpy import *

a = array([[0, 1, 0], [1, 1, 2]])
print a

aSize = a.shape[0] #可以認(rèn)為是輸出列數(shù)
print aSize

b = arange(7, dtype=uint16) #dtype為數(shù)據(jù)類型對(duì)象
print b

'''
tile
將數(shù)組a重復(fù)n次
'''
c = array([0, 1])
d = tile(c, (3, 1))
print d

c = zeros((3, 1), dtype=int)
print c

輸出結(jié)果

[[0 1 0]
[1 1 2]]
2
[0 1 2 3 4 5 6]
[[0 1]
[0 1]
[0 1]]
[[0]
[0]
[0]]

參考文獻(xiàn):

http://www.aichengxu.com/yejie/512129.htm
http://blog.csdn.net/quincuntial/article/details/50471423
http://blog.csdn.net/suipingsp/article/details/41964713

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末初烘,一起剝皮案震驚了整個(gè)濱河市涡真,隨后出現(xiàn)的幾起案子分俯,更是在濱河造成了極大的恐慌,老刑警劉巖哆料,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缸剪,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡东亦,警方通過查閱死者的電腦和手機(jī)杏节,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來典阵,“玉大人奋渔,你說我怎么就攤上這事∽嘲。” “怎么了卒稳?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)他巨。 經(jīng)常有香客問我充坑,道長(zhǎng),這世上最難降的妖魔是什么染突? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任捻爷,我火速辦了婚禮,結(jié)果婚禮上份企,老公的妹妹穿的比我還像新娘也榄。我一直安慰自己,他們只是感情好司志,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布甜紫。 她就那樣靜靜地躺著,像睡著了一般骂远。 火紅的嫁衣襯著肌膚如雪囚霸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天激才,我揣著相機(jī)與錄音拓型,去河邊找鬼。 笑死瘸恼,一個(gè)胖子當(dāng)著我的面吹牛劣挫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播东帅,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼压固,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了靠闭?” 一聲冷哼從身側(cè)響起帐我,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤刘莹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后焚刚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡扇调,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年矿咕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狼钮。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡碳柱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出熬芜,到底是詐尸還是另有隱情莲镣,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布涎拉,位于F島的核電站瑞侮,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏鼓拧。R本人自食惡果不足惜半火,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望季俩。 院中可真熱鬧钮糖,春花似錦、人聲如沸酌住。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽酪我。三九已至消痛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間都哭,已是汗流浹背肄满。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留质涛,地道東北人稠歉。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像汇陆,于是被迫代替她去往敵國(guó)和親怒炸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容