k 近鄰演算法2 識別約會物件

2022-09-11 14:18:26 字數 4238 閱讀 5102

本文主要內容來自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...