本文主要是介绍K Nearest Neighbor,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
KNN算法
概述
KNN算法:即最邻近分类算法(K-NearestNeighbor
算法思路:如果一个样本在特征空间中的k个最相似(即特征空间中最临近)的样本中的大多数属于某一个类别 则该样本也属于这个类别 k通常是不大于20的整数 KNN算法中 所选择的邻居都是已经正确分类的对象 该方法在定义决策上只依据最邻近的一个或几个样本的类别来决定待分样本所属的类别
如上所示
绿色圆要被决定赋予哪个类,是红色三角形还是蓝色四方形?如果K=3,由于红色三角形所占比例为2/3,绿色圆将被赋予红色三角形那个类,如果K=5,由于蓝色四方形比例为3/5,因此绿色圆被赋予蓝色四方形类。由此也说明了KNN算法的结果很大程度取决于K的选择。
在kNN中,计算对象之间的距离通常使用欧氏距离。比如若是求二维平面的欧氏距离,则公式为d = sqrt[(x1 - x2)^2 + (y1 - y2)^2]
KNN算法思路总结:就是在训练集中数据和标签已知的情况下,输入测试数据 将测试数据的特征与训练集中对应的特征进行相互比较 找到训练集中与之最为相似的前K个数据 则该测试数据对应的类别就是K个数据中出现次数最多的那个分类 其算法的描述为:
1. 计算测试数据与各个训练数据之间的距离
2. 按照距离的递增关系进行排序
3. 选取距离最小的K个点
4. 确定前K个点所在类别的出现频率
5. 返回前K个点中出现频率最高的类别作为测试数据的预测分类
import numpy as np
import math
import operator
"""knn算法优化:param dataSet 无量纲化:func knn weight:return 系统体系other:knn logistic regression
"""def createDataSet():group = np.array([[10, 9.2], [8.8, 7.9], [0.1, 1.4], [0.3, 3.5]])labels = ['A', 'A', 'B', 'B']return group, labelsdef normDatafunc(dataSet):print(dataSet)print(np.max(dataSet))print(np.min(dataSet))dataMax = np.max(dataSet)dataMin = np.min(dataSet)dataRange = dataMax - dataMinnormData = (dataSet-dataMin)/dataRangereturn dataRange, dataMin, dataMax, normDatadef normTest(dataMin, dataRange, testSet):test = (testSet-dataMin)/dataRangereturn testdef gaussian(dist, a=1, b=0, c=0.3):return a * np.math.e ** (-(dist - b) ** 2 / (2 * c ** 2))def knnClassify(dataSet, Labels, testSet, k):nrow = np.shape(dataSet)[0]cdiff = np.tile(testSet, (nrow, 1)) - dataSetsqdiff = cdiff ** 2sumdiff = np.sum(sqdiff, axis=1)dist = np.sqrt(sumdiff)print('dist', dist)# knn加权 越近权重越大 越远权重越小 与dist排序相反weightDis = []for i in dist:weightDis.append(gaussian(i, a=1, b=0, c=0.3))print('weightDis', weightDis)weightDis = np.array(weightDis)# weightDis = []# for i in dist:# weightDis.append(gaussian(dist=i, a=1, b=0, c=0.3))indexSorted = np.argsort(-weightDis) # 降序排序print(indexSorted)classCount = {}for i in range(k):vote = Labels[indexSorted[i]]classCount[vote] = classCount.get(vote, 0) + 1# maxCount = 0# for k, v in classCount.items():# if v > maxCount:# maxCount = v# classes = ksortedLabel = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)return sortedLabel[0][0]def main():dataSet, Labels = createDataSet()dataRange, dataMin, dataMax, normData = normDatafunc(dataSet)testSet = [0.0, 0.0]test = normTest(dataMin, dataRange, testSet)k = 3lis = {'A': 'big','B': 'smaller'}print(lis)result = knnClassify(normData, Labels, test, k)print('result is:'+lis[result])if __name__ == '__main__':main()
KNN学习及补充
import math
"""KNN一句话总计:近朱者赤 近墨者黑input: 经过预处理的特征向量对应于特征空间的点 --- 多个类监督分析算法分类时通过多数表决进行预测k近邻算法--没有训练过程 --不具有显式的学程基本要素:k值的选择距离度量分类决策规则案列:爱情片和动作片分类数学原理:欧式距离计算未知与已知之间的距离相似度越高距离越小相似度越低距离越大k: 是自己设置的数训练时间为0 计算时间很多k值:交叉验证优化优缺点:缺点:k值小了 容易过拟合 分得过于细了k值大了可以避免过拟合对最终结果可能有影响缺点:分类决策规则:knn中求取分类最优近邻 是合理的距离加权距离近权重加大距离远权重减小# 学习误差: # 估计误差: 模型估计值与实际之间的差距 训练# 近似误差: 模型估值与实际差距 测试集 消除数据的量纲大小影响---做无量纲化优化归一化:AutoNorm将你需要处理的数据经过处理限制在一定条件范围内方法:1.线性函数转化[0, 1]2.对数函数转化3.反余切函数转化4.输入值转为[-1, 1]样本数据分解:0.1 训练数据0.9 测试数据总体样本数据 用于回归:k个近邻的平均值""""""knn 距离加权的几种方式1. 反函数该方法最简单的形式是返回距离的倒数 完全一样或非常接近的商品权重为会很大因此: 在距离求倒数时 在距离上加一个常量比如距离D 权重为:1/Dweigh = 1/(distance + const)缺点: 为近邻分配很大的权重 使得算法对噪声数据变得敏感2.高斯函数(正态分布)高斯函数在距离为0的时候权重为1,随着距离增大,权重减少,但不会变为0计算加权knn1.在处理离散型数据时,将这k个数据用权重区别对待,预测结果与第n个数据的label相同的概率2.在处理数值型数据时,并不是对这k个数据简单的求平均,而是加权平均:通过将每一项的距离值乘以对应权重,让后将结果累加。求出总和后,在对其除以所有权重之和。"""
# 高斯函数实现方式
def gaussian(dist, a=1, b=0, c=0.3):return a * math.e ** (-(dist - b) ** 2 / (2 * c ** 2))
KNN预测算法
import numpy as np
import operatordef creatDataSet():groups = np.array([[1, 1.1], [1, 0.99], [0.1, 0.02], [0.2, 0.1]])labels = ['A', 'A', 'B', 'B']return groups, labelsdef classify(test, dataSet, labels, k):dataSize = dataSet.shape[0]diff = np.tile(test, (dataSize, 1)) - dataSetstdDiff = diff ** 2stdDis = np.sum(stdDiff, axis=1)sortedIndex = np.argsort(stdDis)classCount = {}for n in range(k):voteLabel = labels[sortedIndex[n]]classCount[voteLabel] = classCount.get(voteLabel, 0) + 1sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)return sortedClassCount[0][0]def test():dataSet, labels = creatDataSet()test = [0.9, 1]result = knnLR(test, dataSet, labels, 2)print(result)def weight(dist, a=1, b=0, c=0.3):return a * np.math.e ** (-(dist - b) ** 2 / (2 * c ** 2))# 回归预测 -- 使用权重
def knnLR(inX,dataset,labels,k):#1,计算距离dataset_size = dataset.shape[0]diff_mat = np.tile(inX,(dataset_size,1))-datasetsqdiff_mat = diff_mat**2sq_distances = sqdiff_mat.sum(axis=1)distances = sq_distances**0.5#2,按递增排序print(distances, 'distances')lis = []for i in distances:lis.append(weight(i, a=1, b=0, c=0.3))print(lis, 'lis')sorted_distances_index = distances.argsort()#3,选择距离最近的前k个点, 取其均值knnpredict = int()for i in range(k):knnpredict += dataset[sorted_distances_index[i]] * lis[sorted_distances_index[i]]knnpredict = knnpredict/kreturn knnpredict#4,返回前k个里面统计的最高次类别作为预测数值# return sorted_class_count[0][0]if __name__ == '__main__':test()
这篇关于K Nearest Neighbor的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!