机器学习实战 k-近邻算法

边看书边看代码,结合自己的理解总结。
概括:
1.思想:计算测试样本与训练集对应特征值之间的距离(文中用的是欧式距离),认为与测试样本距离最近的k个样本可以用来描述这个测试样本,取这k个训练样本中出现最多次的类别,作为这个测试样本的类别。
2.优点:精度高,对异常值不敏感
3.缺点:复杂度高
4.适用范围:数值型和标称型
(数值型主要是指它的目标变量可以从无限的数值集合中取值,标称型指的是在有限目标机中取值)

算法分析:
0.训练集必须是已标记的样本,首先对训练集样本的特征值归一化
1.计算测试样本(测试样本同样要归一化)与所有训练样本的欧氏距离
2.按照距离递增排序,选择前k个样本点
3.确定这k个样本所在类别的出现频率,出现频率最高的类别即为测试样本的类别
4.文中给的评判分类器的标准是错误率=测试集中分类错误的个数/测试集样本数

#python 使用前安装numpy
from numpy import *
import operator
from os import listdir

def classify0(inX, dataSet, labels, k):
# kNN分类
# 输入测试集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):#选前k个样本
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
    #存储出现的类别的次数
    sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
    #类别排序,选择出现次数最多的作为测试样本的类别
    return sortedClassCount[0][0]

def autoNorm(dataSet):#归一化特征值
    minVals = dataSet.min(0)
    maxVals = dataSet.max(0)
    ranges = maxVals - minVals
    normDataSet = zeros(shape(dataSet))
    m = dataSet.shape[0]
    normDataSet = dataSet - tile(minVals, (m,1))
    #归一化=(原-最小值)/(最大值-最小值)
    #element wise divide
    return normDataSet, ranges, minVals

def datingClassTest():#对分类器的测试
    hoRatio = 0.20#选择样本的10%当做测试集,参数可调
    datingDataMat,datingLabels = file2matrix('测试集.txt')
    #从文件中读取数据       #load data setfrom file
    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)                               
     #每次输入测试集,训练集总样本,训练集标签,近邻k
        #得到测试结果和测试集标签
        if (classifierResult != datingLabels[i]): errorCount += 1.0
        #如果预测错误,则错误个数加一
    print "the total error rate is: %f" % (errorCount/float(numTestVecs))#最后算出错误率
    print errorCount

从代码中也可以看出,knn的确是简单有效,但是算法必须保存全部的数据集,每一次测试时必须与所有样本计算距离,并且也无法给出数据的基础结构信息(比如特征具有什么样的特点)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值