機(jī)器學(xué)習(xí)之K-近鄰算法(Python描述)基礎(chǔ)

Python 2.7
IDE Pycharm 5.0.3
numpy 1.11.0


前言

總算邁入機(jī)器學(xué)習(xí)第一步剂癌,總比原地踏步要好境肾。

什么是K-近鄰?

一句話總結(jié)永丝,物以類聚锹漱,人以群分,更‘靠近’哪一個(gè)點(diǎn)慕嚷,就認(rèn)為它屬于那一個(gè)點(diǎn)凌蔬。以一篇碩士論文截圖說(shuō)明

這里寫(xiě)圖片描述

Knn算法思想

Knn偽代碼

根據(jù)這個(gè)偽代碼流程,我們就可以使用python進(jìn)行算法重構(gòu)了闯冷,分三步砂心,一算距離,二排序蛇耀,三取值


實(shí)現(xiàn)Knn基礎(chǔ)代碼

第一部分辩诞,被調(diào)函數(shù),在主程序中需要導(dǎo)入

# -*- coding: utf-8 -*-
from numpy import *
import operator


def creatDataSet():
    group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
    labels = ['A','A','B','B']
    return group,labels


def classify0(inX,dataSet,labels,k): # inX用于需要分類的數(shù)據(jù)纺涤,dataSet輸入訓(xùn)練集


    ######輸入與訓(xùn)練樣本之間的距離計(jì)算######
    dataSetSize = dataSet.shape[0] # 讀取行數(shù),shape[1]則為列數(shù)
    diffMat = tile(inX,(dataSetSize,1))-dataSet # tile,重復(fù)inX數(shù)組的行(dataSize)次译暂,列重復(fù)1
    sqDiffMat = diffMat**2 #平方操作
    sqDistances = sqDiffMat.sum(axis=1) # 每一個(gè)列向量相加,axis=0為行相加
    distances = sqDistances**0.5

    sortedDistIndicies = distances.argsort() # argsort函數(shù)返回的是數(shù)組值從小到大的索引值
    #print sortedDistIndicies #產(chǎn)生的是一個(gè)排序號(hào)組成的矩陣
    classCount={}

    ######累計(jì)次數(shù)構(gòu)成字典######
    for i in range(k):
        #print sortedDistIndicies[i]
        voteIlabel = labels[sortedDistIndicies[i]] #排名前k個(gè)貼標(biāo)簽
        #print voteIlabel
        classCount[voteIlabel] = classCount.get(voteIlabel,0)+1 # 不斷累加計(jì)數(shù)的過(guò)程,體現(xiàn)在字典的更新中
        #print classCount.get(voteIlabel,0)
        #print classCount
        #get(key,default=None),就是造字典


    ######找到出現(xiàn)次數(shù)最大的點(diǎn)######
    sortedClassCount = sorted(classCount.iteritems(),key = operator.itemgetter(1),reverse=True)
    #以value值大小進(jìn)行排序撩炊,reverse=True降序
    #print classCount.iteritems()
    #print sortedClassCount
    #key = operator.itemgetter(1)外永,operator.itemgetter函數(shù)獲取的不是值,而是定義了一個(gè)函數(shù)拧咳,通過(guò)該函數(shù)作用到對(duì)象上才能獲取值

    return sortedClassCount[0][0]
    #返回出現(xiàn)次數(shù)最多的value的key

第二部分伯顶,主程序部分,只要將主程序和被調(diào)函數(shù)放在同一工作目錄下骆膝,直接運(yùn)行主程序即可

# -*- coding: utf-8 -*-
import Knn_bymyself

group,labels = Knn_bymyself.creatDataSet() # 調(diào)用Knn_bymyself中的creatDataSet()方法
while 1:
    try:
        a=input('please input x:')
        b=input('please input y:')
        #classify0(inX,dataSet,labels,k)對(duì)應(yīng)起來(lái)看
        print 'belong to :'+Knn_bymyself.classify0([a,b],group,labels,3)+' class'
    except:
        break

跑出來(lái)大概是這樣的:

please input x:2
please input y:1
belong to :A class

分析一下

group也就是輸入訓(xùn)練集祭衩,label就是訓(xùn)練集代表的標(biāo)簽

從圖形上分析

表現(xiàn)形式

從上圖可以看出,我測(cè)試的點(diǎn)是(2,1)阅签,明顯可以看出它是距離A類比較靠近掐暮,所以歸屬于A類沒(méi)有問(wèn)題。

再?gòu)乃惴ㄉ戏治觯?/em>
計(jì)算unknown點(diǎn)到每個(gè)點(diǎn)的距離政钟,然后取最小距離的K個(gè)點(diǎn)路克,在K個(gè)點(diǎn)中樟结,哪個(gè)類出現(xiàn)的概率高就歸屬于哪一類,應(yīng)該沒(méi)什么問(wèn)題了精算。


你可能需要的知道

先過(guò)一眼NumPy快速入門(mén)→點(diǎn)擊這里快速學(xué)習(xí)NumPy

附加:上述代碼中出現(xiàn)的方法使用解析

In[138]: marray
Out[138]: 
array([[1, 2, 3],
       [4, 5, 6]])
  • sum(axis= )狭吼,行(列)相加形成新的行(列)
In[135]: marray.sum(axis=0)
Out[135]: array([5, 7, 9])
  • tile(a,(n,m)),將數(shù)組a的行重復(fù)n次殖妇,列重復(fù)m次
In[136]: b = tile(marray,(2,3))
In[137]: b
Out[137]: 
array([[1, 2, 3, 1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6, 4, 5, 6],
       [1, 2, 3, 1, 2, 3, 1, 2, 3],
       [4, 5, 6, 4, 5, 6, 4, 5, 6]])

dict.get(k,d)
get相當(dāng)于一條if...else...語(yǔ)句,參數(shù)k在字典中,字典將返回dict[k]也就是k對(duì)應(yīng)的value值破花;如果參數(shù)k不在字典中則返回參數(shù)d谦趣。

舉栗子

In[149]: dict = {'A':1,'B':2}
In[150]: dict.get('A',0)
Out[150]: 1
In[151]: dict.get('C',1)
Out[151]: 1
  • .iteritems()迭代器的使用
#使用next()
In[165]: dict.iteritems().next()
Out[164]: ('A', 1)

#使用for循環(huán)
In[169]: for i in dict.iteritems():
...     print i
...     
('A', 1)
('B', 2)

#轉(zhuǎn)化成list之后檢索
In[170]: list_dict = list(dict.iteritems())
In[171]: list_dict[0]

Out[170]: ('A', 1)

最后

 這里只是解釋了如何使用最基本的KNN的方法,代碼也是最簡(jiǎn)單的座每,配合圖的講解前鹅,應(yīng)該會(huì)更加清楚一些,代碼我抄自機(jī)器學(xué)習(xí)峭梳,但是它的解釋比較少舰绘,算是加上了自己的備注,也算是自己的一個(gè)學(xué)習(xí)過(guò)程吧葱椭,希望對(duì)你也有幫助

附錄

如果你對(duì)那副點(diǎn)陣圖感興趣捂寿,也是用python寫(xiě)的代碼如下,可作參考孵运。

# -*- coding: utf-8 -*-

import matplotlib.pyplot as plt
plt.title("KNN ")
plt.xlim(xmax=2.2,xmin=0)
plt.ylim(ymax=2.2,ymin=0)

#標(biāo)識(shí)箭頭
plt.annotate("unknown", xy = (2, 1), xytext = (1.5, 2), arrowprops = dict(facecolor = 'black', shrink = 0.1))
plt.annotate("A class", xy = (1, 1.2), xytext = (1, 2), arrowprops = dict(facecolor = 'black', shrink = 0.1))
plt.annotate("B class", xy = (0.1,0.1), xytext = (0.5,1), arrowprops = dict(facecolor = 'black', shrink = 0.1))

plt.xlabel("x")
plt.ylabel("y")
plt.plot([1,1,0,0],[1.1,1,0,0.1],'ro') # A.B類的點(diǎn)陣
plt.plot([2],[1],'ro') # unknown點(diǎn)
plt.show()

致謝

利用python進(jìn)行數(shù)據(jù)分析.Wes McKinney
機(jī)器學(xué)習(xí)實(shí)戰(zhàn).Peter Harrington
@jihite--字典訪問(wèn)的三種方法
@MrLevo520--numpy快速入門(mén)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末秦陋,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子治笨,更是在濱河造成了極大的恐慌驳概,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件旷赖,死亡現(xiàn)場(chǎng)離奇詭異顺又,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)等孵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)稚照,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人俯萌,你說(shuō)我怎么就攤上這事锐锣。” “怎么了绳瘟?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵雕憔,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我糖声,道長(zhǎng)斤彼,這世上最難降的妖魔是什么分瘦? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮琉苇,結(jié)果婚禮上嘲玫,老公的妹妹穿的比我還像新娘。我一直安慰自己并扇,他們只是感情好去团,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著穷蛹,像睡著了一般土陪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上肴熏,一...
    開(kāi)封第一講書(shū)人閱讀 51,198評(píng)論 1 299
  • 那天鬼雀,我揣著相機(jī)與錄音,去河邊找鬼蛙吏。 笑死源哩,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鸦做。 我是一名探鬼主播励烦,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起骗奖,我...
    開(kāi)封第一講書(shū)人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤确封,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年系瓢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片句灌。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡夷陋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出胰锌,到底是詐尸還是另有隱情骗绕,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布资昧,位于F島的核電站酬土,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏格带。R本人自食惡果不足惜撤缴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一刹枉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧屈呕,春花似錦微宝、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至嗽桩,卻和暖如春岳守,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背涤躲。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留贡未,地道東北人种樱。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像俊卤,于是被迫代替她去往敵國(guó)和親嫩挤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

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