替换 R 中的循环 : multivariate k-nearest neighbor regression example

标签 r algorithm loops nearest-neighbor

我是 R 新手,正在尝试用更有效的东西替换附加代码块中的循环。对于上下文,这是具有多元(3 维)目标的 k 最近邻回归的简单综合示例。

rm(list=ls())
set.seed(1)

# Fast nearest neighbor package
library(FNN)
k <- 3

# Synthetic 5d predictor and noisy 3d target data
x <- matrix(rnorm(50), ncol=5)
y <- 5*x[,1:3] + matrix(rnorm(30), ncol=3)
print(x)
print(y)

# New synthetic 5d predictor data (4 cases)
x.new <- matrix(rnorm(20), ncol=5)
print(x.new)

# Identify k-nearest neighbors
nn <- knnx.index(data=x, query=x.new, k=k)
print(nn)

目前,我通过以下循环获取 k 最近邻 (nn) 的未加权平均值:

# Unweighted k-nearest neighbor regression predictions based on y and nn
y.new <- matrix(0, ncol=ncol(y), nrow=nrow(x.new))
for(i in 1:nrow(nn))
    y.new[i,] <- colMeans(y[nn[i,],,drop=FALSE])

print(y.new)

但是必须有一个简单的方法来避免这里循环。谢谢。

最佳答案

在这些情况下,一个选择是构建一个大矩阵并操纵索引:

y2<-array(colMeans(matrix(y[t(nn),],nrow=ncol(nn))),dim(y.new))
identical(y2,y.new) 
## [1] TRUE

在这种情况下,我的代码运行速度大约是你的两倍:

microbenchmark(
loop = for(i in 1:nrow(nn))
    y.new[i,] <- colMeans(y[nn[i,],,drop=FALSE]),
matrix=y2<-array(colMeans(matrix(y[t(nn),],nrow=ncol(nn))),dim(y.new)))
## Unit: microseconds
##    expr    min      lq  median     uq     max neval
##    loop 43.680 47.8805 49.1675 49.975 128.698   100
##  matrix 23.807 25.4330 25.9985 26.761  80.491   100

这种情况下的循环并没有那么糟糕。一般来说,只要您在循环中执行大量工作(在本例中对矩阵进行子集化并调用 colMeans),那么每次迭代的开销与循环的实际内容相比就会很小。在 R 中真正需要避免循环的时候是每次迭代只执行少量工作的情况,在这种情况下,R 中迭代的开销将真正成为瓶颈,而避免循环可以显着提高性能。

循环的优点是你在做什么非常清楚,而我的代码却相当难以理解。然而,像这样进行矩阵索引操作通常会更快,有时会快很多,因为您只对 y 矩阵进行子集化一次,而不是每次循环一次。

关于替换 R 中的循环 : multivariate k-nearest neighbor regression example,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19284939/

相关文章:

c++ - 电话号码中字母和数字的排列

java - 如何按照列表描述的顺序有效地处理HashMap?

javascript - 使用映射返回多维数组中的第一个索引

c - 我怎样才能加快这个循环(在 C 中)?

r - 识别相关图中落在 CI 之外的数据点

r - 如何通过分类变量过滤 R 中的 data.frame?

r - 检查数据框中多个列的相同值

algorithm - 如何简化样条曲线?

r - 将向量传递给 R 中的粘贴函数

laravel - 如何在 Laravel Blade 中显示数组的动态键?