R:中数百万个小匹配需要性能
我有一个一百万长的单词向量,叫做单词。我有一张900万的物品清单,叫做句子。我列表中的每个对象都是一个句子,由10-50个单词组成的向量表示。以下是一个例子:R:中数百万个小匹配需要性能,r,performance,join,position,match,R,Performance,Join,Position,Match,我有一个一百万长的单词向量,叫做单词。我有一张900万的物品清单,叫做句子。我列表中的每个对象都是一个句子,由10-50个单词组成的向量表示。以下是一个例子: head(WORDS) [1] "aba" "accra" "ada" "afrika" "afrikan" "afula" "aggamemon" SENTENCES[[1]] [1] "how" "to" "interpret" "that" "picture" 我想将列表中的每个句子转换成一个数字向量,其元素对应于句子单词在单词
head(WORDS)
[1] "aba" "accra" "ada" "afrika" "afrikan" "afula" "aggamemon"
SENTENCES[[1]]
[1] "how" "to" "interpret" "that" "picture"
我想将列表中的每个句子转换成一个数字向量,其元素对应于句子单词在单词大向量中的位置。
实际上,我知道如何使用该命令:
convert <- function(sentence){
return(which(WORDS %in% sentence))
}
SENTENCES_NUM <- lapply(SENTENCES, convert)
convertfastmatch,一个由R核心人员编写的小程序包,对查找进行哈希运算,以便初始搜索,尤其是后续搜索更快
你真正要做的是使每个句子都有一个具有预定义级别的因子。他的C代码中缓慢的一步是对因子级别进行排序,您可以通过向其快速版本的因子函数提供因子级别的(唯一)列表来避免这种情况
如果您只需要整数位置,您可以轻松地从因子转换为整数:许多人会无意中这样做
实际上,你根本不需要一个因子来满足你的需求,只要匹配。您的代码还生成一个逻辑向量,然后从中重新计算位置:match
直接进入位置
library(fastmatch)
library(microbenchmark)
WORDS <- read.table("https://dotnetperls-controls.googlecode.com/files/enable1.txt", stringsAsFactors = FALSE)[[1]]
words_factor <- as.factor(WORDS)
# generate 100 sentences of between 5 and 15 words:
SENTENCES <- lapply(c(1:100), sample, x = WORDS, size = sample(c(5:15), size = 1))
bench_fun <- function(fun)
lapply(SENTENCES, fun)
# poster's slow solution:
hg_convert <- function(sentence)
return(which(WORDS %in% sentence))
jw_convert_match <- function(sentence)
match(sentence, WORDS)
jw_convert_match_factor <- function(sentence)
match(sentence, words_factor)
jw_convert_fastmatch <- function(sentence)
fmatch(sentence, WORDS)
jw_convert_fastmatch_factor <- function(sentence)
fmatch(sentence, words_factor)
message("starting benchmark one")
print(microbenchmark(bench_fun(hg_convert),
bench_fun(jw_convert_match),
bench_fun(jw_convert_match_factor),
bench_fun(jw_convert_fastmatch),
bench_fun(jw_convert_fastmatch_factor),
times = 10))
# now again with big samples
# generating the SENTENCES is quite slow...
SENTENCES <- lapply(c(1:1e6), sample, x = WORDS, size = sample(c(5:15), size = 1))
message("starting benchmark two, compare with factor vs vector of words")
print(microbenchmark(bench_fun(jw_convert_fastmatch),
bench_fun(jw_convert_fastmatch_factor),
times = 10))
因此,我现在还不会遇到并行实现的麻烦。不会更快,但这是一种整洁的方式
library(dplyr)
library(tidyr)
sentence =
data_frame(word.name = SENTENCES,
sentence.ID = 1:length(SENTENCES) %>%
unnest(word.name)
word = data_frame(
word.name = WORDS,
word.ID = 1:length(WORDS)
sentence__word =
sentence %>%
left_join(word)
你用mclappy
?Thkx试过了吗?没有,我在Windows上,我只有一个Core。另外,你试过pmatch
而不是,它(…%in%…)
?我注意到你没有接受你所问问题的任何答案。虽然接受答案不是强制性的,但如果其中一个答案对您有效,那么接受答案被认为是良好的做法。这将为未来的读者提供有关解决方案价值的线索。另请参见此帮助页:哦,抱歉,我不知道此Jaap。好的,谢谢。让我们假设我只是想把世界映射成整数,不管这些整数是什么——因为实际上,我不想用单词的位置来把句子转换成数字向量,你看到更简单的东西了吗?我假设你希望相同的单词在每个句子中用相同的数字来表示。如果不是这样,它会稍微简化问题,但我怀疑这是你所追求的。即使你不关心每个句子中的单词顺序,也就是说它们将如何被R存储(因为没有相当于C++的代码> STD::unSoReDeStEd)。我刚试过。真令人印象深刻。我真的需要了解如何将700K秒提高到3秒!我不是一名计算机科学家,但我必须学会一些性能技巧。正如我所理解的那样,散列是从元素本身派生包含set元素的bucket的一种方法。这是一个很好的开始。我要补充的唯一一点是,值得一看源代码,特别是当某些代码比您需要的慢时。您需要确切地知道CPU对数据做了什么,以便加速数据。在您的例子中,每次查找都会将大量数据从主内存分流到CPU,这很可能是瓶颈
library(dplyr)
library(tidyr)
sentence =
data_frame(word.name = SENTENCES,
sentence.ID = 1:length(SENTENCES) %>%
unnest(word.name)
word = data_frame(
word.name = WORDS,
word.ID = 1:length(WORDS)
sentence__word =
sentence %>%
left_join(word)