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

来源:互联网 发布:英语音标学习软件 编辑:程序博客网 时间:2024/04/29 10:20

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 pdimport numpy as npimport 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 0
原创粉丝点击