向 kNN 提供自定义距离度量(由于圆形特征)

supplying a custom distance metric to kNN (due to a circular feature)

我将尝试对一个数据集进行 kNN 分类,该数据集除其他特征外还包含名为 "time of day" 的数据集。在应用程序的上下文中,星期一 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(货币交易市场开盘)被认为是 "far"天 23:00。其他特殊情况也可能出现。

Afaik knn 的工作方式有点不同。它是一种基于实例的方法,这意味着实际模型由实例组成。对于每组测试样本,根据计算 nxn 距离矩阵 <- 这是你所在的位置吗?

重新计算距离矩阵

你不能简单地仅通过距离矩阵来定义knn。至少我不知道如何在给定测试向量的情况下计算距离而无需相应的训练向量集。

但是如果你有 nxn 距离矩阵然后看看下面的类似问题 Find K nearest neighbors, starting from a distance matrix

但文档明确指出:

Usage

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

Arguments

i is from the numeric class and is a row from the distance_matrix.

distance_matrix is a nxn matrix.

k is from the numeric class and represent the number of neigbours that the function will return.

这个恕我直言类似于:

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

鉴于您有一个 nxn 距离矩阵,您已经重新设计了 knn

的 80%