KNN代码解析

代码是机器学习实战书上的,略有修改,在python3下运行

#1 导入模块,创建数据集
from numpy import *
import operator
def createDataSet(): #创建简单测试数据
    group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
    labels = ['A','A','B','B']
    return group, labels
导入numpy和operator模块,注意导入方式不同,使用operator时需要以operator.的形式而
numpy可直接用创建数据集及标签,group和labels一一对应
#2 核心部分 kNN算法实现
def classify0(inX, dataSet, labels, k): 
   dataSetSize= dataSet.shape[0]                                    
   diffMat= tile(inX,(dataSetSize, 1))- dataSet    
   sqDiffMat= diffMat**2                        
   sqDistances= sqDiffMat.sum(axis=1)           
   distances= sqDistances**0.5                  
   sortedDistIndicies= distances.argsort()
    有四个输入参数,待分类向量,训练样本集,标签向量,k值使用shape函数方式
如shape(dataSet)可返回一个维度元组信息,shape方法方式shape[0]可得到第一维
也就是行数inX是行向量,使用tile可以将inX整个按dataSetSize行1列进行复制,再
与dataSet做差;得到的diffMat是数组形式,平方可对其中每个元素平方操作,sum
则是对sqDiffMat进行求和,axis=1可对每一行求和得到列向量数组,axis=0则可对
每一列求和得到行向量数组;得到距离后要进行排序操作,argsort方法可以返回升序
排序后的索引
      
   classCount= {}
   for i in range(k):                                         
      voteIlabel= labels[sortedDistIndicies[i]]               
      classCount[voteIlabel]= classCount.get(voteIlabel,0)+1   
   sortedClassCount= sorted(classCount.items(),               
   key=operator.itemgetter(1), reverse= True)                 
   return sortedClassCount[0][0]
 
  创建classCount用于统计标签次数,循环k次找出最近的k个数据;
sortedDistIndicies[i]可获取索引并找出对应标签,然后统计各
标签出现次数存入classCount中,get方法可以取得voteIlabel的
的值,如果没有voteIlabel则创建并赋值0;得到classCount后要继续
排序,sorted的参数中,items()将字典变为可迭代对象,key指定了
排序规则,按值比较,reverse=True指定降序,最后返回值最大的键

#3 文本处理部分
def file2matrix(filename):#文本转换
   fr= open(filename)
   arrayOLines= fr.readlines()   #按行读取全部行                        
   numberOfLines= len(arrayOLines)    #计算行数
   returnMat= zeros((numberOfLines, 3))  #创建numberOfLines行3列的零矩阵
   classLabelVector= []
   index= 0
   for line in arrayOLines:            #遍历每一行
      line= line.strip()          #去掉每一行前后的空白
      listFromLine= line.split('\t')   #按'\t'切分每一行
      returnMat[index,:]= listFromLine[0:3]        #特征值放入returnMat
      classLabelVector.append(int(listFromLine[-1]))  #类别放入classLabelVector
      index+=1
   return returnMat, classLabelVector
   
def autoNorm(dataSet):   #归一化数值
   minVals= dataSet.min(0)    #取得dataSet中一列的最小值,即每个属性的最小特征值
   maxVals= dataSet.max(0)    #同上
   ranges= maxVals- minVals
   m= dataSet.shape[0]
   normDataSet= dataSet- tile(minVals,(m,1))
   normDataSet= normDataSet/tile(ranges,(m,1))
   return normDataSet, ranges, minVals
#4 测试部分
def datingClassTest():  
   hoRatio = 0.10       #使用10%的数据作为测试集,90%则为训练集
   datingDataMat,datingLabels = file2matrix('datingTestSet2.txt') #注意打开的文件,书上有误
   normMat, ranges, minVals = autoNorm(datingDataMat)
   m = normMat.shape[0]
   numTestVecs = int(m*hoRatio)
   errorCount = 0.0
   for i in range(numTestVecs):
      classifierResult = classify0(normMat[i,:],\
            normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)
      print("the classifier came back with: %d, the real answer is: %d" \
              % (classifierResult, datingLabels[i]))
      if (classifierResult != datingLabels[i]):
         errorCount += 1.0
   print("the total error rate is: %f" % (errorCount/float(numTestVecs)))
   print(errorCount)


完整代码
from numpy import *
import operator

def createDataSet(): #创建简单测试数据
    group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
    labels = ['A','A','B','B']
    return group, labels

def classify0(inX, dataSet, labels, k): #k近邻算法
    dataSetSize= dataSet.shape[0]
    diffMat= tile(inX,(dataSetSize, 1))- dataSet
    sqDiffMat= diffMat**2
    sqDistances= sqDiffMat.sum(axis=1)
    distances= sqDistances**0.5
    sortedDistIndicies= distances.argsort()
    classCount= {}
    for i in range(k):
        voteIlabel= labels[sortedDistIndicies[i]]
        classCount[voteIlabel]= classCount.get(voteIlabel,0)+1
    sortedClassCount= sorted(classCount.items(),
    key=operator.itemgetter(1), reverse= True)
    return sortedClassCount[0][0]

def file2matrix(filename):#文本转换
    fr= open(filename)
    arrayOLines= fr.readlines()
    numberOfLines= len(arrayOLines)
    returnMat= zeros((numberOfLines, 3))
    classLabelVector= []
    index= 0
    for line in arrayOLines:
        line= line.strip()
        listFromLine= line.split('\t')
        returnMat[index,:]= listFromLine[0:3]
        classLabelVector.append(int(listFromLine[-1]))
        index+=1
    return returnMat, classLabelVector
    
def autoNorm(dataSet): #归一化数值
    minVals= dataSet.min(0)
    maxVals= dataSet.max(0)
    ranges= maxVals- minVals
    m= dataSet.shape[0]
    normDataSet= dataSet- tile(minVals,(m,1))
    normDataSet= normDataSet/tile(ranges,(m,1))
    return normDataSet, ranges, minVals

def datingClassTest():
    hoRatio = 0.10
    datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')
    normMat, ranges, minVals = autoNorm(datingDataMat)
    m = normMat.shape[0]
    numTestVecs = int(m*hoRatio)
    errorCount = 0.0
    for i in range(numTestVecs):
        classifierResult = classify0(normMat[i,:],\
                normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)
        print("the classifier came back with: %d, the real answer is: %d" \
                  % (classifierResult, datingLabels[i]))
        if (classifierResult != datingLabels[i]):
            errorCount += 1.0
    print("the total error rate is: %f" % (errorCount/float(numTestVecs)))
    print(errorCount)

group, labels= createDataSet()
print(group)
print(labels)
print(classify0([0,0], group, labels, 3))
datingClassTest()




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值