数据挖掘-KNN-K最近邻算法

 1. 算法核心思想:

     通过计算每个训练样本到待分类样本的距离,选取和待分类样本的距离最近的 K 个训练样本,K个样本中那个类别的训练样本占据着多数, 则表明待分类的样本就属于哪一个类别。

    KNN算法在类别的决策中, 只与极少数的相邻样本相关。因此,对于类别的样本交叉或重叠较多的待分类样本集来说, KNN较其他算法较为适合。KNN算法的结果很大程度取决于K的选择。

    K值得取值一般低于训练数据样本数的平方根

 

1.1:欧式距离,曼哈顿距离和余弦距离:

上图分别为 欧式距离, 曼哈顿距离和余弦距离

1.欧式距离又称欧几里得距离欧几里得度量(Euclidean Metric),以空间为基准的两点之间最短距离 :

2.曼哈顿距离又称马氏距离(Manhattan distance),还见到过更加形象的,叫出租车距离的。

3.

余弦距离,也称为余弦相似度,是用向量空间中两个向量夹角的余弦值作为衡量两个个体间差异的大小的度量。

向量,是多维空间中有方向的线段,如果两个向量的方向一致,即夹角接近零,那么这两个向量就相近。而要确定两个向量方向是否一致,这就要用到余弦定理计算向量的夹角。

采用哪种距离度量方法对最终结果有很大影响。例如,你的数据集有很多特征,但是如果任
意一对个体之间的欧氏距离都相等,那么你就没法通过欧氏距离进行比较了!曼哈顿距离在某些
情况下具有更高的稳定性,但是如果数据集中某些特征值很大,用曼哈顿距离的话,这些特征会
掩盖其他特征间的邻近关系。最后,再来说说余弦距离,它适用于特征向量很多的情况,但是它
丢弃了向量长度所包含的在某些场景下可能会很有用的一些信息。    from:blog

 

         

2.其算法的描述为:

1)计算测试数据与各个训练数据之间的距离;

2)按照距离的递增关系进行排序;

3)选取距离最小的K个点;

4)确定前K个点所在类别的出现频率;

5)返回前K个点中出现频率最高的类别作为测试数据的预测分类。

3.算法实现

#coding=gbk
import numpy as np
import operator
import pandas as pd import matplotlib.pyplot as plt def createDateset(): #创建数据集 dataset =np.array([[1.0,2.0],[1.2,0.1],[0.1,1.4],[0.3,3.5]]) labels = ['A','A','B','B'] return dataset,labels # dataset =array([[1.0,2.0],[1.2,0.1],[0.1,1.4],[0.3,3.5]]) # print(dataset.shape) #(4, 2) # print(dataset.shape[0]) #4 输出有4组数据,shape[1]返回数组的列数 a = np.array([0,1,2]) b = np.tile(a,(2,2)) print(b) # [[0 1 2 0 1 2] #将a 看做是一个整体,打印出2行2列的数据 # [0 1 2 0 1 2]] print(b.sum(axis = 1)) #[6 6] 输出每一列的和 #定义一个函数KNN def classify(input, dataset, labels, k): datasize = dataset.shape[0] #计算欧式距离 diffMat = np.tile(input, (datasize,1)) - dataset #将输入的数据与样本数据相减 sqdmax = diffMat ** 2 #计算每个样本与输入数据的距离的平方和,按列求和 sqdDistance = sqdmax.sum(axis =1 ) #取根号.得到一列的数组,得到每个数据点与输入数据点的欧式距离 distances = sqdDistance ** 0.5 print('distances:', distances) sortDistances = distances.argsort() #依据元素的大小按索引进行排序, print('sortDistances:',sortDistances) classCount = {} #创建字典 for i in range(k): #取出前k项的类别 voteLabel = labels[sortDistances[i]] print('第%d个的类别是:',i,voteLabel) #找出输入点距离最近点的label #计算类别的次数 # dict.get(key,default=None),字典的get()方法,返回指定键的值,如果值不在字典中返回默认值。 classCount[voteLabel] = classCount.get(voteLabel, 0)+ 1 #key=operator.itemgetter(1)根据字典的值进行排序 #key=operator.itemgetter(0)根据字典的键进行排序 sortedClassCount = sorted(classCount.items(),key = operator.itemgetter(1),reverse = True) print('sortedClassCount:',sortedClassCount) return sortedClassCount[0][0] #if __name__ == '__main__': # labels = np.array(labels).reshape(4,1) # print(dataset) # print(labels) # data = np.concatenate([dataset,labels],axis = 1) # print(data) # plt.axis([0,3,0,3]) # plt.scatter(data[:2,0],data[:2,1],color ='red', marker='o', label='A') # plt.scatter(data[2:,0],data[2:,1],color ='green', marker='+', label='B') # plt.legend(loc =2) # plt.show() dataset,labels = createDateset() input = [1.1,2.4] test_class = classify(input, dataset, labels, 3) print(test_class) # distances: [0.41231056 2.30217289 1.41421356 1.36014705] # sortDistances: [0 3 2 1] # 第%d个的类别是: 0 A # sortedClassCount: [('A', 1)] # A #代表新的样本是属于A类的 print('---------') print("dict.get()方法和operator.itemgetter()方法的练习") demo_k =['a','b','a','a'] d = {} for i in demo_k: d[i] = d.get(i,0)+1 print(d) # 输出 {'a': 3, 'b': 1} ,可用于计算,类别的次数 sorted_d = sorted(d.items(), key = operator.itemgetter(1),reverse =False) #将值按从小到大进行排序 print(sorted_d) #[('b', 1), ('a', 3)] print(sorted_d[0][0]) #b 得到类别 

4.算法的优缺点:

 

scikit-learn 中KNN 的参数:

neighbors.KNeighborsClassifier(n_neighbors=5,
 weights=’uniform’, algorithm=’auto’, leaf_size=30, p=2, 
metric=’minkowski’, metric_params=None, n-jobs=1)

1. n_neighbors 就是 kNN 里的 k,就是在做分类时,我们选取问题点最近的多少个最近邻。

2.weights 是在进行分类判断时给最近邻附上的加权,默认的 'uniform' 是等权加权,

 'distance' 选项是按照距离的倒数进行加权,也可以使用用户自己设置的其他加权方法。

3.algorithm 是分类时采取的算法,有 'brute'、'kd_tree' 和 'ball_tree'。kd_tree 的 kd 树,而 ball_tree 是另一种基于树状结构的 kNN 算法,brute 则是最直接的蛮力计算。根据样本量的大小和特征的维度数量,不同的算法有各自的优势。默认的 'auto' 选项会在学习时自动选择最合适的算法,所以一般来讲选择 auto 就可以。

4.leaf_size 是 kd_tree 或 ball_tree 生成的树的树叶(树叶就是二叉树中没有分枝的节点)的大小。在 kd 树文章中我们所有的二叉树的叶子中都只有一个数据点,但实际上树叶中可以有多于一个的数据点,算法在达到叶子时在其中执行蛮力计算即可。对于很多使用场景来说,叶子的大小并不是很重要,我们设 leaf_size=1 就好。

5.metric 和 p,是距离函数的选项,如果 metric ='minkowski' 并且 p=p 的话,计算两点之间的距离就是

 

d((x1,…,xn),(y1,…,yn))=(∑i=1n|xi−yi|p)1/p

 

一般来讲,默认的 metric='minkowski'(默认)和 p=2(默认)就可以满足大部分需求。其他的 metric 选项可见说明文档。metric_params 是一些特殊 metric 选项需要的特定参数,默认是 None。

 

6.n_jobs 是并行计算的线程数量,默认是 1,输入 -1 则设为 CPU 的内核数。

函数方法:

neighbors.KNeighborsClassifier.fit(X,y)

对数据集进行预测

neighbors.kNeighborsClassifier.predict(X)

输出预测概率:

neighbors.kNeighborsClassifier.predict_proba(X)

正确率打分

neighbors.KNeighborsClassifier.score(X, y, sample_weight=None)

 

 

 

 

 

 

 

#coding=gbk
#KNN算法实现对电影类型的分类
import numpy as np
from sklearn import neighbors
knn = neighbors.KNeighborsClassifier()
data = np.array([[3,104],[2,100],[1,81],[101,10],[99,5],[98,2]])
labels = ['A','A','A','B','B','B']
labels = np.array(labels)
knn.fit(data,labels)
c= knn.predict([[18,90]])  #看清楚括号的顺序
print(c)        
print(knn.predict_proba([[18,90]]))
# ['A']预测为浪漫的电影
# [[0.6 0.4]]

 

转载于:https://www.cnblogs.com/junge-mike/p/9335027.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据挖掘是一种通过从大量数据中发现模式、关联和规律来提取有用信息的技术。KNN(K-最近算法是一种常用的分类算法,它基于特征之间的距离度量,通过选择离样本最近的K个居来进行分类。 对于酒的质量判断问题,我们可以采集酒的相关特征作为输入数据,如酒的品种、酒精度、酸度、挥发性酸度等。然后,利用已经打上质量标签(高质量或低质量)的样本数据构建一个训练集,其中包含了特征和对应的质量标签。 在实际应用中,我们将未标记的酒样本作为测试集,对于每个未标记的样本,通过计算其与训练集中样本的距离,选取最接近的K个样本。然后,通过统计这K个样本质量标签的频率,来决定该酒样本的质量高低。 例如,如果K=5,那么对于一个未标记的酒样本,如果其最近的5个居中有3个标记为高质量,2个标记为低质量,则我们可以预测该酒的质量为高质量。 不过需要注意的是,KNN算法在应用中需要严格考虑特征的选择、数据预处理和距离度量等问题,以提高分类的准确度。此外,模型的性能和泛化能力也需要经过适当的评估和调优。 总之,数据挖掘利用KNN算法可以对酒的质量进行判断。通过根据输入的特征和训练数据构建模型,使用K个最近居的质量标签来预测酒的质量高低。但是在实际应用中还需要注意选择合适的特征和进行适当的数据处理,以提高算法的准确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值