02 KNN算法 - KD Tree

KD Tree是KNN算法中用于计算最近邻的快速简便的构建方式。

当样本量少的时候,用brute直接搜索最近邻的方式是可行的。即计算到所有样本的距离。但当样本量庞大时,直接计算所有样本距离的工作量很大,这种情况使用KD Tree可以节约大量时间成本。

KD Tree构建方式

KD树采用从m个样本的n维特征中,分别计算n个特征取值的方差,用方差最大的第k维特征nk 作为根节点。对于这个特征,选择取值中的中位数 nkv 作为样本的划分点,对于小于该值的样本划分到左子树,对于大于等于该值的样本划分到右子树,对左右子树采用同样的方式找方差最大的特征作为根节点,递归产生KD Tree。

为什么要选择方差最大的进行划分?
构建树的目的是加快我的搜索过程。
既然我想加快我的搜索过程,要就意味着我最终的数据落在某个叶子节点上。我希望只需搜索整个二叉树的某一些列即可,那么最好的划分方式,就是让我的每个分支上数据的差异性最大化。

那么衡量数据差异性的最基础的数学指标是什么?
是方差。方差越大,意味着数据的离散程度就越大,我将离散程度由大到小的数据一分为二,方差小意味着数据更集中到了一起。

KD Tree

示例 KD_Tree的构建:

现在有一个二维样本: {(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)}

1、计算x1和x2每一列对应的方差


a、通过pandas计算出的是样本方差:
\sum_{} [x-mean(x) ]^2 / (n-1)

import numpy as np
import pandas as pd

data = np.array([
        [2,3],
        [5,4],
        [9,6],
        [4,7],
        [8,1],
        [7,2]
    ])

df = pd.DataFrame(data)
df.var()

0| 6.966667
1| 5.366667
dtype: float64


b、通过numpy计算出的是总体方差:
\sum_{} [x-mean(x) ]^2 / n

import numpy as np
import pandas as pd
data = np.array([
        [2,3],
        [5,4],
        [9,6],
        [4,7],
        [8,1],
        [7,2]
    ])
print(data)
mean =np.mean(data,axis = 0)
var = np.var(data,axis = 0)
a_var = np.sum(pow(data-mean,2),axis = 0)/6
print(var)
print(a_var)

[[2 3]
[5 4]
[9 6]
[4 7]
[8 1]
[7 2]]
[ 5.80555556 4.47222222]
[ 5.80555556 4.47222222]

特征空间的划分

第一个树的划分:基于x1进行划分
[2,4,5,7,8,9]的中位数是5和7的平均值6。
虽然严格意义上说中位数是6,但是在计算机中我们人为得定义x1的中位数是7。


即 x1 ≤ 7的数据落在左侧;x1 > 7的数据落在右侧;

左侧:(2,3)(5,4)(4,7) (7,2)
右侧: (9,6)(8,1)

第一次划分生成的区域

第二个树的划分:根据右侧(9,6)(8,1)的x2进行划分

下侧:x2 ≤ 6;上侧x2>6

第二次划分的区域

第二个树的划分:根据左侧(2,3)(5,4)(4,7) (7,2)的x2进行划分

寻找2、3、4、7的中位数 4 进行划分

第三次划分的区域

....

注意:每次生成的划分都是一个矩形。当叶子节点无法被继续划分的时候,KD树的构建完成,递归结束。

KD Tree查找最近邻

我们生成了KD Tree后,现在就可以去预测测试集里面的样本目标点了。

1、对于一个目标点,先在KD树里找到包含目标点的叶子节点。

2、以目标点为圆心,以目标点叶子节点样本实例的距离为半径,得到一个超球体,最近邻的点一定在这个超球体内部。

3、然后返回叶子节点的父节点,检查另一个子节点包含的超矩形体是否和超球体相交。

4、如果相交就倒这个子节点寻找着是否有更加近的近邻,有的话就更新最近邻。

5、如果不相交,直接返回父节点中的父节点,在另一个子树继续搜索最近邻。当回溯到根节点时,算法结束。

6、此时保存的最近邻节点就是最终的最近邻。

如果现在想找(2,4.5)这点的最近邻,该如何操作?

1、画出二叉树:


2、寻找(2,4.5)这点:


一个比较好的理解方式:首先找到第一个最近邻,然后画出一个圆。然后逐渐收缩圆的半径,查看每次缩小后的圆是否能够和矩形相交于一个更小的最近邻点,如果有则更新。直到回到根节点。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容