採用測量不同特徵值之間的距離
優點:精度高、對異常值不敏感、無資料輸入假定。
缺點:計算複雜度高、空間複雜度高。
適用資料範圍:數值型和標稱型。
工作原理:
存在乙個樣本資料集,也稱作訓練樣本集,並且樣本集中每個資料都存在標籤,即我們知道樣本集中每一資料與所屬分類的對應關係。
輸入沒有標籤的新資料後,將新資料的每個特徵與樣本集中資料對應的特徵進行比較,然後演算法提取樣本集中特徵最相似資料的分類標籤。
只選擇樣本資料集中前k個最相似的資料,這就是
k-近鄰演算法中
k的出處。一般小於20。
最後,選擇k個最相似資料中出現次數最多的分類,作為新資料的分類。
# -*- coding: utf-8 -*-
from numpy import *
import operator
import matplotlib
import matplotlib.pyplot as plt
'''k 臨近演算法:
(1)計算已知類別資料集中的點與當前點之間的距離
(2)按照距離遞增次序排序
(3)選取與當前點距離最小的k個點
(4)確定前
k個點所在類別的出現頻率
(5)返回前
k個點出現頻率最高的類別最為當前點的**分類
'''def classify(inx, dataset, label, k):
datasetsize = dataset.shape[0]
diffmat = tile(inx, (datasetsize,1)) - dataset # tile(
a,n)函式,
a沿各維度重複n次數
sqdiffmat = diffmat**2 # **2 表示平方,
**3表示立方
sqdistances = sqdiffmat.sum(axis=1) # axis =1表示每一行向量相加
0表示每一列
distances = sqdistances**0.5
#argsort()函式是將
x中的元素從小到大排列,提取其對應的
index(索引)
,然後輸出到y。
sorteddistindicies = distances.argsort()
classcount={}
for i in range(k):
voteilabel = label[sorteddistindicies[i]]
classcount[voteilabel] = classcount.get(voteilabel,0) + 1
sortedclasscount=sorted(classcount.items(),key=operator.itemgetter(1), reverse=true)
return sortedclasscount[0][0]
開啟檔案,轉為對應的格式
'''def file2matrix(filename):
fr=open(filename)
arraylines=fr.readlines() #讀取所有的內容,分析成行
numberoflines = len(arraylines) #n行
returnmat = zeros((numberoflines,3)) # 3列
n行初始化為
0classlabelvoctor =
index = 0
for line in arraylines:
line = line.strip() #移除頭尾空格
listformline = line.split('\t') #根據空格切割
returnmat[index,:]=listformline[0:3] # 行數,前3列
index+=1
return returnmat,classlabelvoctor
歸一化處理
'''def autonorm(dataset):
minvals = dataset.min(0) # 每一列的最小值
maxvals = dataset.max(0)
ranges = maxvals- minvals
normdataset = zeros(shape(dataset)) #shape(dataset) 讀取 長度、列數
m =dataset.shape[0] # 長度(行數)
=1000
normdataset = dataset - tile(minvals,(m,1)) # [ 0 0 0.00156] 重複
1000
行normdataset = normdataset/(tile(ranges, (m, 1)))
return normdataset,ranges , minvals
'''# 判斷錯誤率
'''def datingclasstest():
horatio = 0.10
datingdatamat,datinglabels = file2matrix('datingtestset2.txt')
normmat,ranges , minvals = autonorm(datingdatamat) #歸一化處理
m = normmat.shape[0]
numtestvecs = int(m*horatio)
errorcount = 0.0
for i in range(numtestvecs): # 前numtestvecs個作為測試,後面的作為訓練
classifierresult =classify(normmat[i,:],normmat[numtestvecs:m,:],\
datinglabels[numtestvecs:m],3)
print ("the guess :%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)))
#根據輸入進行判斷,並輸出結果
def classifyperson():
resultlist =['not at all','in small doses','in large deses']
percentdats = float(input('percentage of time spent plating video games?'))
ffmiles = float(input('frequent flier miled earned per year?'))
icecream = float(input('liters if ice cream consumed per year?'))
datingdatamat ,datinglabels =file2matrix('datingtestset2.txt')
normmat, ranges, minvals = autonorm(datingdatamat)
inarr =array([ffmiles,percentdats,icecream]) # 封裝
classifierresult = classify((inarr-minvals)/ranges,normmat,datinglabels,3) # 進行判斷
print ("you will probably like this person :",resultlist[classifierresult -1 ])
classify函式的引數:
inx:用於分類的輸入向量
dataset:訓練樣本集合
labels:標籤向量
k:k-
近鄰演算法中的
kshape:是
array
的屬性,描述乙個多維陣列的維度
tile(
inx, (datasetsize,1)
):把inx
二維陣列化,
datasetsize
表示生成陣列後的行數,
1表示列的倍數。整個這一行**表示前乙個二維陣列矩陣的每乙個元素減去後乙個陣列對應的元素值,這樣就實現了矩陣之間的減法,簡單方便得不讓你佩服不行!
axis=1:引數等於
1的時候,表示矩陣中行之間的數的求和,等於
0的時候表示列之間數的求和。
argsort():對乙個陣列進行非降序排序
classcount.get(numoflabel,0) + 1:這一行**不得不說的確很精美啊。
get()
:該方法是訪問字典項的方法,即訪問下標鍵為
numoflabel
的項,如果沒有這一項,那麼初始值為
0。然後把這一項的值加
1。所以
python
中實現這樣的操作就只需要一行**,實在是很簡潔高效。
機器學習演算法02 K近鄰演算法實戰
摘要 本文主要介紹knn演算法的原理和實列。包括演算法描述 演算法缺點 演算法概述。若乙個樣本在特徵空間中的k個最相似 即特徵空間中最鄰近 的樣本的大多數是屬於類別a,則該樣本也是屬於a類。已存在乙個帶標籤的資料庫,對輸入沒有標籤的新資料後。將新資料的每個特徵與樣本集中資料對應的特徵進行比較,然後演...
機器學習 02 K近鄰模型
機器學習02 k近鄰模型 k近鄰的主要思想就是首先將資料分為訓練資料集和測試資料集。然後用訓練資料集來建立模型。通過判斷測試資料到其他訓練資料集中的歐式距離然後排序,選取離測試資料點最近的k個資料,然後根據這k個資料的類別及多數表決原則,來決定此測試點的資料類別。接下來是具體例項 這裡僅用乙個測試點...
機器學習實戰 k 臨近演算法(一)
工作原理 存在乙個樣本資料集合,也稱為訓練樣本集,並且樣本集中每個資料都存在標籤,即我們知道樣本集中每一資料與所屬分類的對應關係。輸入沒有標籤的新資料後,將新資料的每個特徵與樣本集中資料對應的特徵進行比較,然後演算法提取樣本集中特徵最相似資料 最鄰近 的分類標籤。一般來說,我們只選擇樣本資料集中前k...