約會網站

4、 任務分析

  西普收集的約會數據在/home/soft/KNN/datingTestSet.txt。根據分析,每一個樣本數據佔據一行,總共1000行,樣本數據包含3中特徵:一、每一年得到的飛行常客里程數;二、玩視頻遊戲所消耗的時間百分比;三、每週消耗的冰淇淋公升數。didntLike表明不喜歡;smallDoses表明魅力通常;largeDoses表明極具魅力。python

 

 ♥ 知識連接
K-近鄰算法完整流程

一、收集數據:網絡爬蟲、第三方提供的免費及收費數據
二、準備數據:使用Python解析、預處理數據
三、分析數據:對數據進行可視化
四、測試算法:計算錯誤率
五、使用算法:錯誤率在接受範圍內,運行算法進行分類

5、 任務實施

步驟一、環境準備算法

  右擊Ubuntu操做系統桌面,從彈出菜單中選擇【Open in Terminal】命令 打開終端。vim

  經過【cd /home】切換到home目錄下。【ls】查看該目錄下的全部內容。如圖1所示。數組

圖1 切換目錄

  【mkdir KNN】在home目錄下建立KNN文件夾。如圖2所示。網絡

圖2 建立文件夾

步驟二、數據解析app

  【cd KNN】切換目錄,【cp /home/soft/KNN/datingTestSet.txt /home/KNN/】將數據集複製到該目錄下,【head -n 10 datingTestSet.txt】查看前十行的數據。如圖3所示。機器學習

  樣本數據包含3中特徵:一、每一年得到的飛行常客里程數;二、玩視頻遊戲所消耗的時間百分比;三、每週消耗的冰淇淋公升數。didntLike表明不喜歡;smallDoses表明魅力通常;largeDoses表明極具魅力。學習

圖3 數據分析

  【vim kNN_date.py】回車後建立並編輯名爲kNN_date的Python文件。如圖4所示。測試

圖4 建立Python文件

  回車後進入編輯框內,按鍵盤【i】進入編輯狀態,編譯以下程序。如圖5所示。網站

  對數據進行解析,將數據分類成兩部分,既特徵矩陣和對應的分類標籤。

圖5 數據解析

  在main方法內定義文件信息,調用處理數據的方法,將方法返回的特徵矩陣和分類標籤打印。如圖6所示。

圖6 main方法

  編輯完畢後,按【esc】退出編輯狀態,【:wq】保存並退出編輯框,【python kNN_date.py】執行kNN_date的Python文件。如圖7所示。

圖7 運行Python文件

步驟三、數據歸一化

  約會網站樣本數據。如圖8所示。

圖8 樣本數據

  想要計算樣本3和樣本4之間的距離,可使用歐拉公式計算。如圖9所示。

圖9 公式

  在計算中發現數字差值最大的屬性對計算結果的影響最大。在處理這種不一樣取值範圍的特徵值時,採用的方法是將數值歸一化。將取值範圍處理爲0到1或者-1到1之間。
公式爲:newValue = (oldValue - min) / (max - min)

  再次進入kNN_date.py文件編輯狀態,修改程序。如圖10所示。

  以數據矩陣爲參數根據公式求出數值歸一化的特徵矩陣、數據範圍、最小值。

圖10 歸一化數據

  在main內調用歸一化的方法,並將數據處理後獲得的數據矩陣做爲參數,輸出數值歸一化的特徵矩陣、數據範圍、最小值。如圖11所示。

圖11 main方法

  編輯完畢後,按【esc】退出編輯狀態,【:wq】保存並退出編輯框,【python kNN_date.py】執行kNN_date的Python文件。如圖12所示。

  控制檯分別打印歸一化後的特徵矩陣、數據範圍、最小值

圖12 運行Python文件

步驟四、驗證分類器

  機器學習算法最重要的工做就是評估算法的正確率,一般提供已有數據的90%做爲訓練樣原本訓練分類器,10%數據測試分類器。

  再次進入kNN_date.py文件編輯狀態,修改程序。如圖13所示。

  建立分類器(導入運算符模塊【import operator】)。

圖13 分類器

  測試分類器,90%做爲訓練集,10%做爲測試集。如圖14所示。

圖14 測試分類器

  在main內調用測試分類器的方法。如圖15所示。

圖15 main方法

  編輯完畢後,按【esc】退出編輯狀態,【:wq】保存並退出編輯框,【python kNN_date.py】執行kNN_date的Python文件。如圖16所示。

  根據結果得知錯誤率是3%。是一個在能夠接受的範圍之類。

圖16 main方法

步驟五、構建系統

  給西普一個程序,經過該程序西普在約會網站找到並輸入某我的的信息。程序會判斷出對該男生的預測值。

  再次進入kNN_date.py文件編輯狀態,修改程序。如圖17所示。

  分別獲取玩視頻遊戲所佔的時間百分比、每一年得到飛行常客里程數、每週消費的冰淇淋公升數的值。對數據集進行處理,數據集歸一化,並生成測試集,對測試集歸一化,以後對數據進行分類。返回分類的結果。

  在main方法內調用classifyPerson()方法。

圖17 完善系統

  編輯完畢後,按【esc】退出編輯狀態,【:wq】保存並退出編輯框,【python kNN_date.py】執行kNN_date的Python文件。如圖18所示。

  分別輸入玩視頻遊戲所佔的時間百分比爲20、每一年得到飛行常客里程數爲52000、每週消費的冰淇淋公升數爲1。得知西普很是喜歡這我的。

 

圖18 運行Python程序

步驟六、源碼

  1 #coding:utf-8
  2 import numpy as np
  3 import operator
  4 def file2matrix(filename):
  5     fr = open(filename) #打開文件
  6     arrayOLines = fr.readlines() #讀取文件全部內容
  7     numberOfLines = len(arrayOLines) #獲得文件行數
  8     returnMat = np.zeros((numberOfLines,3)) #生成numberOfLines行,3列數據
  9     classLabelVector = [] #分類標籤向量
 10     index = 0 #行的索引值
 11     for line in arrayOLines:
 12         line = line.strip() #默認刪除空白符
 13         listFromLine = line.split('\t') #將字符串根據'\t'分隔符進行切片
 14         returnMat[index,:] = listFromLine[0:3] #將數據前三列提取出來,存放到returnMat的Numpy矩陣
 15         #根據文本中標記的喜歡的程度進行分類,1表明不喜歡,2表明魅力通常,3表明極具魅力
 16         if listFromLine[-1] == 'didntLike':
 17             classLabelVector.append(1)
 18         elif listFromLine[-1] == 'smallDoses':
 19             classLabelVector.append(2)
 20         elif listFromLine[-1] == 'largeDoses':
 21             classLabelVector.append(3)
 22         index += 1
 23     return returnMat,classLabelVector 
 24 """
 25 dataSet:特徵矩陣
 26 """
 27 def autoNorm(dataSet):
 28     #得到數據的最小、最大值
 29     minVals = dataSet.min(0)
 30     maxVals = dataSet.max(0)
 31     #最大值和最小值的範圍
 32     ranges = maxVals - minVals #最大值和最小值的範圍
 33     normDataSet = np.zeros(np.shape(dataSet)) #生成與dataSet相同矩陣行列數
 34     m = dataSet.shape[0] #返回dataSet的行數
 35     normDataSet = dataSet - np.tile(minVals,(m,1))  #原始值減去最小值
 36     normDataSet = normDataSet / np.tile(ranges,(m,1))  #除以最大和最小值的差,獲得歸一化數據
 37     #返回歸一化數據結果,數據範圍,最小值
 38     return normDataSet,ranges,minVals
 39 """
 40 分類器
 41 inX:測試集
 42 dataSet:訓練集
 43 label:分類標籤
 44 k:距離最小的k個點
 45 """
 46 def classify0(inX,dataSet,labels,k):
 47     dataSetSize = dataSet.shape[0] #返回dataSet的行數
 48     diffMat = np.tile(inX,(dataSetSize,1)) - dataSet #生成四組二維已知預測數據與樣本數據集相減
 49     sqDiffMat = diffMat**2 #二維特徵相減後的平方
 50     sqDistances = sqDiffMat.sum(axis=1) #sum()全部元素相加,sum(1)行相加
 51     distances = sqDistances**0.5 #開方,計算出距離
 52     sortedDistIndices = distances.argsort() #返回從小到大排序後的索引值
 53     classCount = {} #記錄類別次數的字典
 54     for i in range(k):
 55         voteIlabel = labels[sortedDistIndices[i]] #取出前k個元素的類別
 56         classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1  #計算類別次數
 57     #operator.itemgetter(1)根據字典的值進行排序
 58     #reverse降序排序字典
 59     sortedClassCount = sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)
 60     return sortedClassCount[0][0] #返回次數最多的類別,及索要分類的類別
 61 """
 62 分類器測試
 63 """
 64 def datingClassTest():
 65     filename = "datingTestSet.txt" #文件名
 66     #將返回的特徵矩陣和分類向量分別存儲到datingdataMat和datingLabels中
 67     datingDataMat, datingLabels = file2matrix(filename)
 68     hoRatio = 0.10 #取全部數據的百分之十
 69     #數據歸一化,返回歸一化的矩陣,數據範圍,數據最小值
 70     normMat, ranges, minVals = autoNorm(datingDataMat)
 71     m = normMat.shape[0] #得到normMat的行數
 72     numTestVecs = int(m * hoRatio) #百分之十的測試數據的個數
 73     errorCount = 0.0 #分類錯誤計數
 74     for i in range(numTestVecs):
 75         #前numTestVecs個數據做爲測試集,後m-numTestVecs個數據做爲訓練集
 76         classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],4)
 77         print "分類結果:%d\t真實類別:%d" %(classifierResult,datingLabels[i])
 78         if classifierResult != datingLabels[i]:
 79             errorCount += 1.0
 80     print "錯誤率:%f%%"%(errorCount/float(numTestVecs) * 100)
 81 def classifyPerson():
 82     resultList = ['討厭','有些喜歡','很是喜歡'] #輸出結果
 83     #三維特徵用戶輸入
 84     precentTats = float(raw_input("玩視頻遊戲所耗時間百分比:"))
 85     ffmiles = float(raw_input("每一年得到的飛行常客里程數:"))
 86     iceCream = float(raw_input("每週消費的冰淇淋公升數:"))
 87     filename = "datingTestSet.txt" #文件名
 88     #打開並處理數據
 89     datingDataMat,datingLabels = file2matrix(filename)
 90     #訓練集歸一化
 91     normMat,ranges,minVals = autoNorm(datingDataMat)
 92     #生成Numpy數組,測試集
 93     inArr = np.array([ffmiles,precentTats,iceCream])
 94     #測試集歸一化
 95     norminArr = (inArr-minVals) / ranges
 96     #返回分類結果
 97     classifierResult = classify0(norminArr,normMat,datingLabels,3)
 98     #打印結果
 99     print "你可能%s這我的" % (resultList[classifierResult-1])
100 if __name__ == '__main__':
101     classifyPerson()
相關文章
相關標籤/搜索