機器學習(基于Python)--k-近鄰算法

前提基礎

安裝好Numpy庫

基礎知識:

(1)numpy.tile

import numpy

numpy.tile([1,2],(1,2))

Out[3]:

array([[1, 2, 1, 2]])

numpy.tile([1,2],(2,2))

numpy.tile([1,2],(2,2))//第一個參數(shù)是重復的數(shù) 第二個參數(shù)(行,列)重復的次數(shù)

Out[4]:

array([[1, 2, 1, 2],

[1, 2, 1, 2]])

2.shape

numpy.shape([[1,2],[2,2]])

Out[21]:

(2, 2)

numpy.shape(a)

Out[22]:

(3, 2)

a

Out[23]:

[[1.0, 1.1], [1, 1.0], [0.0, 1.0]]

a是一個矩陣

返回3行 2列

shape函數(shù)是numpy.core.fromnumeric中的函數(shù),它的功能是讀取矩陣的長度,比如shape[0]就是讀取矩陣第一維度的長度。

3.平方 開方

1**2Out[24]: 14**2#4的平方Out[25]: 1616**0.5#開方Out[26]: 4.0

4.argsort()

x=numpy.array([1,2,3,-1,5])

x.argsort()

Out[28]:

array([3, 0, 1, 2, 4], dtype=int64)

我們發(fā)現(xiàn)argsort()函數(shù)是將x中的元素從小到大排列,提取其對應的index(索引),然后輸出到y(tǒng)。 注意輸出的是索引

5.

operator.itemgetter函數(shù)

operator模塊提供的itemgetter函數(shù)用于獲取對象的哪些維的數(shù)據(jù),參數(shù)為一些序號??聪旅娴睦?/p>

a = [1,2,3]

>>> b=operator.itemgetter(1)? ? ? //定義函數(shù)b,獲取對象的第1個域的值

>>> b(a)

2

>>> b=operator.itemgetter(1,0)? //定義函數(shù)b,獲取對象的第1個域和第0個的值

>>> b(a)

(2, 1)

要注意,operator.itemgetter函數(shù)獲取的不是值,而是定義了一個函數(shù),通過該函數(shù)作用到對象上才能獲取值。

sorted函數(shù)用來排序,sorted(iterable[, cmp[, key[, reverse]]])

其中key的參數(shù)為一個函數(shù)或者lambda函數(shù)。所以itemgetter可以用來當key的參數(shù)

a = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]

根據(jù)第二個域和第三個域進行排序

sorted(students, key=operator.itemgetter(1,2))

6.sorted()

sorted(...)

sorted(iterable, cmp=None, key=None, reverse=False)--> new sorted list

iterable:是可迭代類型;

cmp:用于比較的函數(shù),比較什么由key決定;

key:用列表元素的某個屬性或函數(shù)進行作為關(guān)鍵字,有默認值,迭代集合中的一項;

reverse:排序規(guī)則. reverse = True ?降序 或者 reverse = False 升序,有默認值。

返回值:是一個經(jīng)過排序的可迭代類型,與iterable一樣。

參數(shù)說明:

(1) ?cmp參數(shù)

cmp接受一個函數(shù),拿整形舉例,形式為:

def f(a,b):

return a-b

如果排序的元素是其他類型的,如果a邏輯小于b,函數(shù)返回負數(shù);a邏輯等于b,函數(shù)返回0;a邏輯大于b,函數(shù)返回正數(shù)就行了

(2) ?key參數(shù)

key也是接受一個函數(shù),不同的是,這個函數(shù)只接受一個元素,形式如下

def f(a):

return len(a)

key接受的函數(shù)返回值,表示此元素的權(quán)值,sort將按照權(quán)值大小進行排序

(3) reverse參數(shù)

接受False 或者True 表示是否逆序

例子:

按照元素長度排序

L = [{1:5,3:4},{1:3,6:3},{1:1,2:4,5:6},{1:9}]

deff(x):

returnlen(x)

sort(key=f)

printL

輸出:

[{1: 9}, {1: 5, 3: 4}, {1: 3, 6: 3}, {1: 1, 2: 4, 5: 6}]

K-近鄰算法

2.7:

#coding utf-8

from numpy import *

import operator

def createDataSet():

group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])

labels = ['A','A','B','B']

return group,labels

def classsify0(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):

voteIlable = labels[sortedDistIndicies[i]]

classCount[voteIlable] = classCount.get(voteIlable,0) + 1

sortedClassCount = sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)

return sortedClassCount[0][0]

if __name__ == '__main__':

group,labels = createDataSet()

a= classsify0([0,0],group,labels,3)

print(a)

3

#coding utf-8

from numpy import *

import operator

def createDataSet():

group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])

labels = ['A','A','B','B']

return group,labels

def classsify0(inx,dataset,labels,k):

datasetSize = dataset.shape[0]

diffMat = tile(inx,(datasetSize,1)) - dataset

sqDiffMat = diffMat**2

sqDistances = sqDiffMat.sum(axis=1)#1 按行求和 0按列求和? 這樣得到距離的計算

distances = sqDistances**0.5

sortedDistIndicies = distances.argsort()

classCount = {}

for i in range(k):

voteIlable = labels[sortedDistIndicies[i]]

classCount[voteIlable] = classCount.get(voteIlable,0) + 1

sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)

return sortedClassCount[0][0]

if __name__ == '__main__':

group,labels = createDataSet()

a= classsify0([0,0],group,labels,3)

print(a)

將文本記錄轉(zhuǎn)換NumPy的解析程序

def file2matrix(filename):

fr = open(filename)

arrayOflines =fr.readline()

numberOflines = len(arrayOflines)

returnMat = zeros((numberOflines,3))

classLabelVector = []

index = 0

for line in arrayOflines:

line = line.strip()

listFromLine = line.split('\t')

returnMat[index,:] = listFromLine[0:3]

classLabelVector.append(int(listFromLine[-1]))

index += 1

return returnMat,classLabelVector

----------------------------------------------10.29更新--------------------------------------------------

k近鄰算法的一般流程

收集數(shù)據(jù):可以使用任何方法。

準備數(shù)據(jù):距離計算所需要的數(shù)值,最好是結(jié)構(gòu)化的數(shù)據(jù)格式。

分析數(shù)據(jù):可以使用任何方法。

訓練算法:此步驟不適用于k近鄰算法。

測試算法:計算錯誤率。

使用算法:首先需要輸入樣本數(shù)據(jù)和結(jié)構(gòu)化的輸出結(jié)果,然后運行k近鄰算法判定輸入數(shù)據(jù)分別屬于哪個分類,最后應用對計算出的分類執(zhí)行后續(xù)的處理。

向量labels包含了每個數(shù)據(jù)點的標簽信息,labels包含的元素個數(shù)等于group矩陣行數(shù)。

例子:把一個32x32的二進制圖像矩陣轉(zhuǎn)換為1x1024的向量

from numpy import *

def img2vector(filename):

#創(chuàng)建向量

returnVect = zeros((1,1024))

#打開文件夾

fr = open(filename)#32行

for i in range(32):#讀取每一行

lineStr = fr.readline()#一行有32個數(shù)據(jù)

for j in range(32):將每行前32字符轉(zhuǎn)成int存入向量returnVect[0,32*i+j] = int(lineStr[j])

return returnVect

計算“距離”

算法實現(xiàn)過程:

計算已知類別數(shù)據(jù)集中的點與當前點之間的距離;

按照距離遞增次序排序;

選取與當前點距離最小的k個點;

確定前k個點所在類別的出現(xiàn)頻率;

返回前k個點出現(xiàn)頻率最高的類別作為當前點的預測分類。

算法實現(xiàn)為函數(shù)classify0(),函數(shù)的參數(shù)包括:

inX:用于分類的輸入向量

dataSet:輸入的訓練樣本集

labels:樣本數(shù)據(jù)的類標簽向量

k:用于選擇最近鄰居的數(shù)目

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容