KNN算法被稱爲 lazy 算法,只有在判斷未知類別的元素時纔會建立模型進行計算。
KNN算法可以分爲以下三步:
1 存儲已知類別的元素。
2 來了一個新的元素後,計算所有已知元素與它的歐式距離。可以採用加權歐氏距離來計算。
3 取出與待分類元素最近的k個類型已知的元素,這個k個元素中大多數元素屬於哪個類別,那麼待分類元素就屬於哪個類別。
怎樣存儲?怎樣使第二步的計算量最少?
例子: 已知一些電影的類別(romance,action), 這些電影爲二維數據(打鬥次數、接吻次數)
電影名稱 | 打鬥次數 | 接吻次數 | 電影類型 |
California Man
|
3 | 104 | Romance |
He’s Not Really into Dudes
|
2 | 100 | Romance |
Beautiful Woman
|
1 | 81 | Romance |
Kevin Longblade
|
101 | 10 | Action |
Robo Slayer 3000
|
99 | 5 | Action |
Amped II
|
98 | 2 | Action |
未知 | 18 | 90 | Unknown |
現在有一個未知的電影類別,怎樣判斷它是action 還是 romance 呢?
按照上面的步驟:
1 先將已知類別的電影儲存起來。
已python語言爲例:
構建一個類,類中對象的元素有:打鬥次數,接吻次數,所屬類別(romance或action),編號(先存儲的編號爲0,然後依次增加)
在類中,有一個全局列表來存儲對象,有一個全局的迭代器來遞增對象的編號,
我們將上面6部電影的對象存儲到列表中。
2 來一個新的元素與K值,要計算它與所有對象的的距離,並取出距離最小額前K個
函數1:計算距離 歐氏距離
函數2:調用函數1 循環遍歷全局列表,並將每個元素與待分類元素的距離存入“距離列表”中,對“距離列表”排序。返回“距離列表”
3 判斷大多數元素的類別
函數3:調用函數3 從“距離列表“中選出大多數元素屬於哪一個類別,然後返回次類別。
附python代碼 按照數據挖掘學習札記:KNN算法(二)中的python代碼仿寫:
from math import sqrt
class Movie:
"""docstring for Movie"""
lib=[]
total=0 # number of movies
def __init__(self, nk, nf, tag):
self.nkiss = nk
self.nfight = nf
self.tag = tag
self.index = len(Movie.lib)+1
Movie.lib.append(self) # append a movie(object) to lib
Movie.total+=1
def distance(self,movie):
if type(self)!=type(movie):
raise TypeError('require type %s, give type %s'% (type(self),type(movie)))
else:
dis=(self.nkiss-movie.nkiss)**2
dis+=(self.nfight-movie.nfight)**2
dis=sqrt(dis)
def neighbors(self,k):
dis=[]
movie_many=[]
for movie in self.lib:
dis.append((movie, self.distance(movie)))
dis.sort(key=lambda dis:dis[1])
for i in range(0,k+1):
movie_many.append(dis[i][0])
return movie_many
def label(self,k=1):
if self.tag == "unknown":
movie_many = self.neighbors(k)
nr=0
na=0
for movie in movie_many:
if movie.tag == "R":
nr+=1
elif movie.tag == "A":
na+=1
else:
raise TypeError('The movie with tag %d is not a training data'% movie.tag)
if nr>na:
tag="R"
elif nr<na:
tag="A"
else:
tag="known"
return tag
if __name__ == '__main__':
Movie(3,104,'R')
Movie(2,100,'R')
Movie(1,81,'R')
Movie(101,10,'A')
Movie(99,5,'A')
Movie(98,2,'A')
test=Movie(18,90,'unknown')
print "begin test"
print "test.label: " , test.label(1)