如何在R中使用Mahalanobis距离查找时间序列K最近邻
问题解答
支持马氏距离的KNN实现方案
你之前使用的get.knn()、get.knnx()属于FNN包的函数,仅内置了欧氏距离、曼哈顿距离等少数固定度量,不支持直接设置马氏距离,可通过以下两种方式实现需求:
- 直接调用
dbscan包的kNN()函数,该函数支持自定义距离度量,指定method = "mahalanobis"参数即可直接计算马氏距离的K近邻,代码实现更简洁。 - 手动计算所有训练样本和2021年观测值的马氏距离,排序后取前10位,适合小体量数据集使用。
mahalanobis()函数返回值说明
你调用mahalanobis()得到的数值是马氏距离的平方,不是原始马氏距离。但距离的平方和原始距离的升序排序结果完全一致,你可以直接对这组数值做升序排序,取前10位对应的训练集样本,就是你需要的10个最近邻。
可复用代码示例
# 加载依赖包(如果用方法1需要安装dbscan包:install.packages("dbscan")) library(dbscan) # 替换为你自己的数据集:train为1970-2020年训练集(矩阵/数据框格式),test_2021为2021年单条观测 # 方法1:用kNN函数直接计算 knn_res <- kNN(x = train, query = test_2021, k = 10, method = "mahalanobis") # knn_res$id 为10个最近邻在训练集中的索引,knn_res$dist 为对应的马氏距离 # 方法2:手动计算后排序 # 计算训练集协方差矩阵,若存在共线性可添加极小岭校正避免矩阵不可逆:cov_mat <- cov(train) + diag(1e-6, ncol(train)) cov_mat <- cov(train) # 计算所有训练样本到目标样本的马氏距离平方 mahala_sq <- mahalanobis(x = train, center = test_2021, cov = cov_mat) # 升序排序取前10的索引 top10_index <- order(mahala_sq)[1:10] # 提取对应的10个最近邻样本 top10_samples <- train[top10_index, ]
内容的提问来源于stack exchange,提问作者Rua Jing
相关产品推荐
相关产品推荐

