機器學習實戰(zhàn)入門篇之二:kNN算法 | 她是不是你喜歡的類型?

她是不是你喜歡的類型.jpg

通過本篇博文雕沿,你可以學習到:

  1. 環(huán)境搭建练湿,主要為python,numpy审轮,以及matplotlib庫的搭建等肥哎;
  2. k-近鄰算法辽俗;
  3. k-近鄰算法實戰(zhàn)練習,使用k-近鄰算法判斷某個同學是不是你喜歡的類型篡诽。

理論與實戰(zhàn)的結合崖飘,趕快打起精神,一起來學習吧杈女!吼吼吼~~~

環(huán)境搭建

  • python:開發(fā)語言朱浴,使用廣泛, 簡單易學
  • NumPy:科學計算庫文件达椰,它實現(xiàn)了大量的向量和矩陣操作翰蠢,在python中我們可以像在matlab里面一樣編寫非常簡單易讀矩陣操作代碼。
  • matplotlib:繪圖庫文件,在python中我們可以像在matlab里面一樣,方便的實現(xiàn)繪圖功能摔敛。

python###

  1. 下載python安裝文件
    https://www.python.org/downloads/ 上下載相應平臺的python安裝文件,本文采用的python版本為windows平臺的python 2.7廷支。下載后,點擊安裝猖辫,一路next酥泞。

  2. 添加環(huán)境變量
    右鍵“我的電腦”——屬性——系統(tǒng)高級設置——高級——環(huán)境變量,在系統(tǒng)變量中找到Path啃憎,編輯此變量在后面追加 ;C:\Python27\ (python安裝位置,每個人都可能不一樣哦似炎,注意前面的分號)辛萍。

  3. 如何證明python安裝成功?
    打開命令提示符羡藐,輸入python贩毕,能看到所安裝python的版本信息即證明安裝成功,如下圖所示:

python安裝成功示意圖.png

numpy及matplotlib等庫文件安裝###

一個一個安裝比較麻煩仆嗦,如果想省事兒的話辉阶,建議使用Anaconda進行安裝,Anaconda針對的痛點就是一個一個安裝這些庫會比較麻煩瘩扼,那么他就幫大家一起集成了谆甜。

  1. 下載Anaconda安裝文件
    https://www.continuum.io/downloads 下載相應版本的安裝文件,雙擊安裝即可集绰,一路next规辱。

  2. 環(huán)境變量設置
    Anaconda安裝的過程中,會自動在path下面添加相關的環(huán)境變量栽燕,所以這步跳過罕袋。

  3. 如何證明Anaconda已經安裝成功改淑?
    在cmd里面,輸入conda list可以查看Anaconda已經幫大家安裝的庫浴讯,如下圖所示朵夏。

Anaconda安裝成功示意圖.png

可以自己看下我們所需要用到的numpy及matplotlib庫文件也在包含在里面。

4.如何證明numpy及matplotlib已經安裝成功榆纽?

numpy正常使用示意圖.png
matplotlib正確安裝示意圖_代碼.png
使用matplotlib畫圖.png

如上圖所示仰猖,就表示能夠正常的使用numpy及matplotlib。

爬過的坑###

  1. 單獨下載numpy包掠河,然后cd到相應的路徑亮元,使用python setup.py install安裝numpy,報錯“failed with exit status 1120”唠摹,如下圖所示:
    爬過的坑1.png

產生問題的原因及解決辦法:版本原因爆捞,python版本為2.7,numpy下載的版本為1.11勾拉,后來使用Anaconda下載的匹配的版本是1.10煮甥。解決方法是使用Anaconda安裝。

2.安裝完Anaconda之后藕赞,import matplotlib的時候成肘,提示"no module named matplotlib"。

產生問題的原因:猜想是python無法使用Anaconda安裝的庫斧蜕。

解決辦法
在python安裝目錄下的lib\site-packages下面双霍,新建一個文件anaconda.pth,文件的內容是Anaconda安裝目錄下的site-packages路徑批销。

爬過的坑2.png

3.import matplotlib.pyplot as plt報錯“from PyQt4 import QtCore, QtGui ImportError: DLL load failed:找不到指定的程序“洒闸,如下圖所示

爬過的坑3.png

產生問題的原因:沒有安裝PyQt4

解決辦法:安裝PyQt4,下載鏈接https://riverbankcomputing.com/software/pyqt/download

OK均芽!到這一步為止環(huán)境就算搭建好了丘逸,下面就開始這篇文章的正題,k-近鄰算法掀宋。

k-近鄰(kNN)算法概述

  • kNN算法原理

存在一個樣本數(shù)據(jù)集合深纲,也稱作訓練樣本集,并且樣本集中每個數(shù)據(jù)都存在標簽劲妙,即我們知道樣本集中每一數(shù)據(jù)與所屬分類的對應關系湃鹊。輸入沒有標簽的新數(shù)據(jù)后,將新數(shù)據(jù)的每個特征與樣本集中數(shù)據(jù)對應的特征進行比較是趴,然后算法提取樣本集中特征最相似(最鄰近)的分類標簽涛舍。一般來說我們只選擇數(shù)據(jù)集中前k個最相似的數(shù)據(jù),這就是k-近鄰算法的k的出處唆途,通常k是不大于20的整數(shù)富雅。最后掸驱,選擇k個最相似數(shù)據(jù)中出現(xiàn)次數(shù)最多的分類,作為新數(shù)據(jù)的分類没佑。

上面寫的太復雜了毕贼,其實很簡單,就是計算距離蛤奢,根據(jù)距離進行分類鬼癣。舉個栗子,吼吼啤贩,如下圖所示待秃,已知右上角的兩個點屬于A類,左下角的兩個點屬于B類痹屹,那么給定一個點如圖中的小紅點章郁,那么他是屬于A點還是B點呢?

kNN算法給出的解決方案是志衍,分別計算小紅點與每個點的距離暖庄,然后將距離從小到大排序,取前k位楼肪,如取前2位培廓,如果發(fā)現(xiàn)這2位都是B類,那么說明這個小紅點也是屬于B類春叫。

k近鄰算法示例.png
  • kNN算法實現(xiàn)

算法流程

  1. 計算待分類點與已知類別數(shù)據(jù)集中每個點的距離肩钠;
  2. 按照距離遞增次序排序;
  3. 選取與待分類點距離最小的k個點暂殖;
  4. 確定前k個點類別出現(xiàn)的頻率蔬将;
  5. 返回前k個點出現(xiàn)頻率最高的類別作為當前點的預測分類。

python代碼實現(xiàn)

from numpy import *

def classify0(inX, dataSet, labels, k):
    dataSetSize = dataSet.shape[0]
    diffMat = tile(inX, (dataSetSize,1)) - dataSet
    sqDiffMat = diffMat**2
    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances**0.5
    sortedDistIndicies = distances.argsort()     
    classCount={}          
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
    sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]

四不四很簡單央星?吼吼吼~~~

使用k-近鄰算法快速判定她是不是你喜歡的類型?

  1. 問題描述
    比如你的朋友經常上約會網站尋找自己的約會對象惫东,你的朋友選定約會對象的時候主要看重三點“每年飛行的旅程數(shù)”莉给、“玩游戲所耗時間百分比”、“每個月看書的數(shù)目”廉沮,你閱人無數(shù)的朋友已經約會過很多個對象了颓遏,并且把這些對象分為三類“她是我喜歡的類型”、“一般喜歡”滞时,“她不是我喜歡的類型”叁幢,經過無數(shù)次的約會之后,你的朋友心已經很累了坪稽,他想能否輸入某人的“每年飛行的旅程數(shù)”曼玩、“玩游戲所耗時間百分比”鳞骤、“每個月看書的數(shù)目”這三項數(shù)據(jù),就能判斷她是不是他喜歡的類型呢黍判?

  2. 已有資源
    為了簡化問題豫尽,我們假設你的朋友,已經整理了一份數(shù)據(jù)顷帖,如下圖所示:

    數(shù)據(jù).png

    其中前三列分別表示“每年飛行的旅程數(shù)”美旧、“玩游戲所耗時間百分比”、“每個月看書的數(shù)目”贬墩,第四列表示分類榴嗅。其中“1”表示“她不是我喜歡的類型”、“2”表示“一般喜歡”陶舞,“3”表示“她是我喜歡的類型”嗽测。

  3. 如何使用kNN算法?
    在前一篇博文機器學習實戰(zhàn)入門篇之一:機器學習中必會的基礎概念吊说!中论咏,我們介紹了使用機器學習算法解決問題的一般步驟,我們再一次回顧一遍流程圖颁井。

開發(fā)機器學習應用程序步驟.png

下面我們將一步一步來完成厅贪。

  • 收集數(shù)據(jù)
    為簡單起見,已經提供txt文本數(shù)據(jù)雅宾。

  • 數(shù)據(jù)預處理
    數(shù)據(jù)預處理中养涮,我們得將txt文本中提供的數(shù)據(jù)放到矩陣或矢量中進行存儲,然后還需要將數(shù)據(jù)進行歸一化眉抬。
    (1) 把txt文本中的數(shù)據(jù)轉換成矩陣或矢量進行存儲

#函數(shù)名:file2matrix
#輸入:文件名
#輸出:returnMat為txt文本數(shù)據(jù)的前三列構成的二維數(shù)組
 #     classLabelVector為txt文本數(shù)據(jù)第四列的分類信息的一維矢量
def file2matrix(filename):
    fr = open(filename)
    numberOfLines = len(fr.readlines())         #get the number of lines in the file
    returnMat = zeros((numberOfLines,3))        #prepare matrix to return
    classLabelVector = []                       #prepare labels return   
    fr = open(filename)
    index = 0
    for line in fr.readlines():
        line = line.strip()
        listFromLine = line.split('\t')
        returnMat[index,:] = listFromLine[0:3]
        classLabelVector.append(int(listFromLine[-1]))
        index += 1
    return returnMat,classLabelVector

(2) 數(shù)據(jù)歸一化
為什么要進行數(shù)據(jù)歸一化贯吓?分析下數(shù)據(jù)可以看出,飛行距離相對于其他兩個特征的數(shù)據(jù)來說通常要大的多蜀变,如果不進行數(shù)據(jù)歸一化悄谐,那么在計算距離的時候飛行距離對結果的影響占絕對主導性,這顯然是不合理的库北,所以需要進行數(shù)據(jù)歸一化爬舰,歸一化的python代碼如下所示:

#函數(shù)名:autoNorm
#輸入:dataSet為原始數(shù)據(jù)二維數(shù)組
#輸出:normDataSet歸一化之后的二維數(shù)組,ranges為每一列最大值減去最小值的范圍寒瓦,minVals為每一列的最小值情屹。
def autoNorm(dataSet):
    minVals = dataSet.min(0)
    maxVals = dataSet.max(0)
    ranges = maxVals - minVals
    normDataSet = zeros(shape(dataSet))
    m = dataSet.shape[0]
    normDataSet = dataSet - tile(minVals, (m,1))
    normDataSet = normDataSet/tile(ranges, (m,1))   #element wise divide
    return normDataSet, ranges, minVals
  • 分析輸入數(shù)據(jù)
    可以將數(shù)據(jù)用二維散點圖畫出來,直觀感受一下杂腰。

  • 訓練算法
    此步驟不適用于kNN算法

  • 測試算法
    通常來說垃你,我們使用數(shù)據(jù)的90%作為訓練數(shù)據(jù),10%的數(shù)據(jù)作為測試數(shù)據(jù)。測試的指標為出錯率惜颇,當預測的分類和實際的分類結果不一致時皆刺,記錄一個錯誤,錯誤的總數(shù)/測試的樣本數(shù)即為出錯率官还。
    python代碼:

#函數(shù)名:datingClassTest
#輸入:無
#輸出:無芹橡,但是會打印出錯個數(shù)及錯誤率。
def datingClassTest():
    hoRatio = 0.50      #hold out 10%
    datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')       #load data setfrom file
    normMat, ranges, minVals = autoNorm(datingDataMat)
    m = normMat.shape[0]
    numTestVecs = int(m*hoRatio)
    errorCount = 0.0
    for i in range(numTestVecs):
        classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)
        print "the classifier came back with: %d, the real answer is: %d" % (classifierResult, datingLabels[i])
        if (classifierResult != datingLabels[i]): errorCount += 1.0
    print "the total error rate is: %f" % (errorCount/float(numTestVecs))
    print errorCount

運行結果:


測試程序運行結果.png

可以看出望伦,錯誤率為6.4%林说,大家可以改變參數(shù)值k,觀察下出錯率的變化屯伞。

  • 應用算法
    測試出錯率達到滿意結果之后腿箩,我們就可以拿來用了,應用程序如下:
def classifyPerson():
    resultList = ['not like','so so','very like']
    gamePercent = float(raw_input("gaming time percent:"))
    flyMiles = float(raw_input("flying miles per year:"))
    bookNum = float(raw_input("reading books per month:"))
    datingDataMat, datingLabels = file2matrix("datingTestSet2.txt")
    normMat, ranges, minVals = autoNorm(datingDataMat)
    inArray = array([flyMiles, gamePercent, bookNum])
    classifyResult = classify0((inArray - minVals)/ranges, normMat, datingLabels, 3)
    print "prediction result is: ", resultList[classifyResult - 1]

運行結果:


運行結果.png

可以看出劣摇,具有這些特征數(shù)據(jù)的她對你吸引力一般般啦珠移,你可以自己測試看看,看到底什么樣的她才是你喜歡的類型呢末融?

kNN算法總結

  • 優(yōu)點:簡單有效
  • 缺點:經過前面的介紹可以看出钧惧,kNN算法必須保存全部的數(shù)據(jù)集,如果訓練數(shù)據(jù)集很大勾习,那么就需要耗費大量的存儲空間浓瞪。此外,由于必須對待分類數(shù)據(jù)計算與每一個訓練數(shù)據(jù)的距離巧婶,非常耗時乾颁。

終于寫好了,碼字好累诅妹,歡迎志同道合的朋友留言交流堰塌,有什么寫的不對的地方敬請指出!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市科乎,隨后出現(xiàn)的幾起案子太抓,更是在濱河造成了極大的恐慌碴倾,老刑警劉巖捶障,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芥挣,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鞍时,你說我怎么就攤上這事弱贼∠荆” “怎么了鸳兽?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長爆班。 經常有香客問我衷掷,道長,這世上最難降的妖魔是什么柿菩? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任戚嗅,我火速辦了婚禮,結果婚禮上枢舶,老公的妹妹穿的比我還像新娘懦胞。我一直安慰自己,他們只是感情好凉泄,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布躏尉。 她就那樣靜靜地躺著,像睡著了一般后众。 火紅的嫁衣襯著肌膚如雪醇份。 梳的紋絲不亂的頭發(fā)上稼锅,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天,我揣著相機與錄音僚纷,去河邊找鬼。 笑死拗盒,一個胖子當著我的面吹牛怖竭,可吹牛的內容都是我干的。 我是一名探鬼主播陡蝇,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼痊臭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了登夫?” 一聲冷哼從身側響起广匙,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎恼策,沒想到半個月后鸦致,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡涣楷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年分唾,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狮斗。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡绽乔,死狀恐怖,靈堂內的尸體忽然破棺而出碳褒,到底是詐尸還是另有隱情折砸,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布沙峻,位于F島的核電站睦授,受9級特大地震影響,放射性物質發(fā)生泄漏专酗。R本人自食惡果不足惜睹逃,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望祷肯。 院中可真熱鬧沉填,春花似錦、人聲如沸佑笋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蒋纬。三九已至猎荠,卻和暖如春坚弱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背关摇。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工荒叶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人输虱。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓些楣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親宪睹。 傳聞我的和親對象是個殘疾皇子愁茁,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內容