K 近鄰演算法

2021-07-10 08:00:46 字數 4381 閱讀 4822

首先,我們將**k-近鄰演算法的基本理論;其次我們將使用python從文字檔案中匯入並解析資料;再次,討論當存在許多資料**的時,如何避免計算距離時可能碰到的一些常見錯誤;最後,利用實際的例子講解如何使用k-近鄰演算法改進約會**。

1.1 knn演算法

工作原理:存在乙個樣本資料集合,也稱作訓練樣本集,並且樣本集中每個資料都存在標籤,即我們知道樣本集中每一資料與所屬分類的對應關係。輸入沒有標籤的新資料後,將新資料的每個特徵與樣本集中資料對應的特徵進行比較,然後演算法提取樣本集中特徵最相似資料的分類標籤。最後,選擇k個最相似資料中出現次數最多的分類,作為新資料的分類。

程式清單1-1:k近鄰演算法

def

classify0

(inx,dataset,labels,k):

datasetsize = dataset.shape[0]

diffmat = tile(inx,(dataset,1))-dataset

sqdiffmat = diffmat**2

sqdistances = sqdiffmat.sum(axis = 1) #將乙個矩陣的每行的行向量相加

distances = sqdistances**0.5

sorteddistindicies = distances.argsort() #返回陣列值從小到大的索引值

classcount = {}

for i in range(k):

votedilabel = labels[sorteddistindicies[i]]

classcount[votedilabel] = classcount.get(votedilabel,0)+1

sortedclasscount = sorted(classcount.iteritems(),key = operator.itemgetter(1),reverse = true) #返回乙個給定的key對應的值,如果key是沒有的,然後返回0

return sortedclasscount[0][0]

classify0()函式有4個輸入引數:用於分類的輸入向量inx,輸入的訓練樣本集為dataset,標籤向量為labels,最後的引數k表示用於選擇最近鄰居的數目。使用歐式距離公式計算兩個向量點的距離。sortedclasscount按照第二個元素的次序對元組進行排序。此處的排序為逆序,即按照從最大到最小次序排序,最後返回發生頻率最高的元素標籤。

在將特徵資料輸入到分類器之前,必須將待處理資料的格式改變為分類器可以接受的格式。

程式清單1-2:將文字記錄轉換為numpy的解析程式

def

file2matrix

(filename):

fr = open(filename)

arrayolines = fr.readlines()

numberoflines = len(arrayolines)

returnmat = zeros((numberoflines,3))

classlabelvector =

index = 0

for line in numberoflines:

line = line.strip() #擷取掉所有的回車字元

listfromline = line.split('\t') #使用tab字元\t將上一步得到的整行資料分隔成乙個元素列表

returnmat[index,:] = listfromline[0:3]

index += 1

return returnmat,classlabelvector

該函式的輸入為檔名字串,輸出為訓練樣本矩陣和類標籤向量。

1.2.2 準備資料:歸一化數值

我們很容易發現,數字差值最大的屬性對計算結果的影響最大。在處理這種不同取值範圍的特徵值時,我們通常採用的方法是將數值歸一化,如將取值範圍處理為0到1或者-1到1之間。

程式清單1-3: 歸一化特徵值

def

autonorm

(dataset):

minvals = dataset.min(0) #引數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))

return normdataset,ranges,minvals

autonorm()函式中,我們將每列的最小值放在變數minvals中,將最大值放在變數maxvals中。然後函式計算可能的取值範圍,並建立新的返回矩陣。為了歸一化特徵值,我們必須使用當前值減去最小值,然後除以取值範圍。

1.2.3 測試演算法:作為完整程式驗證分類器

def

datingclasstest

(): horatio = 0.10

datingdatamat,datinglabels = file2matrix('datingtestset.txt')

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 classifer 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))

它使用file2matrix和autonorm函式從檔案中讀取資料並將其轉換為歸一化特徵值。接著計算測試向量的數量,此步決定了normmat向量中哪些資料用於測試,哪些資料用於分類器的訓練樣本;然後將這兩部分資料輸入到原始knn分類器函式classify0,最後,函式計算錯誤率並輸出結果。

1.2.4 使用演算法:構建完整可用系統

def

classifyperson

(): resultlist = ['not at all','in small doses','in large doses']

percenttats = float(raw_input("percentage of time spent playing video games?"))

ffmiles = float(raw_input("frequent flier miles earned per year?"))

icecream = float(raw_input("liters of ice cream consumed per year?"))

datingdatamat,datinglabels = file2matrix('datingtestset2.txt')

normmat,ranges,minvals = autonorm(datingdatamat)

inarr = array([ffmiles,percenttats,icecream])

classifierresult = classify0((inarr-minvals)/ranges,normmat,datinglabels,3)

print

"you will probably like this person:",resultlist[classifierresult - 1]

print classifyperson()

大部分**我們在前面都見過,唯一新加入的**是函式raw_input()。該函式允許使用者輸入文字行命令並返回使用者所輸入的命令。

(還可以構造使用k近鄰分類器的手寫識別系統,因為時間有限,這裡不做具體介紹,等有時間再繼續撰寫手寫識別系統的各個步驟實現…….)

k 近鄰演算法

此文章參考機器學習實戰一書,具體的理論知識可以參考該書。本文的初衷只是為了做乙個複習,將學過的知識加以整理,其中不免有一定的錯誤。2.k 近鄰演算法的原理介紹 k 近鄰演算法通過測量不同的特徵值之間的距離進行分類。它的工作原理如下 存在乙個樣本的資料集合,也成為訓練樣本集合。並且樣本集中的每個資料都...

K 近鄰演算法

k 近鄰演算法採用測量不同特徵值之間的距離方法進行分類。優點 精度高 對異常值不敏感 無資料輸入假定 缺點 計算複雜度高 空間複雜度高 適用資料範圍 數值型和標稱型 工作原理 存在乙個樣本資料集合,也稱作訓練樣本集,並且樣本集中每個資料都存在標籤,即我們知道樣本集中每一資料與所屬分類的對應關係。輸入...

K 近鄰演算法

k 近鄰演算法 有點 精度高,對異常值不敏感,無資料輸入假定。缺點 計算複雜度高,空間複雜度高。使用範圍 數值型和標稱型。python from numpy import def createdataset group array 1.0,1.1 1.0,1.0 0.0,0.0 0.0,0.1 la...