天天看點

機器學習實戰中的KNN算法

"""
k-近鄰算法采用不同特征值之間的距離方法進行分類
優點:精度高,對異常值不敏感,無資料輸入假定
缺點:計算複雜度高,空間複雜度高
适用資料範圍:數值型與标稱型
工作原理:存在一個資料集合,也稱作訓練資料集,并且樣本集中每個資料都有标簽,即我們知道樣本集中每一資料與
所屬分類的對應關系。輸入沒有标簽的新資料後,将新資料的每個特征與樣本集中資料對應的特征進行比較,然後算法
提取樣本集中特征最相似資料(最近鄰)的分類标簽。一般來書,我們隻選擇樣本資料集中前k個最相似的資料,這就
是最近鄰算法中k的出處,通常k是不大于20的整數。最後,選擇k個最相似資料中出現次數最多的分類,作為新資料
的分類。

"""
import numpy as np  # 科學計算包
import operator  # 運算符子產品

def creatDataSet():
    group = np.array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])
    labels = ['A', 'A', 'B', 'B']
    return group, labels

"""
KNN算法僞代碼
(1)計算已知類别資料集中的點與目前點之間的距離
(2)按照距離遞增順序排序
(3)選取與目前點距離最小的K個點
(4)确定前K個點所在類别的出現頻率
(5)傳回前K個點出現頻率最高的類别作為目前點的預測類别
"""
def classify0(inX, dataSet, labels, k):
    dataSetSize = dataSet.shape[0]  # shape:幾行幾列(元組) ,這裡指資料的行數
    # np.tile:将inX在列方向上重複1次,行向量上重複dataSetSize次
    diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet
    sqDiffMat = diffMat ** 2
    sqDistance = sqDiffMat.sum(axis=1)
    distance = sqDistance ** 0.5
    # argsort: 用來傳回數組值從小到大索引值(先排序,然後找其在原數組中的索引值)
    sortedDistIndicies = distance.argsort()
    classCount = {}
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        #dict.get(key, default=None)  傳回指定鍵的值,如果指定鍵不存在,傳回預設值None
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1 # 對A或者B出現的次數進行技數
    sortedClassCount = sorted(classCount.items(), key= operator.itemgetter(1), reverse= True)
    return sortedClassCount[0][0]
group, labels = creatDataSet()
a = classify0([0, 0], group, labels, 3)
      

print(a) # B

下面對程式中一些部分進行細緻的學習

numpy.tile()

"""
numpy.tile(A, (x,y))
A: array_alike
x: 對A來說,在行方向上重複X次
y: 對A來說,在列方向上重複y次
"""
import numpy as np
arr = [1,2,3]
arr1 = np.tile(arr, 2)  # 如果隻有一個的話,預設為列方向的
arr2 = np.tile(arr, (2, 3))
print('arr1: ',arr1)  # [1 2 3 1 2 3]
print('arr2: ',arr2)  # n [[1 2 3 1 2 3 1 2 3], [1 2 3 1 2 3 1 2 3]]      

argsort()

"""
argsort: 用來傳回數組值從小到大索引值(先排序,然後找其在原數組中的索引值)
"""
import numpy as np
a = np.array([2, 6, 1, 5])
b = a.argsort() # a.sort() -->  1,2,5,6
print(a) #[[2,6,1,5]]
print(b) #[2,0,3,1]      

sort()

"""
排序有兩種:
1:sort,在本地進行排序,不傳回副本
2:sorted,傳回副本,原始輸入不變
sorted(iterable,cmp=None,key=None,reverse=False)
iterable:可疊代類型
cmp:用于比較的函數,比較什麼由key決定
key:用清單元素的某個屬性或者函數作為關鍵字,有預設值,疊代集合中的一項
reverse:排序規則
"""
#  sortedClassCount = sorted(classCount.items(), key= operator.itemgetter(1), reverse= True)
#  operator.itemgetter(x) 擷取對象x個域的值
import operator
a = [1,2,3]
b = operator.itemgetter(1)
print(a) #[1,2,3]
print(b) # operator.itemgetter(1)
print(b(a)) # 2      

繼續閱讀