机器学习第七篇:Knn、kd树

1.Knn:

knn是目前为止接触到的最简单之一的算法,算法很简单,就是求取测试样本距离最近的几个点,然后采用多数表决的规则,将测试样本归为那一类。

算法流程:

  • 计算已知类别数据集中的点与当前点之间的距离
  • 按照距离递增次序排序
  • 选取与当前点距离最小的k个点
  • 确定前k个点所在类别出现的频率
  • 返回前k个点出现频率最高的类别作为当前点的预测分类
def classify0(inX, dataSet, labels, k):
    dataSetSize = dataSet.shape[0]
    diffMat = tile(inX, (dataSetSize,1)) - dataSet
#inx为我们的输入测试集,tile这个函数将它变成dataSetSize行1列的矩阵,这样就能同时跟所有的训练样本进行加减
    sqDiffMat = diffMat**2  #采用欧式距离
    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances**0.5
    sortedDistIndicies = distances.argsort()    #返回的是对distances进行从小到大的排序返回对应值的索引 
    classCount={}          
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]  #对应值的索引在labels当中就是对应的类
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1  #在字典中获取voteIlabel的大小,没有则赋0
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
#items返回的是键值的元组所组成的迭代器,key是定义了一个函数跟lambda的功能相似,这里的意思是按照值的大小进行排序
    return sortedClassCount[0][0]  #返回最多的值所对应的类,也即与测试样本最接近的类

2.kd数:

如果数据量非常大的时候我们并不能采用上面的方法,这样太耗时了,每一个都要做欧式计算,想要提高速率,肯定要减少计算距离的次数,而kd树就能做到

构造kd树算法:

  • 构造根节点:确定样本有几个维度,比如说有三个维度1,2,3,在构造的过程中会一直不停的在这三个维度循环,首先选择维度1,以所有实例的第一维的坐标的中位数为切分点,注意寻找中位数的过程是,先对那一维的数据进行排序,然后计算len(trainlist)//2,一般奇数的时候会是中间的数,偶数的时候会是中间两个靠后的那一个,然后选出来的坐标就是我们的切分点,切分点的左边都是小于切分点的数,切分点的右边都是大于切分点的数,然后在左右两区域,再利用同样的方法切分,只不过此时要用第二维度的数据来比较,如此的循环下去,直到所有的数据被划分。

搜索kd树算法:

  • 在kd树中找出包含目标点x的叶结点:从根结点出发,递归的向下访问kd树。若目标点当前维的坐标值小于切分点的坐标值,则移动到左子结点,否则移动到右子结点。直到子结点为叶结点为止
  • 以此叶结点为“当前最近点”
  • 递归的向上回退,在每个结点进行以下操作
  • (1)如果该结点保存的实例点比当前最近点距目标点更近,则以该实例点为“当前最近点”

  • (2)当前最近点一定存在于该结点一个子结点对应的区域。检查该子结点的父结点的另一个子结点对应的区域是否有更近的点。具体的,检查另一个子结点对应的区域是否与以目标点为球心、以目标点与“当前最近点”间的距离为半径的超球体相交。如果相交,可能在另一个子结点对应的区域内存在距离目标更近的点,移动到另一个子结点。接着,递归的进行最近邻搜索。如果不相交,向上回退

  • 当回退到根结点时,搜索结束。最后的“当前最近点”即为x的最近邻点
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值