首页 > 编程语言 >简单易学的机器学习算法——K-近邻算法

简单易学的机器学习算法——K-近邻算法

时间:2023-06-14 21:02:56浏览次数:55  
标签:近邻 算法 train result test 训练样本 易学


一、近邻算法(Nearest Neighbors)




1、近邻算法的概念




近邻算法(Nearest Neighbors)是一种典型的非参模型,与生成方法(generalizing method)不同的是,在近邻算法中,通过以实例的形式存储所有的训练样本,假设有m个训练样本:

简单易学的机器学习算法——K-近邻算法_待分类

此时需要存储这m个训练样本,因此,近邻算法也称为基于实例的模型。

    对于一个需要预测的样本,通过与存储好的训练样本比较,以较为相似的样本的标签作为近邻算法的预测结果。


2、近邻算法的分类




在近邻算法中,根据处理的问题的不同,可以分为:


  • 近邻分类算法
  • 近邻回归算法

在本篇博文中,主要介绍近邻分类算法。


注意:除了上述的监督式近邻算法,在近邻算法中,还有一类非监督的近邻算法。




二、近邻分类算法




1、近邻分类算法的概念




    在近邻分类算法中,对于预测的数据,将其与训练样本进行比较,找到最为相似的K个训练样本,并以这K个训练样本中出现最多的标签作为最终的预测标签。


    在近邻分类算法中,最主要的是K-近邻算法。


2、KNN算法概述




    K-NN算法是最简单的分类算法,主要的思想是计算待分类样本与训练样本之间的差异性,并将差异按照由小到大排序,选出前面K个差异最小的类别,并统计在K个中类别出现次数最多的类别为最相似的类,最终将待分类样本分到最相似的训练样本的类中。与投票(Vote)的机制类似。

3、样本差异性




    比较常用的差异性计算方法为欧式距离。

欧式距离:样本

简单易学的机器学习算法——K-近邻算法_ci_02


与样本

简单易学的机器学习算法——K-近邻算法_ci_03


之间的欧式距离为:


简单易学的机器学习算法——K-近邻算法_ci_04



4、KNN算法的流程

  • 求预测样本与训练样本之间的相似性
  • 依据相似性排序
  • 选择前K个最为相似的样本对应的类别
  • 得到预测的分类结果

三、K-近邻算法实现




1、Python实现






   以手写字体MNIST的识别为例,对于测试集中的每一个样本预测其类别,对于手写字体,如下图所示:


简单易学的机器学习算法——K-近邻算法_机器学习_05


k_nn.py




# coding:UTF-8

import cPickle as pickle
import gzip
import numpy as np

def load_data(data_file):
	with gzip.open(data_file, 'rb') as f:
		train_set, valid_set, test_set = pickle.load(f)
	return train_set[0], train_set[1], test_set[0], test_set[1]

def cal_distance(x, y):
	return ((x - y) * (x - y).T)[0, 0]

def get_prediction(train_y, result):
	result_dict = {}
	for i in xrange(len(result)):
		if train_y[result[i]] not in result_dict:
			result_dict[train_y[result[i]]] = 1
		else:
			result_dict[train_y[result[i]]] += 1
	predict = sorted(result_dict.items(), key=lambda d: d[1])
	return predict[0][0]

def k_nn(train_data, train_y, test_data, k):
	# print test_data
	m = np.shape(test_data)[0]  # 需要计算的样本的个数
	m_train = np.shape(train_data)[0]
	predict = []
	
	for i in xrange(m):
		# 对每一个需要计算的样本计算其与所有的训练数据之间的距离
		distance_dict = {}
		for i_train in xrange(m_train):
			distance_dict[i_train] = cal_distance(train_data[i_train, :], test_data[i, :])
		# 对距离进行排序,得到最终的前k个作为最终的预测
		distance_result = sorted(distance_dict.items(), key=lambda d: d[1])
		# 取出前k个的结果作为最终的结果
		result = []
		count = 0
		for x in distance_result:
			if count >= k:
				break
			result.append(x[0])
			count += 1
		# 得到预测
		predict.append(get_prediction(train_y, result))
	return predict

def get_correct_rate(result, test_y):
	m = len(result)
	
	correct = 0.0
	for i in xrange(m):
		if result[i] == test_y[i]:
			correct += 1
	return correct / m	

if __name__ == "__main__":
	# 1、导入
	print "---------- 1、load data ------------"
	train_x, train_y, test_x, test_y = load_data("mnist.pkl.gz")
	# 2、利用k_NN计算	
	train_x = np.mat(train_x)
	test_x = np.mat(test_x)
	print "---------- 2、K-NN -------------"
	result = k_nn(train_x, train_y, test_x[:10,:], 10)
	print result
	# 3、预测正确性
	print "---------- 3、correct rate -------------"
	print get_correct_rate(result, test_y)




当取K=10时,对测试集中的10个数据样本的最终的预测准确性为:70%,预测值为:[7, 2, 1, 0, 9, 1, 9, 9, 8, 9],原始值为[7 2 1 0 4 1 4 9 5 9]。




2、Scikit-leanrn库

在Scikit-learn库中对K-NN算法有很好的支持,核心程序为:


clf = neighbors.KNeighborsClassifier(n_neighbors)
clf.fit(X, y)


四、K-NN算法中存在的问题及解决方法

1、计算复杂度的问题




       在K-NN算法中,每一个预测样本需要与所有的训练样本计算相似度,计算量比较大。比较常用的方法有K-D树,局部敏感哈希等等




2、K-NN的均匀投票




       在上述的 K-NN 算法中,最终对标签的选择是通过投票的方式决定的,在投票的过程中,每一个训练样本的投票的权重是相等的,可以对每个训练样本的投票加权,以期望最相似的样本有更高的决策权。



参考文献


1、1.6. Nearest Neighbors点击打开链接


标签:近邻,算法,train,result,test,训练样本,易学
From: https://blog.51cto.com/u_16161414/6481098

相关文章

  • 简单易学的机器学习算法——朴素贝叶斯
    一、贝叶斯定理  1、条件概率B发生的情况下,事件A发生的概率,用表示。  2、全概率公式     含义是:如果和构成样本空间的一个划分,那么事件B的概率,就等于和的概率分别乘以B对这两个事件的条件概率之和。  3、贝叶斯推断        其中称为先验概率,即......
  • 简单易学的机器学习算法——极限学习机(ELM)
    一、极限学习机的概念    极限学习机(ExtremeLearningMachine)ELM,是由黄广斌提出来的求解单隐层神经网络的算法。    ELM最大的特点是对于传统的神经网络,尤其是单隐层前馈神经网络(SLFNs),在保证学习精度的前提下比传统的学习算法速度更快。二、极限学习机的原理EL......
  • 简单易学的机器学习算法——Logistic回归
    一、Logistic回归的概述  Logistic回归是一种简单的分类算法,提到“回归”,很多人可能觉得与分类没什么关系,Logistic回归通过对数据分类边界的拟合来实现分类。而“回归”也就意味着最佳拟合。要进行最佳拟合,则需要寻找到最佳的拟合参数,一些最优化方法就可以用于最佳回归系数的确......
  • 优化算法——遗传算法
    与遗传算法的第一次接触遗传算法是我进入研究生阶段接触的第一个智能算法,从刚开始接触,到后来具体去研究,再到后来利用遗传算法完成了水利水电的程序设计比赛,整个过程中对遗传算法有了更深刻的理解,在此基础上,便去学习和研究了粒子群算法,人工蜂群算法等等的群体智能算法。想利用这个时......
  • 简单易学的机器学习算法——因子分解机(Factorization Machine)
    一、因子分解机FM的模型    因子分解机(FactorizationMachine,FM)是由SteffenRendle提出的一种基于矩阵分解的机器学习算法。1、因子分解机FM的优势    对于因子分解机FM来说,最大的特点是对于稀疏的数据具有很好的学习能力。现实中稀疏的数据很多,例......
  • 优化算法——模拟退火算法
    模拟退火算法原理爬山法是一种贪婪的方法,对于一个优化问题,其大致图像(图像地址)如下图所示:其目标是要找到函数的最大值,若初始化时,初始点的位置在处,则会寻找到附近的局部最大值点处,由于点出是一个局部最大值点,故对于爬山法来讲,该算法无法跳出局部最大值点。若初始点选择在处,根据爬......
  • 挑战数据结构和算法面试题——最大间隔
    分析:本题首先需要理解清楚最大间隔的最小:最初的间隔为:[1,1,4,1],此时最大间隔为4删除2后的间隔为:[2,4,1],此时最大间隔为4删除3后的间隔为:[1,5,1],此时最大间隔为5删除7后的间隔为:[1,1,5],此时最大间隔为5在删除元素后的间隔为:[4,5,5],最小值为:4方法:intget_min_max_margin(int*a,constintn){......
  • 挑战数据结构和算法——栈的push、pop序列
    题目来源“数据结构与算法面试题80道”。在此给出我的解法,如你有更好的解法,欢迎留言。问题分析:本题考查栈的基本操作,栈是一种“先进后出”的数据结构。判断一个序列是否是栈的pop序列是一种常见的问题,可以通过模拟push和pop的过程,push和pop总是成对出现的,如:方法:#definepush1#def......
  • 【数据结构和算法面试题】跳台阶问题
    题目来源“数据结构与算法面试题80道”。问题分析:假设为跳台阶的总跳法,当时,;当时,;当时,如果先跳1级台阶,有种方法,如果先跳2级台阶,有种方法,依次类推,可以得到下面的递推公式:方法:intget_kind(intn){ if(n<=0)return0; intresult; int*cal=(int*)malloc(sizeof(int)*n);......
  • 挑战数据结构和算法——整数的二进制表示中1的个数
    题目来源“数据结构与算法面试题80道”。在此给出我的解法,如你有更好的解法,欢迎留言。问题分析:本题涉及到二进制的处理,在本题使用到&操作和>>操作。方法:intget_num(intn){intnum=0;if(n<0){num+=1;n=n*(-1);}while(n!=0){......