机器学习KNN——Python算法实现

1.KNN

简介:kNN算法是监督学习中分类方法的一种。所谓监督学习与非监督学习,是指训练数据是否有标注类别,若有则为监督学习,若否则为非监督学习。监督学习是根据输入数据(训练数据)学习一个模型,能对后来的输入做预测。
核心思想:在训练集中选出离输入的数据点最近的k个数据,根据这k个数据的类别判断输入的数据点的类别,k个数据的类别判断方法可以是k个中出现次数最多的类别,也还可以根据距离输入点的距离计算权重,再选出权重最大的类别,等等。
准确率的制约:根据上面的核心思想就可以知道制约条件是两个:k值和类别判断方法,具体取决于样本空间的数据特征

2.数据源

Python sklearn中的iris数据,共有150条,选用80%做训练数据,其余的作为测试数据,我是下载到本地并分割成testdata和traindata的,点击下载
你也可以直接引入数据

from sklearn.datasets import load_iris

3.数据处理

因为是iris现成的数据,所以没有数据清洗过程。

4.实现过程

**没有数据源的算法实现就是耍流氓
没有代码的算法实现就是耍流氓,
有代码没有注释的算法实现更是耍流氓**
上代码。。。

# -*- coding:utf-8 -*-

from pandas import *
import pandas as pd
import numpy as np
import operator

'''
计算样本的距离,预测类别
'''
def classify(testdata,traindata,trainlabels,k):
    traSize=traindata.shape[0]  #得到训练数据的维数,方便下面进行计算
    traDis1=np.tile(testdata,(traSize,1))-traindata
    traDis2=traDis1**2
    traDis3=traDis2.sum(axis=1)
    traDis=traDis3**0.5 #计算样本和训练数据的距离
    sortDis=traDis.argsort()    #排序
    classCount={}
    for i in range(k):  #得出k最近邻类别,判别样本类别
        classLabel=trainlabels[sortDis[i]]
        classCount[classLabel]=classCount.get(classLabel,0)+1
    sortedClassCount=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)
    return sortedClassCount[0][0]   #返回占比最大的类别

'''
装载数据,包括训练数据和测试数据
'''
def load():
    traindata=np.loadtxt('D:/myProject/iris_data/train.txt',delimiter=",",usecols=(0,1,2,3))
    trainlabels=np.loadtxt('D:/myProject/iris_data/train.txt',delimiter=",",usecols=(4,),dtype=str)
    testdata=np.loadtxt('D:/myProject/iris_data/test.txt',delimiter=",",usecols=(0,1,2,3))
    testlabel=np.loadtxt('D:/myProject/iris_data/test.txt',delimiter=",",usecols=(4,),dtype=str)
    return traindata,trainlabels,testdata,testlabel

'''
测试样本,确定最优K值
'''
def getk(traindata,trainlabels,testdata,testlabel):
    testLen=testdata.shape[0]
    trainLen=traindata.shape[0] #得出训练数据和测试数据的行数
    errorRate=[]
    for k in range(1,trainLen+1):
        errorCount=0
        for i in range(testLen):
            trueLabel=testlabel[i]
            classfyResult=classify(testdata[i],traindata,trainlabels,k) #判断测试数据类别
            if classfyResult!=trueLabel:    #比较判断类别和测试数据真实类别,统计类别判断错误的个数
                errorCount+=1
            else:
                pass
        errorRate.append(errorCount/float(testLen)) #计算每个k值对应的错误率
    errorRate=np.array(errorRate)
    kBest1=errorRate.argsort()  #排序
    kBest=kBest1[0]+1
    return kBest

'''
输入需预测数据,预测类别
'''
def predict(kBest,traindata,trainlabels):
    testdata=[]
    for i in range(4):  #输入样本数据
        testdata.append(raw_input("pelease input %d number:" %(i+1)))
    testdata=np.array(testdata)
    testdata=testdata.astype('float64')  
    result=classify(testdata,traindata,trainlabels,kBest)   #判断样本类别
    print "the %r classify is %s" %(testdata,result)

'''
主函数
''' 
if __name__=='__main__':
    print "start ..."
    traindata,trainlabels,testdata,testlabel=load() #获得训练数据和测试数据
    kBest=getk(traindata,trainlabels,testdata,testlabel)    #获得最优K值
    predict(kBest,traindata,trainlabels)    #预测类别

思路:装载数据,测试训练数据获得正确率最高的那个k值,预测输入数据类型
5.难点解释

  • 数据机构:不得不说Python的数学计算支持还是非常不错的,但是要想灵活运用就得弄明白常用的几种数据结构:自带的list,numpy中的array,pandas中的Series和DataFrame,KNN实现主要用到的是list和array,注意两者转换哦!
  • np.tile:将数据复制,这里(traSize,1)的1是保证复制成多行,而不是复制后都挤在同一行
  • argsort:np.argsort排序函数,根据数组元素的大小从小到大排序并返回排序前对应的下标,举个栗子
    a=np.array([2,1,4,3]) 对应的下标是0,1,2,3 a.argsort()
    排序的结果应该为1,2,3,4,再返回各自之前对应的下标 array([1,0,3,2])
  • np.loadtxt:引入txt文本文件,delimiter为分割标识,usecols为使用分割后的哪几列
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值