【问题标题】:supplying a custom distance metric to kNN (due to a circular feature)为 kNN 提供自定义距离度量(由于圆形特征)
【发布时间】:2024-01-13 15:01:01
【问题描述】:

我将在一个数据集上尝试 kNN 分类,该数据集除其他特征外,还包含称为“一天中的时间”的特征。在应用程序的上下文中,星期一 23:58 与星期五 00:04 一样接近星期二 00:02。重要的是钟面上时针的角度。如果不是那个圆形特征,欧几里得距离就可以了。

到目前为止,我知道class::knn()caret::knn3()。但是,我看不到一种方法可以向他们提供我自己的自定义距离度量,甚至没有预先计算的距离矩阵。你知道这样做的方法吗?

一个可能的替代方案是数据准备中的一个额外步骤,即用两个线性(角度 θ 变为一个点 (cosθ,sinθ) )替换圆形特征,或者在 00:00 复制训练集中的数据点边界导致边界消失:https://stats.stackexchange.com/questions/51908/nearest-neighbor-algorithm-for-circular-dimensions 但是,如果可能的话,我宁愿避免将一维替换为二维并创建数据点的副本。

另一种方法是自己计算距离矩阵,然后实现kNN。这听起来很像重新发明*。

我正在寻找一种方法来插入我自己的自定义距离度量的另一个原因如下。虽然周二 15:01 点到周三 15:02 点之间的距离为 1 分钟,但周日 23:00 UTC(货币交易市场开市)被认为与其他任何一天的 23:00 相距“远”。也可能出现其他特殊情况。

【问题讨论】:

    标签: r distance knn


    【解决方案1】:

    Afaik knn 有点不同。它是一种基于实例的方法,这意味着实际模型由实例组成。对于每组测试样本,距离矩阵是根据计算 距离矩阵重新计算的

    您不能仅通过距离矩阵简单地定义 knn。至少我不知道一种方法,在给定一个测试向量的情况下,如何在没有相应的训练向量集的情况下计算距离。

    但是,如果您有 距离矩阵,请查看以下类似问题 Find K nearest neighbors, starting from a distance matrix

    但文档明确表示:

    用法

    k.nearest.neighbors(i, distance_matrix, k = 5)

    参数

    i 来自数字类,是距离矩阵的一行。

    distance_matrix 是一个 nxn 矩阵。

    k 来自数字类,表示函数将返回的邻居数。

    这个恕我直言类似于:

    apply(dm, 1, function(d) "majority vote for labels[order(d) < k]")
    

    假设您有一个 距离矩阵,您已经重新设计了 80% 的 knn

    【讨论】:

    • Drey,尽管我写了,但你说得对。谢谢! FastKNN 包看起来很有前途,会试一试。 (注意到FastKNN::Distance_for_KNN_test() 调用了欧几里得的pdist::pdist(),但只要允许我向FastKNN::k.nearest.neighbors() 提供准备好的距离矩阵,这并不重要)