KNN算法的个人理解

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)




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值