2021-08-02

K近邻算法

基本k近邻算法

import numpy as np
import operator
#创建数据集和标签
def CreatDateSet():
    group =np.array( [[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
    labels =['A','A','B','B']
    return group,labels
#inx是输入向量,训练样本是dataset,标签是labels,k是选择邻居的数目
def classify0(inx,dataset,labels,k):
    datasize=dataset.shape[0]
    diffMat = np.tile(inx,(datasize,1))-dataset
    sqDiffmat=diffMat**2
    sqDistances =sqDiffmat.sum(axis=1)
    distances =sqDistances**0.5
    sortedDistIndicies = np.argsort(distances)
    classCount={}
    for i in range(0,k):
        voteIlabel = labels[sortedDistIndicies[i]]
        #classCount字典是用于统计前k个距离最近的邻居的标签及对应的个数
        classCount[voteIlabel]=classCount.get(voteIlabel,0)+1
    #利用sorted函数根据item的数据项值进行降序排列
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    #返回次数最多的项所对应的标签作为预测结果。
    return sortedClassCount[0][0]
group,labels=CreatDateSet()
print(classify0([0,0],group,labels,3))

使用k近邻算法改进约会网站的配对效果

import numpy as np
import operator
import matplotlib.pyplot as plt
#读取数据
def file2matrix(filename):
    fr=open(filename)
    arrayOLines=fr.readlines()
    numberOfLines=len(arrayOLines)
    returnMat =np.zeros((numberOfLines,3))
    classLabelVector=[]
    index=0
    for line in arrayOLines:
        #将每一行首尾的空格去掉
        line=line.strip()
        #没遇到一个\t就把这一部分赋予给一个元素
        listFormLine=line.split('\t')
        returnMat[index,:]=listFormLine[0:3]
        #将每一行的标签加入数组
        classLabelVector.append(listFormLine[-1])
        index +=1
    return returnMat,classLabelVector
#归一化数值
def autoNorm(dataSet):
 #参数0使得函数可以从列中取得最小值而不是行中
    minVals=dataSet.min(0)
    maxVals=dataSet.max(0)
    ranges=maxVals-minVals
    normDateSet=np.zeros(np.shape(dataSet))
    m=dataSet.shape[0]
    normDateSet=dataSet-np.tile(minVals,(m,1))
    normDateSet=normDateSet/np.tile(ranges,(m,1))
    return normDateSet,ranges,minVals
#inx是输入向量,训练样本是dataset,标签是labels,k是选择邻居的数目
def classify0(inx,dataset,labels,k):
    datasize=dataset.shape[0]
    diffMat = np.tile(inx,(datasize,1))-dataset
    sqDiffmat=diffMat**2
    sqDistances =sqDiffmat.sum(axis=1)
    distances =sqDistances**0.5
    sortedDistIndicies = np.argsort(distances)
    classCount={}
    for i in range(0,k):
        voteIlabel = labels[sortedDistIndicies[i]]
        #classCount字典是用于统计前k个距离最近的邻居的标签及对应的个数
        classCount[voteIlabel]=classCount.get(voteIlabel,0)+1
    #利用sorted函数根据item的数据项值进行降序排列
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    #返回次数最多的项所对应的标签作为预测结果。
    return sortedClassCount[0][0]
#将数据集的一部分用来测试算法的准确率
def datingClassTest():
    a = 'F:\\学习\\machinelearninginaction\\Ch02\\datingTestSet.txt'
    hoRatio=0.10
    Mat,Labels=file2matrix(a)
    normMat,ranges,min=autoNorm(Mat)
    m=normMat.shape[0]
    numTestVecs=int(hoRatio*m)
    errorCount=0.0
    for i in range(0,numTestVecs):
       classifierResult=classify0(normMat[i,:],normMat[numTestVecs:m,:],Labels[numTestVecs:m],3)
       print(classifierResult,Labels[i])
       if(classifierResult!=Labels[i]):
        errorCount+=1
    print(errorCount/float(numTestVecs))
def classifyPerson():
    a = 'F:\\学习\\machinelearninginaction\\Ch02\\datingTestSet.txt'
    percentTats = float(input("percentage of time spent playing video games?"))
    ffMiles = float(input("frequent filer miles earned per year?"))
    iceCream = float(input("liters of ice cream consumed per year?"))
    Mat,Labels=file2matrix(a)
    normMat,ranges,min=autoNorm(Mat)
    inArr = np.array([ffMiles, percentTats, iceCream])
    classifierResult = classify0((inArr - min) / ranges, normMat, Labels, 3)
    print("you will probably like this person:", classifierResult)
datingClassTest()
classifyPerson()

手写识别系统

import numpy as np
from os import listdir
import operator
import matplotlib.pyplot as plt
#inx是输入向量,训练样本是dataset,标签是labels,k是选择邻居的数目
def classify0(inx,dataset,labels,k):
    datasize=dataset.shape[0]
    diffMat = np.tile(inx,(datasize,1))-dataset
    sqDiffmat=diffMat**2
    sqDistances =sqDiffmat.sum(axis=1)
    distances =sqDistances**0.5
    sortedDistIndicies = np.argsort(distances)
    classCount={}
    for i in range(0,k):
        voteIlabel = labels[sortedDistIndicies[i]]
        #classCount字典是用于统计前k个距离最近的邻居的标签及对应的个数
        classCount[voteIlabel]=classCount.get(voteIlabel,0)+1
    #利用sorted函数根据item的数据项值进行降序排列
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    #返回次数最多的项所对应的标签作为预测结果。
    return sortedClassCount[0][0]
#将图片从一个32*32的二进制图像变成一个1*1024的向量
def img2vector(filename):
    returnVect=np.zeros((1,1024))
    fr=open(filename)
    for i in range(0,32):
        linestr=fr.readline()
        for j in range(0,32):
            returnVect[0,32*i+j]=int(linestr[j])
    return returnVect
def handwritingClassTest():
    hwLabels=[]
    # 列出训练集所在的文件夹的路径,返回的是文件夹内所以数据的名字。使用前需导入from os import listdir
    trainingFileList =listdir('F:\\learn\\machinelearninginaction\\Ch02\\trainingDigits')
    m=len(trainingFileList)
    trainingMat=np.zeros((m,1024))
    for i in range(0,m):
        fileNameStr=trainingFileList[i]
        # 将字符串按照'.'分开,并将前一部分放于fileStr
        fileStr=fileNameStr.split('.')[0]
        # 将fileStr按照'_'分开,并将前一部分存于classNumStr
        classNumStr=int(fileStr.split('_')[0])
        # 将每个标签值全部存入一个列表中
        hwLabels.append(classNumStr)
        trainingMat[i,:]=img2vector('F:\\learn\\machinelearninginaction\\Ch02\\trainingDigits\\'+fileNameStr)
    testFileList=listdir('F:\\learn\\machinelearninginaction\\Ch02\\testDigits')
    errorCount=0.0
    mTest=len(testFileList)
    for i in range(0,mTest):
         fileNameStr=testFileList[i]
         # 将字符串按照'.'分开,并将前一部分放于fileStr
         fileStr = fileNameStr.split('.')[0]
         # 将fileStr按照'_'分开,并将前一部分存于classNumStr
         classNumStr = int(fileStr.split('_')[0])
         vectorUnderTest=img2vector('F:\\learn\\machinelearninginaction\\Ch02\\testDigits\\'+fileNameStr)
         classifierResult=classify0(vectorUnderTest,trainingMat,hwLabels,5)
         print("the classifierResult came back with: %d,the real answer is: %d" % (classifierResult, classNumStr))
         # 预测错误,错误数加1次
         if (classifierResult != classNumStr): errorCount += 1.0
         # 打印错误数和错误率
    print("\n错误的个数 %d" % errorCount)
    print("\n错误率 %f" % (errorCount / float(mTest)))
handwritingClassTest()

评价

(1) 如果我们改变训练样本的数目,调整相应的k值,都会对最后的预测错误率产生影响,我们可以根据错误率的情况,对这些变量进行调整,从而降低预测错误率
(2)k近邻算法的优缺点:
k近邻算法具有精度高,对异常值不敏感的优点
k近邻算法是基于实例的学习,使用算法时我们必须有接近实际数据的训练样本数据。k近邻算法必须保存全部数据集,如果训练数据集很大,必须使用大量的存储空间。此外,由于必须对数据集中的每个数据计算距离,实际使用时也可能会非常耗时
此外,k近邻算法无法给出数据的基础结构信息,因此我们无法知道平均实例样本和典型实例样本具有怎样的特征。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值