【问题标题】:Fast way to get topN elements for each matrix column获取每个矩阵列的 topN 元素的快速方法
【发布时间】:2014-10-29 17:13:55
【问题描述】:

这是来自recommenderlab 包的代码 sn-p,它采用带有评分的矩阵并返回每个用户的前 5 个元素 -

reclist <- apply(ratings, MARGIN=2, FUN=function(x) 
  head(order(x, decreasing=TRUE, na.last=NA), 5))

对于大型矩阵(>10K 列)运行时间太长,有没有办法重新编写它以提高效率?也许通过使用 dpyr 或 data.table 包)?编写 C++ 代码不是我的选择

【问题讨论】:

  • 你有多少行?
  • 在我的例子中,它只有 100 个。但由于这里的行代表已售出的物品,可能高达 1M。所以这个案例对其他人来说可能很有趣

标签: r recommendation-engine


【解决方案1】:

data.table 和 base R 的答案

# 10000 column dummy matrix
cols <- 10000
mat <- matrix(rnorm(100*cols), ncol=cols)

带data.table:

library(data.table)
dt1 <- data.table(mat)
# sort every column, return first 5 rows
dt1[, lapply(.SD, sort, decreasing=T)][1:5]
system.time(dt1[, lapply(.SD, sort, decreasing=T)][1:5])

结果:

 user  system elapsed 
2.904   0.013   2.916 

在普通的旧基地中,它实际上更快! (感谢阿伦的评论)

system.time(head(apply(mat, 2, sort, decreasing=T), 5))

 user  system elapsed 
0.473   0.002   0.475 

但是,根据 system.time(),两者都比上面的代码示例快

system.time(
apply(mat, MARGIN=2, FUN=function(x) {
  head(order(x, decreasing=TRUE, na.last=NA), 5)
}))

user  system elapsed 
3.063   0.031   3.094 

【讨论】:

  • 在这里使用data.table到底有什么好处?
  • 是的,好点。自从OP提到它以来,我就这样做了,但是当我进行头对头比较时,直接对矩阵进行操作会更快。
  • 不用担心。 apply + sort 看起来很棒!也许也可以尝试sort.intpartial=5L ......不过,瓶颈似乎是sorting/orderingdata.table 的内部基数顺序 forderv(尚未导出)可能有用,特别是如果还有很多行!
猜你喜欢
  • 1970-01-01
  • 2021-11-23
  • 2014-08-30
  • 2018-02-11
  • 2012-11-20
  • 2022-12-12
  • 2023-03-25
  • 2013-07-02
  • 1970-01-01
相关资源
最近更新 更多