博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[机器学习]-K近邻-最简单的入门实战例子
阅读量:5116 次
发布时间:2019-06-13

本文共 6433 字,大约阅读时间需要 21 分钟。

本篇文章分为两个部分,前一部分主要简单介绍K近邻,后一部分是一个例子

第一部分--K近邻简介

  从字面意思就可以容易看出,所谓的K近邻,就是找到某个样本距离(这里的距离可以是欧式距离,曼哈顿距离,切比雪夫距离等)最近的K个数据,根据最近的K个邻居属于什么分类,来判断这个样本属于什么分类。 

  简单说一下优缺点:

    优点:简单,适合于多分类问题(multi-modal,对象具有多个类别标签), kNN比SVM的表现要好。

    缺点:I:计算量大    II.如果某个分类占绝对优势,分类的效果很差,比如,印度阿三主要是黑人,如果你随便找个人,

       使用K近邻判断这个人是不是黑人,这个人周围可能都是黑人,所以不适合这种类型的数据集。

第二部分--实战例子

  数据集:iris数据集,这是个什么样的数据集呢?

    通过3种鸢尾属植物的花的四个属性(萼片长度(sepal length)、萼片宽度sepalwidth)、花瓣长度(petal length)和花瓣宽度(petal width)) 来判断属于哪一种鸢尾属植物,这三种鸢尾属植物分别是setosa、versic010r和virginica。

  数据集地址:     将数据复制到txt文件中。

  代码:

import csvimport randomimport mathimport operator#装载数据集def loadDataset(filename, split, trainingSet = [], testSet = []):    with open(filename, 'rt') as csvfile:        lines = csv.reader(csvfile)        dataset = list(lines)        for x in range(len(dataset)-1):            for y in range(4):                # print(type(dataset[x][y]))                dataset[x][y] = float(dataset[x][y])            if random.random() < 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)):        #testinstance        dist = euclideanDistance(testInstance, trainingSet[x], length)        distances.append((trainingSet[x], dist))    """        operator模块提供的itemgetter函数用于获取对象的哪些维的数据,参数为一些序号    """    #distances是一个list里面放的tuple,tuple第二个元素是距离,这里就是根据距离排序,默认升序    distances.sort(key=operator.itemgetter(1))    neighbors = []    for x in range(k):        neighbors.append(distances[x][0])    return neighbors#找到k个样本中出现最多的分类,并返回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    """        注意,python3中字典的iteritems()方法已经取消,只有item()    """    # sortedVotes = sorted(classVotes.iteritems(), key=operator.itemgetter(1), reverse=True)    """        sort 与 sorted 区别:        sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作。        list 的 sort 方法返回的是对已经存在的列表进行操作,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。        reverse -- 排序规则,reverse = True 降序 , reverse = False 升序(默认)    """    """        print(classVotes)        输出格式为:{'Iris-versicolor': 1, 'Iris-virginica': 2}    """    """        print(classVotes.items())        输出格式为:dict_items([('Iris-versicolor', 1), ('Iris-virginica', 2)])    """    sortedVotes = sorted(classVotes.items(), key=operator.itemgetter(1), reverse=True)    """        print(sortedVotes)        输出格式为:[('Iris-virginica', 3)]    """    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():    #prepare data    trainingSet = []    testSet = []    split = 0.67  #0.67相当于2/3,就是说2/3是训练集,1/3是测试集,整个iris数据集中有150个数据    loadDataset(r'../data/DTree/irisdata.txt', split, trainingSet, testSet)    # print(trainingSet)    print ('训练集样本数: ' + repr(len(trainingSet)))    print ('测试集样本数: ' + repr(len(testSet)))    #generate predictions    predictions = []    k = 3    for x in range(len(testSet)):        # trainingsettrainingSet[x]        neighbors = getNeighbors(trainingSet, testSet[x], k)        result = getResponse(neighbors)        predictions.append(result)        if result == testSet[x][-1]:            correct = True        else:            correct = False        print ('预测结果:' + repr(result) + ', 实际值=' + repr(testSet[x][-1]) + ',  是否预测正确=' + repr(correct))    accuracy = getAccuracy(testSet, predictions)    #整个测试集预测准确率    print('准确率: ' + repr(accuracy) + '%')if __name__ == '__main__':    main()

输出结果为:

训练集样本数: 109测试集样本数: 41预测结果:'Iris-setosa', 实际值='Iris-setosa',  是否预测正确=True预测结果:'Iris-setosa', 实际值='Iris-setosa',  是否预测正确=True预测结果:'Iris-setosa', 实际值='Iris-setosa',  是否预测正确=True预测结果:'Iris-setosa', 实际值='Iris-setosa',  是否预测正确=True预测结果:'Iris-setosa', 实际值='Iris-setosa',  是否预测正确=True预测结果:'Iris-setosa', 实际值='Iris-setosa',  是否预测正确=True预测结果:'Iris-setosa', 实际值='Iris-setosa',  是否预测正确=True预测结果:'Iris-setosa', 实际值='Iris-setosa',  是否预测正确=True预测结果:'Iris-setosa', 实际值='Iris-setosa',  是否预测正确=True预测结果:'Iris-setosa', 实际值='Iris-setosa',  是否预测正确=True预测结果:'Iris-setosa', 实际值='Iris-setosa',  是否预测正确=True预测结果:'Iris-versicolor', 实际值='Iris-versicolor',  是否预测正确=True预测结果:'Iris-versicolor', 实际值='Iris-versicolor',  是否预测正确=True预测结果:'Iris-versicolor', 实际值='Iris-versicolor',  是否预测正确=True预测结果:'Iris-versicolor', 实际值='Iris-versicolor',  是否预测正确=True预测结果:'Iris-versicolor', 实际值='Iris-versicolor',  是否预测正确=True预测结果:'Iris-versicolor', 实际值='Iris-versicolor',  是否预测正确=True预测结果:'Iris-versicolor', 实际值='Iris-versicolor',  是否预测正确=True预测结果:'Iris-versicolor', 实际值='Iris-versicolor',  是否预测正确=True预测结果:'Iris-versicolor', 实际值='Iris-versicolor',  是否预测正确=True预测结果:'Iris-versicolor', 实际值='Iris-versicolor',  是否预测正确=True预测结果:'Iris-versicolor', 实际值='Iris-versicolor',  是否预测正确=True预测结果:'Iris-versicolor', 实际值='Iris-versicolor',  是否预测正确=True预测结果:'Iris-versicolor', 实际值='Iris-versicolor',  是否预测正确=True预测结果:'Iris-versicolor', 实际值='Iris-versicolor',  是否预测正确=True预测结果:'Iris-versicolor', 实际值='Iris-versicolor',  是否预测正确=True预测结果:'Iris-virginica', 实际值='Iris-virginica',  是否预测正确=True预测结果:'Iris-virginica', 实际值='Iris-virginica',  是否预测正确=True预测结果:'Iris-virginica', 实际值='Iris-virginica',  是否预测正确=True预测结果:'Iris-virginica', 实际值='Iris-virginica',  是否预测正确=True预测结果:'Iris-virginica', 实际值='Iris-virginica',  是否预测正确=True预测结果:'Iris-virginica', 实际值='Iris-virginica',  是否预测正确=True预测结果:'Iris-virginica', 实际值='Iris-virginica',  是否预测正确=True预测结果:'Iris-virginica', 实际值='Iris-virginica',  是否预测正确=True预测结果:'Iris-versicolor', 实际值='Iris-virginica',  是否预测正确=False预测结果:'Iris-virginica', 实际值='Iris-virginica',  是否预测正确=True预测结果:'Iris-virginica', 实际值='Iris-virginica',  是否预测正确=True预测结果:'Iris-virginica', 实际值='Iris-virginica',  是否预测正确=True预测结果:'Iris-virginica', 实际值='Iris-virginica',  是否预测正确=True预测结果:'Iris-virginica', 实际值='Iris-virginica',  是否预测正确=True预测结果:'Iris-virginica', 实际值='Iris-virginica',  是否预测正确=True准确率: 97.5609756097561%

 

转载于:https://www.cnblogs.com/gunduzi/p/10623013.html

你可能感兴趣的文章
Loj #139
查看>>
hihocoder1187 Divisors
查看>>
Azure 托管镜像和非托管镜像对比
查看>>
js window.open 参数设置
查看>>
032. asp.netWeb用户控件之一初识用户控件并为其自定义属性
查看>>
Ubuntu下安装MySQL及简单操作
查看>>
前端监控
查看>>
clipboard.js使用方法
查看>>
移动开发平台-应用之星app制作教程
查看>>
leetcode 459. 重复的子字符串(Repeated Substring Pattern)
查看>>
伪类与超链接
查看>>
centos 7 redis-4.0.11 主从
查看>>
博弈论 从懵逼到入门 详解
查看>>
永远的动漫,梦想在,就有远方
查看>>
springboot No Identifier specified for entity的解决办法
查看>>
慵懒中长大的人,只会挨生活留下的耳光
查看>>
"远程桌面连接--“发生身份验证错误。要求的函数不受支持
查看>>
【BZOJ1565】 植物大战僵尸
查看>>
VALSE2019总结(4)-主题报告
查看>>
浅谈 unix, linux, ios, android 区别和联系
查看>>