如何从 k-d 树实现 K-NN 分类?

Posted

技术标签:

【中文标题】如何从 k-d 树实现 K-NN 分类?【英文标题】:How to implement K-NN classification from a k-d tree? 【发布时间】:2019-07-05 01:56:35 【问题描述】:

我正在尝试使用 k-d 树编写 K-NN 分类的代码,而不使用任何库。到目前为止,我已经能够为 k-d 树编写代码,但我似乎无法理解一旦从训练集形成树后如何找到 k 个最近邻居。 k-d 树代码:

#include<bits/stdc++.h> 
using namespace std; 

const int k = 2; // 2-dimensions 

struct Node 
 
    int point[k]; 
    Node *left, *right; 
; 

struct Node* newNode(int arr[]) 
 
    struct Node* temp = new Node; 

    for (int i=0; i<k; i++) 
    temp->point[i] = arr[i]; 

    temp->left = temp->right = NULL; 
    return temp; 
 
// Inserts a new node and returns root of modified tree
Node *insertRec(Node *root, int point[], unsigned depth) 
 
    if (root == NULL) 
    return newNode(point);  
    unsigned cd = depth % k; 
    if (point[cd] < (root->point[cd])) 
        root->left = insertRec(root->left, point, depth + 1); 
    else
        root->right = insertRec(root->right, point, depth + 1); 

    return root; 
 
// Function to insert a new point with given point and return new root
Node* insert(Node *root, int point[]) 
 
    return insertRec(root, point, 0); 
 

// driver 
int main() 
 
    struct Node *root = NULL; 
    int points[][k] = 3, 6, 17, 15, 13, 15, 6, 12, 
                    9, 1, 2, 7, 10, 19; 
    int n = sizeof(points)/sizeof(points[0]); 
    for (int i=0; i<n; i++) 
    root = insert(root, points[i]); 
    return 0; 
 

【问题讨论】:

【参考方案1】:

首先不要使用&lt;bits/stdc++.h&gt;。错了。

要找到最近的 k 个元素,您需要以一种首先遍历最近元素的方式遍历树。然后,如果你没有足够的元素,就去遍历那些更远的。

这里就不写代码了,只是伪代码(因为我已经建了一个a long time ago):

list l; # list of the elements, sorted by distance
heap p; # heap of nodes to traverse, sorted by distance

p.push(root)
while (!p.empty())

    node = p.pop(); # Get a new node
    d = distance(point, node); # compute the closest distance from the point to the node
    if(l.empty() or distance(point, l.back()) > d)
    
        add(node->left); # iteration on subnodes
        add(node->right);
        l.push(points); # Add points from the current node
    
    l.pop_elements(k); # pop elements to keep only k

【讨论】:

以上是关于如何从 k-d 树实现 K-NN 分类?的主要内容,如果未能解决你的问题,请参考以下文章

K-NN(最近邻分类算法 python

决策树python实现小样例

k-NN分类器的预测方差和模型偏差

监督分类:绘制不同样本大小和 k 值的 K-NN 精度

class-k近邻算法kNN

n_jobs=-1 的 GridSearchCV 不适用于决策树/随机森林分类