本文主要內容來自peter harrington的《machine learning in action》的中文版本《機器學習實戰》
本文中資料和**在這裡
任務——海倫一直在約會**上尋找合適的約會物件,但**推薦的約會物件並不都合她心意。她把曾約會過的物件分為三個型別:毫無魅力、魅力一般、極具魅力,然後收集到一些有益資料,我們將根據她收集到的資料建立分類器,幫助她把**推薦的約會物件劃分到切確的類。
識別約會物件的k-近鄰演算法
分析資料:使用matplotlib畫二維散點圖
訓練演算法:此步驟不適合k-近鄰演算法
測試演算法:利用留出法把海倫提供的資料,隨機提取10%作為測試資料,並統計錯誤率。
使用演算法:利用分類器,根據海倫輸入的特徵資料,對約會物件進行判斷
海倫收集的資料在datingtestset2.txt
中,每個樣本資料佔一行,總共1000行。海倫的樣本主要包含以下三種特徵:
由於資料在文字檔案datingtestset2.txt
中,我們需要解析文字檔案,把資料轉化為分類器可接受的格式。
##轉換文字資料
def filetomatrix(filename):
file = open(filename) #讀入檔案
lines = file.readlines() #按行讀取
numberoflines = len(lines) #統計行數
datingmatrix = zeros((numberoflines, 3)) #約會物件特徵矩陣
datinglabels = #約會物件型別向量
index = 0
for line in lines:
line = line.strip() #去除首尾空格
listfromline = line.split('\t') #使用tab字元把整行資料分割為資料列表
datingmatrix[index, :] = listfromline[0:3] #把前三個資料儲存到物件特徵矩陣
index += 1
return datingmatrix, datinglabels
filetomatrix
把文字中的資料,轉化輸出到物件特徵矩陣datingmatrix
和約會物件型別向量datinglabels
中。
我們寫乙個測試程式
import knn
datingmatrix, datinglabel = knn.filetomatrix('datingtestset2.txt')
print(datingmatrix)
print(datinglabel)
執行結果如下
[[4.0920000e+04 8.3269760e+00 9.5395200e-01]
[1.4488000e+04 7.1534690e+00 1.6739040e+00]
[2.6052000e+04 1.4418710e+00 8.0512400e-01]
...[2.6575000e+04 1.0650102e+01 8.6662700e-01]
[4.8111000e+04 9.1345280e+00 7.2804500e-01]
[4.3757000e+04 7.8826010e+00 1.3324460e+00]]
[3, 2, 1, 1, 1, 1, 3, 3, 1, 3, 1, 1, 2, ....2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 1, 3, 3, 3]
我們使用二維散點圖來分析資料,其中黃色點表示極具魅力,藍色表示魅力一般,紫色表示毫無魅力
通過三張散點圖,我們發現前兩個特徵更容易區分資料點從屬的類別。
由於三個特徵資料之間數值相差很大,而海倫認為三者同等重要,所以我們需要進行歸一化處理。
我們利用公式\(newvalue = (oldvalue-min)/(max-min)\),其中\(min\)和\(max\)是最小特徵值和最大特徵值。
把約會物件的特徵資料歸一化
def normdatingdata(dataset):
minvals = dataset.min(0)
maxvals = dataset.max(0)
ranges = maxvals - minvals
normdataset = zeros(shape(dataset))
rows = dataset.shape[0]
normdataset = dataset - tile(minvals, (rows, 1))
normdataset = normdataset/tile(ranges, (rows, 1))
return normdataset, minvals, ranges
利用留出法進行測試,並計算錯誤率
def datingclasstest():
horatio = 0.10 # 留出法10%
datingmatrix, datinglabels = filetomatrix('datingtestset2.txt') # 讀資料
normmat = normdatingdata(datingmatrix)
rows = normmat.shape[0]
numtestvecs = int(rows * horatio)
errorcount = 0.0
for i in range(numtestvecs):
classifierresult = classify0(normmat[i, :], normmat[numtestvecs:rows, :], datinglabels[numtestvecs:rows], 3)
print("分類器返回結果: %d, 真正的結果: %d" % (classifierresult, datinglabels[i]))
if (classifierresult != datinglabels[i]): errorcount += 1.0
print("錯誤率: %f" % (errorcount / float(numtestvecs)))
執行結果:
分類器返回結果: 3, 真正的結果: 3
分類器返回結果: 2, 真正的結果: 2
分類器返回結果: 1, 真正的結果: 1
分類器返回結果: 1, 真正的結果: 1
分類器返回結果: 1, 真正的結果: 1
分類器返回結果: 1, 真正的結果: 1
...分類器返回結果: 2, 真正的結果: 2
分類器返回結果: 1, 真正的結果: 1
分類器返回結果: 3, 真正的結果: 3
分類器返回結果: 3, 真正的結果: 3
分類器返回結果: 2, 真正的結果: 2
分類器返回結果: 1, 真正的結果: 1
分類器返回結果: 3, 真正的結果: 1
錯誤率: 0.050000
對單個約會物件進行分類
def classifyperson():
resultlist = ['毫無魅力', '魅力一般', '極具魅力']
ffmiles = float(input("每年獲得的飛行常客里程數:"))
icecream = float(input("每週消費的冰淇淋公升數:"))
datingmatrix, datinglabels = filetomatrix('datingtestset2.txt')
normmat, minvals, ranges = normdatingdata(datingmatrix)
person = array([ffmiles, percenttats, icecream])
normperson = (person-minvals)/ranges
classifierresult = classify0(normperson, normmat, datinglabels, 5)
print("此人魅力值:", resultlist[classifierresult-1])
執行結果
每年獲得的飛行常客里程數:40000
每週消費的冰淇淋公升數:1
此人魅力值: 極具魅力
手寫識別系統(k 近鄰演算法)
k 近鄰演算法 knn 是機器學習中乙個相對比較簡單的演算法。該演算法在訓練集中資料和標籤已知的情況下,輸入測試資料,將測試資料的特徵與訓練集中對應的特徵進行相互比較 比如通過歐氏距離 找到訓練集中與之最為相似的前k個資料,則該測試資料對應的類別就是k個資料中出現次數最多的那個分類,其演算法的描述為...
k 近鄰演算法 手寫識別系統
手寫數字是32x32的黑白影象。為了能使用knn分類器,我們需要把32x32的二進位制影象轉換為1x1024 from numpy import 匯入科學計算包numpy和運算子模組operator import operator from os import listdir def img2vec...
機器學習 k 近鄰演算法(手寫字識別)
knn演算法在簡單二維資料上計算時 d 根號 x0 x 2 y0 y 2 這裡被推廣到1024維,將32 32二進位制當成1 1024的向量。計算上和二維是一樣的。缺點是計算量太大了。usr bin python coding utf 8 用knn識別手寫數字 from numpy import i...