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)