通過本篇博文雕沿,你可以學習到:
- 環(huán)境搭建练湿,主要為python,numpy审轮,以及matplotlib庫的搭建等肥哎;
- k-近鄰算法辽俗;
- k-近鄰算法實戰(zhàn)練習,使用k-近鄰算法判斷某個同學是不是你喜歡的類型篡诽。
理論與實戰(zhàn)的結合崖飘,趕快打起精神,一起來學習吧杈女!吼吼吼~~~
環(huán)境搭建
- python:開發(fā)語言朱浴,使用廣泛, 簡單易學
- NumPy:科學計算庫文件达椰,它實現(xiàn)了大量的向量和矩陣操作翰蠢,在python中我們可以像在matlab里面一樣編寫非常簡單易讀矩陣操作代碼。
- matplotlib:繪圖庫文件,在python中我們可以像在matlab里面一樣,方便的實現(xiàn)繪圖功能摔敛。
python###
下載python安裝文件
在https://www.python.org/downloads/ 上下載相應平臺的python安裝文件,本文采用的python版本為windows平臺的python 2.7廷支。下載后,點擊安裝猖辫,一路next酥泞。添加環(huán)境變量
右鍵“我的電腦”——屬性——系統(tǒng)高級設置——高級——環(huán)境變量,在系統(tǒng)變量中找到Path啃憎,編輯此變量在后面追加 ;C:\Python27\ (python安裝位置,每個人都可能不一樣哦似炎,注意前面的分號)辛萍。如何證明python安裝成功?
打開命令提示符羡藐,輸入python贩毕,能看到所安裝python的版本信息即證明安裝成功,如下圖所示:
numpy及matplotlib等庫文件安裝###
一個一個安裝比較麻煩仆嗦,如果想省事兒的話辉阶,建議使用Anaconda進行安裝,Anaconda針對的痛點就是一個一個安裝這些庫會比較麻煩瘩扼,那么他就幫大家一起集成了谆甜。
下載Anaconda安裝文件
在https://www.continuum.io/downloads 下載相應版本的安裝文件,雙擊安裝即可集绰,一路next规辱。環(huán)境變量設置
Anaconda安裝的過程中,會自動在path下面添加相關的環(huán)境變量栽燕,所以這步跳過罕袋。如何證明Anaconda已經安裝成功改淑?
在cmd里面,輸入conda list可以查看Anaconda已經幫大家安裝的庫浴讯,如下圖所示朵夏。
可以自己看下我們所需要用到的numpy及matplotlib庫文件也在包含在里面。
4.如何證明numpy及matplotlib已經安裝成功榆纽?
如上圖所示仰猖,就表示能夠正常的使用numpy及matplotlib。
爬過的坑###
- 單獨下載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路徑批销。
3.import matplotlib.pyplot as plt報錯“from PyQt4 import QtCore, QtGui ImportError: DLL load failed:找不到指定的程序“洒闸,如下圖所示
產生問題的原因:沒有安裝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類春叫。
- kNN算法實現(xiàn)
算法流程
- 計算待分類點與已知類別數(shù)據(jù)集中每個點的距離肩钠;
- 按照距離遞增次序排序;
- 選取與待分類點距離最小的k個點暂殖;
- 確定前k個點類別出現(xiàn)的頻率蔬将;
- 返回前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-近鄰算法快速判定她是不是你喜歡的類型?
問題描述
比如你的朋友經常上約會網站尋找自己的約會對象惫东,你的朋友選定約會對象的時候主要看重三點“每年飛行的旅程數(shù)”莉给、“玩游戲所耗時間百分比”、“每個月看書的數(shù)目”廉沮,你閱人無數(shù)的朋友已經約會過很多個對象了颓遏,并且把這些對象分為三類“她是我喜歡的類型”、“一般喜歡”滞时,“她不是我喜歡的類型”叁幢,經過無數(shù)次的約會之后,你的朋友心已經很累了坪稽,他想能否輸入某人的“每年飛行的旅程數(shù)”曼玩、“玩游戲所耗時間百分比”鳞骤、“每個月看書的數(shù)目”這三項數(shù)據(jù),就能判斷她是不是他喜歡的類型呢黍判?-
已有資源
為了簡化問題豫尽,我們假設你的朋友,已經整理了一份數(shù)據(jù)顷帖,如下圖所示:
數(shù)據(jù).png
其中前三列分別表示“每年飛行的旅程數(shù)”美旧、“玩游戲所耗時間百分比”、“每個月看書的數(shù)目”贬墩,第四列表示分類榴嗅。其中“1”表示“她不是我喜歡的類型”、“2”表示“一般喜歡”陶舞,“3”表示“她是我喜歡的類型”嗽测。 如何使用kNN算法?
在前一篇博文機器學習實戰(zhàn)入門篇之一:機器學習中必會的基礎概念吊说!中论咏,我們介紹了使用機器學習算法解決問題的一般步驟,我們再一次回顧一遍流程圖颁井。
下面我們將一步一步來完成厅贪。
收集數(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
運行結果:
可以看出望伦,錯誤率為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]
運行結果:
可以看出劣摇,具有這些特征數(shù)據(jù)的她對你吸引力一般般啦珠移,你可以自己測試看看,看到底什么樣的她才是你喜歡的類型呢末融?
kNN算法總結
- 優(yōu)點:簡單有效
- 缺點:經過前面的介紹可以看出钧惧,kNN算法必須保存全部的數(shù)據(jù)集,如果訓練數(shù)據(jù)集很大勾习,那么就需要耗費大量的存儲空間浓瞪。此外,由于必須對待分類數(shù)據(jù)計算與每一個訓練數(shù)據(jù)的距離巧婶,非常耗時乾颁。
終于寫好了,碼字好累诅妹,歡迎志同道合的朋友留言交流堰塌,有什么寫的不對的地方敬請指出!