1. 程式人生 > >《機器學習實戰》中的程序清單2-1 k近鄰算法classify0都做了什麽

《機器學習實戰》中的程序清單2-1 k近鄰算法classify0都做了什麽

列表 關鍵字 難解 items 位置 class 做了 ict top k

def start():
        group,labels = createDataSet()
        return classify0([3,3], group, labels, 4)

def createDataSet():
    group = array([[1,2],[2,3],[1,1],[4,5]]) #此處隨意定義,表示一個已知的已分類的數據集
    labels = [A,A,B,B]
    return group, labels 

def classify0(inX,dataSet,labels,k):
    
""" inX 是輸入的測試樣本,是一個[x, y]樣式的 dataset 是訓練樣本集 labels 是訓練樣本標簽 k 是top k最相近的 """ # 矩陣的shape是個tuple,如果直接調用dataSet.shape,會返回(4,2),即 # 返回矩陣的(行數,列數), # 那麽shape[0]獲取數據集的行數, # 行數就是樣本的數量 # shape[1]返回數據集的列數 dataSetSize = dataSet.shape[0] ###################說明代碼########################
print("dataSet.shape[0]返回矩陣的行數:") print(dataSetSize) cols = dataSet.shape[1] print("dataSet.shape[1]返回矩陣的列數:") print(cols) print(dataSet.shape) print("dataSet.shape類型:") print(type(dataSet.shape)) ################################################### #
此處Mat是Maxtrix的縮寫,diffMat,即矩陣的差,結果也是矩陣 #關於tile函數的說明,見http://www.cnblogs.com/Sabre/p/7976702.html #簡單來說就是把inX(本例是[1,1])在“行”這個維度上,復制了dataSetSize次(本例dataSetSize==4),在“列”這個維度上,復制了1次 #形成[[1,1],[1,1],[1,1],[1,1]]這樣一個矩陣,以便與dataSet進行運算 #之所以進行這樣的運算,是因為要使用歐式距離公式求輸入點與已存在各點的距離 #這是第1步,求給出點[1,1]與已知4點的差,輸出為矩陣 diffMat = tile(inX,(dataSetSize,1)) - dataSet ###################說明代碼######################## print("diffMat:" + str(diffMat)) ################################################### #對矩陣進行平方,即,求差的平方 sqDiffMat = diffMat ** 2 ###################說明代碼######################## print("sqDiffMat:" + str(sqDiffMat)) ################################################### #sum(axis=1)是將矩陣中每一行中的數值相加,如[[0 0] [1 1] [0 1] [9 9]]將得到[0,2,1,18],得到平方和 #sum(axis=0)是將矩陣中每一列中的數值相加 sqDistances = sqDiffMat.sum(axis=1) ###################說明代碼######################## print("sqDistances:" + str(sqDistances)) ################################################### #將平方和進行開方,得到距離,輸出數組 distances = sqDistances ** 0.5 ###################說明代碼######################## print("未知點到各個已知點的距離:",distances) ################################################### #argsort(),將數組中的元素的索引放在由小到大的位置上由小到大排序 #如數組[ 0 2 1 18],argsort之後,得到[0 2 1 3],最小的在最前面,位置0,第二小的是索引為2的元素,即1 #第三小的是索引為1的,即2,第四小的是索引為3的,即18 #這樣保證了原數組元素的位置不變,以便進行標簽的匹配 sortedDistIndicies = distances.argsort() ###################說明代碼######################## print("索引位置:",sortedDistIndicies) ################################################### #創建空字典 classCount = {} #k值是取前k個樣本進行比較 for i in range(k): #返回distances中索引為sortedDistIndicies[i]的值 #此例中分別為: #sortedDistIndicies[0]==0,則labels[0]==‘A‘,voteIlabel==‘A‘ #sortedDistIndicies[1]==2,則labels[2]==‘B‘,voteIlabel==‘B‘ #sortedDistIndicies[2]==1,則labels[0]==‘A‘,voteIlabel==‘A‘ #sortedDistIndicies[3]==18,則labels[0]==‘B‘,voteIlabel==‘B‘ voteIlabel = labels[sortedDistIndicies[i]] ###################說明代碼######################## print("標簽" + str(i) + "" + voteIlabel) ################################################### #dict.get(key, default=None),對於鍵 key 返回其對應的值,或者若 dict 中不含 key 則返回 default(註意, default的默認值為 None) #第一次調用classCount.get時,classCount內還沒有值 classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1 ###################說明代碼######################## print(""+str(i+1)+"次訪問,classCount[" + voteIlabel + "]值為:" + str(classCount[voteIlabel])) print("classCount的內容為:") print(classCount) ################################################### # sorted(iterable[,cmp,[,key[,reverse=True]]]) # 作用:Return a new sorted list from the items in iterable. # 第一個參數是一個iterable,返回值是一個對iterable中元素進行排序後的列表(list)。 # 可選的參數有三個,cmp、key和reverse。 # 1)cmp指定一個定制的比較函數,這個函數接收兩個參數(iterable的元素),如果第一個參數小於第二個參數,返回一個負數;如果第一個參數等於第二個參數,返回零;如果第一個參數大於第二個參數,返回一個正數。默認值為None。 # 2)key指定一個接收一個參數的函數,這個函數用於從每個元素中提取一個用於比較的關鍵字。默認值為None。 # 3)reverse是一個布爾值。如果設置為True,列表元素將被倒序排列。 # operator.itemgetter(1)這個很難解釋,用以下的例子一看就懂 # a=[11,22,33] # b = operator.itemgetter(2) # b(a) # 輸出:33 # b = operator.itemgetter(2,0,1) # b(a) # 輸出:(33,11,22) # operator.itemgetter函數返回的不是值,而是一個函數,通過該函數作用到對象上才能獲取值 # 比較復雜,此處不做過多解釋 sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1), reverse=True) print(sortedClassCount) #返回正序排序後最小的值,即“k個最小相鄰”的值決定測試樣本的類別 print("最終結果,測試樣本類別:" , end="") print(sortedClassCount[0][0]) return sortedClassCount[0][0]

if __name__=="__main__":
    start()

輸出結果:

dataSet.shape[0]返回矩陣的行數:
4
dataSet.shape[1]返回矩陣的列數:
2
(4, 2)
dataSet.shape類型:
<class ‘tuple‘>
diffMat:[[ 2 1]
[ 1 0]
[ 2 2]
[-1 -2]]
sqDiffMat:[[4 1]
[1 0]
[4 4]
[1 4]]
sqDistances:[5 1 8 5]
未知點到各個已知點的距離: [ 2.23606798 1. 2.82842712 2.23606798]
索引位置: [1 0 3 2]
標簽0:A
第1次訪問,classCount[A]值為:1
classCount的內容為:
{‘A‘: 1}
標簽1:A
第2次訪問,classCount[A]值為:2
classCount的內容為:
{‘A‘: 2}
標簽2:B
第3次訪問,classCount[B]值為:1
classCount的內容為:
{‘A‘: 2, ‘B‘: 1}
標簽3:B
第4次訪問,classCount[B]值為:2
classCount的內容為:
{‘A‘: 2, ‘B‘: 2}
[(‘A‘, 2), (‘B‘, 2)]
最終結果,測試樣本類別:A
[Finished in 5.3s]

《機器學習實戰》中的程序清單2-1 k近鄰算法classify0都做了什麽