机器学习(Machine Learning)算法总结-K临近算法

时间:2022-09-10 22:10:56

一、算法详解

1.什么是K临近算法

  • Cover 和 Hart在1968年提出了最初的临近算法
  • 属于分类(classification)算法
  • 邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。
  • 所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。
  • kNN算法的核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。
  • 该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。
  • kNN方法在类别决策时,只与极少量的相邻样本有关。
  • 由于kNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,kNN方法较其他方法更为适合。
  • 输入基于实例的学习(instance-based learning),懒惰学习(lazy learning)

2.算法流程

对每一个未知点执行:(为了判断未知实例的类别,以所有已知类别的实例作为参照)

    • 选择参数 K
    • 计算未知点到所有已知类别点的距离
    • 按距离排序(升序)
    • 选取与未知点离得最近的K个的点
    • 统计k个点中各个类别的个数
    • 根据少数服从多数的投票法则,上述k个点里类别出现频率最高的作为未知点的类别

3. 算法细节-关于K的计算

K:临近数,即在预测目标点时取几个临近的点来预测。

K值得选取非常重要,因为:

  • 如果当K的取值过小时,一旦有噪声得成分存在们将会对预测产生比较大影响,例如取K值为1时,一旦最近的一个点是噪声,那么就会出现偏差,K值的减小就意味着整体模型变得复杂,容易发生过拟合;
  • 如果K的值取的过大时,就相当于用较大邻域中的训练实例进行预测,学习的近似误差会增大。这时与输入目标点较远实例也会对预测起作用,使预测发生错误。K值的增大就意味着整体的模型变得简单;
  • 如果K==N的时候,那么就是取全部的实例,即为取实例中某分类下最多的点,就对预测没有什么实际的意义了;
  • K的取值尽量要取奇数,以保证在计算结果最后会产生一个较多的类别,如果取偶数可能会产生相等的情况,不利于预测。

K的取法:

  • 常用的方法是从k=1开始,使用检验集估计分类器的误差率。重复该过程,每次K增值1,允许增加一个近邻。选取产生最小误差率的K。
  • 一般k的取值不超过20,上限是n的开方,随着数据集的增大,K的值也要增大。

4. 算法细节-关于距离的计算

距离就是平面上两个点的直线距离

关于距离的度量方法,常用的有:欧几里得距离、余弦值(cos), 相关度 (correlation), 曼哈顿距离 (Manhattan distance)或其他。

在KNN中,通过计算对象间距离来作为各个对象之间的非相似性指标,避免了对象之间的匹配问题,在这里距离一般使用欧氏距离或曼哈顿距离:

欧氏距离:

机器学习(Machine Learning)算法总结-K临近算法

曼哈顿距离:

机器学习(Machine Learning)算法总结-K临近算法

5.算法优缺点

优点:
  简单有效、易理解、易于实现,无需估计参数,无需训练
  适合对稀有事件进行分类
  特别适合于多分类问题,KNN比SVM表现要好

缺点:
  需要大量空间储存所有的已知实例。(k近邻需要保存全部数据集,因此对内存消耗大,当数据集较大时对设备要求非常高)
  算法计算量较大(需要计算每个未知点到全部已知点的距离,可能会很耗时 )
  当样本分布不平衡时,比如其中一类样本过大(实例数量过多)占主导的时候,新的未知实例容易被归为这个主导样本(因为这类样本实例的数量过大,但这个新的未知实例实际并未接近目标样本)

针对上述缺点,采用权值得方法,根据距离加上权重,比如1/d(d:距离),这样一来,距离越近,所占的比重就会增加。

二、利用sklearn中模块实现KNN

1. 数据集的介绍

  • Iris数据集是常用的分类实验数据集,由Fisher, 1936收集整理。
  • Iris也称鸢尾花卉数据集,是一类多重变量分析的数据集。
  • 数据集包含150个数据集,分为3类,每类50个数据,每个数据包含4个属性。
  • 可通过花萼长度,花萼宽度,花瓣长度,花瓣宽度4个属性预测鸢尾花卉属于(Setosa,Versicolour,Virginica)三个种类中的哪一类。

iris以鸢尾花的特征作为数据来源,常用在分类操作中。该数据集由3种不同类型的鸢尾花的50个样本数据构成。其中的一个种类与另外两个种类是线性可分离的,后两个种类是非线性可分离的。
该数据集包含了5个属性:

& Sepal.Length(花萼长度),单位是cm;
& Sepal.Width(花萼宽度),单位是cm;
& Petal.Length(花瓣长度),单位是cm;
& Petal.Width(花瓣宽度),单位是cm;
& 种类:Iris Setosa(山鸢尾)、Iris Versicolour(杂色鸢尾),以及Iris Virginica(维吉尼亚鸢尾)。

2.利用sklearn中的KNN库实现KNN

scikit-learn 中KNN相关的类库概述
在scikit-learn 中,与近邻法这一大类相关的类库都在sklearn.neighbors包之中。
KNN分类树的类是KNeighborsClassifier,KNN回归树的类是KNeighborsRegressor。
除此之外,还有KNN的扩展,即限定半径最近邻分类树的类RadiusNeighborsClassifier和限定半径最近邻回归树的类RadiusNeighborsRegressor, 以及最近质心分类算法NearestCentroid。

sklearn中自带iris的数据集,可以直接调用来实现分类功能

代码实现:

from sklearn import neighbors
from sklearn import datasets
knn = neighbors.KNeighborsClassifier() #调用KNN分类器
iris = datasets.load_iris() #载入iris数据集
print("featureList: " + "\n" + str(iris.data))
print("labelList: " + "\n" + str(iris.target))
knn.fit(iris.data, iris.target) #将数据传入Knn分类器
predictedLabel = knn.predict([[0.1, 0.2, 0.3, 0.4]]) #进行预测
print ("predictedLabel is : " + str(predictedLabel)) #打印预测结果

三、利用Python程序自己实现KNN

 import csv
import random
import math
import operator #载入数据集
def loadDataset(filename, split, trainingSet=[], testSet=[]):
with open (filename) as csvfile:
lines = csv.reader(csvfile)
dataset = list(lines)
for x in range(len(dataset)-1):
for y in range(4):
dataset[x][y] = float(dataset[x][y])
if random.random() < split: #通过split比较,随机将数据集分成训练集(占约三分之二)和测试集(占约三分之一)
trainingSet.append(dataset[x])
else:
testSet.append(dataset[x]) #计算任意两个实例间的欧氏距离
def euclideanDistance(instance1, instance2, length):
distance = 0
for x in range(length): #实现任意维度距离的计算
distance += pow((instance1[x]-instance2[x]), 2)
return math.sqrt(distance) #获取待测实例最临近的K个已知点
def getNeighbors(trainingSet, testInstance, k):
distances = []
length = len(testInstance)-1
for x in range(len(trainingSet)):
dist = euclideanDistance(testInstance, trainingSet[x], length) #计算每一个待测实例与已知实例的欧氏距离
distances.append((trainingSet[x], dist))
distances.sort(key=operator.itemgetter(1)) #list.sort(*, key=None, reverse=None),sort()是Python列表的一个内置的排序方法,key是带一个参数的函数,返回一个值用来排序,默认为 None。reverse表示排序结果是否反转
neighbors = []
for x in range(k):
neighbors.append(distances[x][0])
return neighbors #每一个测试实例所对应的分类结果根据临近样本的结果进行获取(少数服从多数原则)
def getResponse(neighbors):
classVotes = {}
for x in range(len(neighbors)):
response = neighbors[x][-1] #测试实例周围已知实例的结果获取
if response in classVotes:
classVotes[response] += 1
else:
classVotes[response] = 1
sortedVotes = sorted(classVotes.items(), key=operator.itemgetter(1), reverse=True)
return sortedVotes[0][0] #测试集准确率的计算
def getAccuracy(testSet, predictions):
correct = 0
for x in range(len(testSet)):
if testSet[x][-1] == predictions[x]:
correct += 1
return (correct/float(len(testSet)))*100.0 def main():
trainingSet = []
testSet = []
split = 0.70
loadDataset(r'irisdata.txt', split, trainingSet, testSet) #数据集载入
print('Train set: ' + repr(len(trainingSet)))
print('Test set: ' + repr(len(testSet))) predictions = []
k = 3 #选3个临近的样本点
for x in range(len(testSet)):
neighbors = getNeighbors(trainingSet, testSet[x], k)
result = getResponse(neighbors)
predictions.append(result)
print('>predicted=' + repr(result) + ', actual=' + repr(testSet[x][-1]))
accuracy = getAccuracy(testSet, predictions)
print('Accuracy: ' + repr(accuracy) + '%') if __name__ == '__main__':
main()

执行结果:

Train set: 106
Test set: 44
>predicted='Iris-setosa', actual='Iris-setosa'
>predicted='Iris-setosa', actual='Iris-setosa'
>predicted='Iris-setosa', actual='Iris-setosa'
>predicted='Iris-setosa', actual='Iris-setosa'
>predicted='Iris-setosa', actual='Iris-setosa'
>predicted='Iris-setosa', actual='Iris-setosa'
>predicted='Iris-setosa', actual='Iris-setosa'
>predicted='Iris-setosa', actual='Iris-setosa'
>predicted='Iris-setosa', actual='Iris-setosa'
>predicted='Iris-setosa', actual='Iris-setosa'
>predicted='Iris-setosa', actual='Iris-setosa'
>predicted='Iris-setosa', actual='Iris-setosa'
>predicted='Iris-setosa', actual='Iris-setosa'
>predicted='Iris-versicolor', actual='Iris-versicolor'
>predicted='Iris-versicolor', actual='Iris-versicolor'
>predicted='Iris-versicolor', actual='Iris-versicolor'
>predicted='Iris-versicolor', actual='Iris-versicolor'
>predicted='Iris-versicolor', actual='Iris-versicolor'
>predicted='Iris-virginica', actual='Iris-versicolor'
>predicted='Iris-versicolor', actual='Iris-versicolor'
>predicted='Iris-versicolor', actual='Iris-versicolor'
>predicted='Iris-versicolor', actual='Iris-versicolor'
>predicted='Iris-versicolor', actual='Iris-versicolor'
>predicted='Iris-versicolor', actual='Iris-versicolor'
>predicted='Iris-versicolor', actual='Iris-versicolor'
>predicted='Iris-virginica', actual='Iris-virginica'
>predicted='Iris-virginica', actual='Iris-virginica'
>predicted='Iris-virginica', actual='Iris-virginica'
>predicted='Iris-virginica', actual='Iris-virginica'
>predicted='Iris-virginica', actual='Iris-virginica'
>predicted='Iris-virginica', actual='Iris-virginica'
>predicted='Iris-virginica', actual='Iris-virginica'
>predicted='Iris-virginica', actual='Iris-virginica'
>predicted='Iris-virginica', actual='Iris-virginica'
>predicted='Iris-virginica', actual='Iris-virginica'
>predicted='Iris-virginica', actual='Iris-virginica'
>predicted='Iris-virginica', actual='Iris-virginica'
>predicted='Iris-virginica', actual='Iris-virginica'
>predicted='Iris-virginica', actual='Iris-virginica'
>predicted='Iris-virginica', actual='Iris-virginica'
>predicted='Iris-virginica', actual='Iris-virginica'
>predicted='Iris-virginica', actual='Iris-virginica'
>predicted='Iris-virginica', actual='Iris-virginica'
>predicted='Iris-virginica', actual='Iris-virginica'
Accuracy: 97.72727272727273%

机器学习(Machine Learning)算法总结-K临近算法的更多相关文章

  1. &lbrack;Machine-Learning&rsqb; K临近算法-简单例子

    k-临近算法 算法步骤 k 临近算法的伪代码,对位置类别属性的数据集中的每个点依次执行以下操作: 计算已知类别数据集中的每个点与当前点之间的距离: 按照距离递增次序排序: 选取与当前点距离最小的k个点 ...

  2. K临近算法

    K临近算法原理 K临近算法(K-Nearest Neighbor, KNN)是最简单的监督学习分类算法之一.(有之一吗?) 对于一个应用样本点,K临近算法寻找距它最近的k个训练样本点即K个Neares ...

  3. 秒懂机器学习---k临近算法(KNN)

    秒懂机器学习---k临近算法(KNN) 一.总结 一句话总结: 弄懂原理,然后要运行实例,然后多解决问题,然后想出优化,分析优缺点,才算真的懂 1.KNN(K-Nearest Neighbor)算法的 ...

  4. 机器学习算法之Kmeans算法(K均值算法)

    Kmeans算法(K均值算法) KMeans算法是典型的基于距离的聚类算法,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大.该算法认为簇是由距离靠近的对象组成的,因此把得到紧凑 ...

  5. 【机器学习Machine Learning】资料大全

    昨天总结了深度学习的资料,今天把机器学习的资料也总结一下(友情提示:有些网站需要"*"^_^) 推荐几本好书: 1.Pattern Recognition and Machi ...

  6. 机器学习&lpar;Machine Learning&rpar;&amp&semi;深度学习&lpar;Deep Learning&rpar;资料【转】

    转自:机器学习(Machine Learning)&深度学习(Deep Learning)资料 <Brief History of Machine Learning> 介绍:这是一 ...

  7. 数据挖掘&lpar;data mining&rpar;,机器学习&lpar;machine learning&rpar;,和人工智能&lpar;AI&rpar;的区别是什么? 数据科学&lpar;data science&rpar;和商业分析&lpar;business analytics&rpar;之间有什么关系?

    本来我以为不需要解释这个问题的,到底数据挖掘(data mining),机器学习(machine learning),和人工智能(AI)有什么区别,但是前几天因为有个学弟问我,我想了想发现我竟然也回答 ...

  8. 机器学习&lpar;Machine Learning&rpar;&amp&semi;深度学习&lpar;Deep Learning&rpar;资料&lpar;Chapter 2&rpar;

    ##机器学习(Machine Learning)&深度学习(Deep Learning)资料(Chapter 2)---#####注:机器学习资料[篇目一](https://github.co ...

  9. 机器学习&lpar;Machine Learning&rpar;&amp&semi;amp&semi;深度学习&lpar;Deep Learning&rpar;资料

    机器学习(Machine Learning)&深度学习(Deep Learning)资料 機器學習.深度學習方面不錯的資料,轉載. 原作:https://github.com/ty4z2008 ...

随机推荐

  1. Ado&period;net&lbrack;登录,增删改查,Get传值&comma;全选,不选,批量删除&comma;批量更新&rsqb;

    [虽然说,开发的时候,我们可以使用各种框架,ado.net作为底层的东西,作为一个合格的程序员,在出问题的时候我们还是要知道如何调试] 一.增删改查 cmd.ExecuteReader();执行查询, ...

  2. 【架构】MQTT&sol;XMPP&sol;GCM 等参考资料

    https://www.zhihu.com/question/29138530 https://segmentfault.com/q/1010000002598843/a-10200000026014 ...

  3. python之异常处理

    异常处理是高级编程语言必备的一个功能模块. 一.异常基础 在编程过程中为了增加友好性.容错性和健壮性,在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面,通俗来说就是不让用户看见大 ...

  4. EPPLUS之外的选择,EXCEL的操作(NPOI,POI(java))

    NPOI 编辑 NPOI 是 POI 项目的 .NET 版本.POI是一个开源的Java读写Excel.WORD等微软OLE2组件文档的项目. 中文名 NPOI 优    势 传统操作Excel遇到的 ...

  5. SIP入门(二):建立SIPserver

    在我的上一篇文章中已经介绍怎样通过SIP软电话直接通话,可是假设须要支持很多其它用户互相通话,同一时候基于安全考虑,须要对用户帐户登录进行验证控制,这些情况下就须要建立SIPserver. SIPse ...

  6. eclipse集承jboss服务器

    eclipse Kepler + Jboss7.1 参考引用文档: http://www.tekdigest.com/how-to-install-jboss-tools-in-eclipse.htm ...

  7. 第三章 jQuery中的事件与动画

    第三章jQuery中的事件与动画 一. jQuery中的事件 jQuery事件是对javaScript事件的封装. 1.基础事件 在javaScript中,常用的基础事件有鼠标事件.键盘事件.wind ...

  8. golang使用chrome headless获取网页内容

    如今动态渲染的页面越来越多,爬虫们或多或少都需要用到headless browser来渲染待爬取的页面. 而最近广泛使用的headless browser解决方案PhantomJS已经宣布不再继续维护 ...

  9. 【BZOJ4712】洪水

    题解: 注意题目说了每个点的权值只能增加 每个点的dp方程比较简单 min(v[i],sum[i]) 那么我们考虑如果v[i]增加那么上面使用sum[i]的会带来影响 暴力的做就是一个个往上查然后修改 ...

  10. Uniform Generator

    Computer simulations often require random numbers. One way to generate pseudo-random numbers is via ...