將每個新資料與樣本集中的每個特徵進行比較,計算距離。把距離遞增排序選取前k個距離最小的點,並統計前k個點的標籤的出現頻率,將出現頻率最高的標籤作為當前資料的**分類。
此處使用歐氏距離公式:
"""函式說明:
建立資料集的例子
引數: 無
返回值:
group:資料集
labels:標籤類別
"""def
createdataset()
: 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分類器,k-近鄰演算法
計算已知類別點和當前點的距離,從前k個距離最小的點中,選取出現頻率最高的類別作為當前點的類別
引數: inx: 用於分類的資料,測試集
dataset: 訓練樣本集
labels: 標籤類別
k: 選取最近鄰近的數目
返回值:
sortclasscount[0][0]: 分類結果
"""def
classify0
(inx, dataset, labels, k)
:# 讀取矩陣第一維的長度,即行數
# 注意是shape[0],不是shape(0)
datasetsize = dataset.shape[0]
# 把inx複製成和dataset相同行數的矩陣, 並作差
diffmat = np.tile(inx,
(datasetsize,1)
)- dataset
# 將作差的結果平方
sqdiffmat = diffmat**
2# 矩陣每行相加
sqdistances = sqdiffmat.
sum(axis=1)
# 結果開方
distance = sqdistances**
0.5# 返回排序的下表索引值
sorteddistindicies = distance.argsort(
)# 選取前k個距離最小的點並用classcount記錄
classcount =
for i in
range
(k):
# 距離最小的標籤
voteilabel = labels[sorteddistindicies[i]
]# 若標籤存在則在標籤基礎上+1,若不存在返回預設值0,即0+1
classcount[voteilabel]
= classcount.get(voteilabel,0)
+1print
(classcount)
sortclasscount =
sorted
(classcount.items(),
key=operator.itemgetter(1)
, reverse=
true
(sortclasscount)
return sortclasscount[0]
[0]"""
函式說明:
開啟檔案,讀取資料資訊
引數: filename: 檔名
返回值 returnmat: 特徵矩陣
classlabelvector: 類別向量
"""def
file2matrix
(filename)
: fr =
open
(filename)
# 讀取檔案所有內容,儲存在列表中
arrayolines = fr.readlines(
) numberofline =
len(arrayolines)
# 建立numberoflines行,3列的0矩陣
returnmat = np.zeros(
(numberofline,3)
) classlabelvector =
index =
0for line in arrayolines:
line = line.strip(
) listfromline = line.split(
)# 將資料的前3列進行提取儲存在returnmat矩陣中,也就是特徵矩陣
returnmat[index,:]
= listfromline[0:
3]int(listfromline[-1
])) index +=
1return returnmat, classlabelvector
"""函式說明:
歸一化數值,將特徵值轉化為0~1區間內的值
公式:newvalue = (oldvalue - min) / (max - min)
引數: dataset: 特徵矩陣
返回值:
normdataset: 歸一化後的特徵矩陣
ranges: 資料範圍
minvals: 最小值
"""def
autonorm
(dataset)
:# 引數 0 可以使函式從列中選取最小值,而不是行
minvals = dataset.
min(0)
maxvals = dataset.
max(0)
ranges = maxvals - minvals
# 建立和 dataset 行列相同的矩陣
normdataset = np.zeros(np.shape(dataset)
)# 獲取 datashape 的行數
m = dataset.shape[0]
# 原始值減去最小值
normdataset = dataset - np.tile(minvals,
(m,1))
# 差值除以ranges
normdataset = normdataset/np.tile(ranges,
(m,1))
return normdataset, ranges, minvals
"""函式說明:
分類器測試
引數: 無
返回值:
無"""def
datingclasstest()
:# horatio 表示取10%的資料用來測試
horatio =
0.1#
datingdatamat, datinglabels = file2matrix(
'datingtestset2.txt'
)# 資料歸一化
normmat, ranges, minvals = autonorm(datingdatamat)
# m為歸一化後矩陣的行數
m = normmat.shape[0]
# numtestvecs 是測試資料的行數
numtestvecs =
int(m*horatio)
# 錯誤次數
errorcount =
0.0for i in
range
(numtestvecs)
:# 前 numtestvecs 個資料作為測試集,剩下的作為訓練集
# normmat[i, :] 返回 normmat 矩陣第i行的全部
classifierresult = classify0(normmat[i,:]
, normmat[numtestvecs:m,:]
, datinglabels[numtestvecs:m],3
("the classifier came back with: %d, the real answer is: %d"
%(classifierresult, datinglabels[i]))
if(classifierresult != datinglabels[i]):
errorcount +=
1.0print
("the total error rate is: %f"
%(errorcount/
float
(numtestvecs)))
# group, labels = createdataset()
# datingdatamat, datinglabels = file2matrix('datingtestset2.txt')
## fig = plt.figure()
# ax = fig.add_subplot(111)
# ax.scatter(datingdatamat[:, 1], datingdatamat[:, 2], 15.0*np.array(datinglabels), 15.0*np.array(datinglabels))
# plt.show()
datingclasstest(
)
k 近鄰演算法
此文章參考機器學習實戰一書,具體的理論知識可以參考該書。本文的初衷只是為了做乙個複習,將學過的知識加以整理,其中不免有一定的錯誤。2.k 近鄰演算法的原理介紹 k 近鄰演算法通過測量不同的特徵值之間的距離進行分類。它的工作原理如下 存在乙個樣本的資料集合,也成為訓練樣本集合。並且樣本集中的每個資料都...
K 近鄰演算法
k 近鄰演算法採用測量不同特徵值之間的距離方法進行分類。優點 精度高 對異常值不敏感 無資料輸入假定 缺點 計算複雜度高 空間複雜度高 適用資料範圍 數值型和標稱型 工作原理 存在乙個樣本資料集合,也稱作訓練樣本集,並且樣本集中每個資料都存在標籤,即我們知道樣本集中每一資料與所屬分類的對應關係。輸入...
K 近鄰演算法
首先,我們將 k 近鄰演算法的基本理論 其次我們將使用python從文字檔案中匯入並解析資料 再次,討論當存在許多資料 的時,如何避免計算距離時可能碰到的一些常見錯誤 最後,利用實際的例子講解如何使用k 近鄰演算法改進約會 1.1 knn演算法 工作原理 存在乙個樣本資料集合,也稱作訓練樣本集,並且...