我在R中构建了一个预测函数,但是当我运行它非常慢时,我只使用了我将在生产中使用的1%数据样本。该函数用于预测给定一系列ngrams(从我的语料库创建的两个单词,三个单词或四个单词组合)的下一个单词。
我将这些单词传递给函数,例如“我可以”,以及一系列三字组合。按顺序排列的输出将是“我能读”,数为4.
这里传递的双字ngram是一个矩阵,dim和示例数据来自位置100。
dim(bigram_index)
[1] 46201 3
bigram_index[,1][100]
[1] "abandon"
bigram_index[,2][100]
[1] "contemporary"
bigram_index[,3][100]
[1] "1"
这是预测函数:
predict.next.word <- function(word, ng_matrix){
ngram_df <- data.frame(predicted=character(), count = numeric(), stringsAsFactors=FALSE)
col_ng_matrix <- nrow(bigram_index)
if(ncol(ng_matrix)==3){
for (i in 1:col_ng_matrix){
first_word <- ng_matrix[,1][i]
second_word <- ng_matrix[,2][i]
count_word <- ng_matrix[,3][i]
if (word[1] == first_word && !is.na(first_word)){
matched_factor <- structure(c(second_word, count_word), .Names = c("predicted", "count"))
ngram_df[i,] <- as.list(matched_factor)
}
}
} else if(ncol(ng_matrix)==4){
for (i in 1:col_ng_matrix){
first_word <- ng_matrix[,1][i]
second_word <- ng_matrix[,2][i]
third_word <- ng_matrix[,3][i]
count_word <- ng_matrix[,4][i]
if (word[1] == first_word && !is.na(first_word) && word[2] == second_word && !is.na(second_word)){
matched_factor <- structure(c(third_word, count_word), .Names = c("predicted", "count"))
ngram_df[i,] <- as.list(matched_factor)
}
}
} else if(ncol(ng_matrix)==5){
for (i in 1:col_ng_matrix){
first_word <- ng_matrix[,1][i]
second_word <- ng_matrix[,2][i]
third_word <- ng_matrix[,3][i]
fourth_word <- ng_matrix[,4][i]
count_word <- ng_matrix[,5][i]
if (word[1] == first_word && !is.na(first_word) && word[2] == second_word
&& !is.na(second_word) && word[3] == third_word && !is.na(third_word)){
ngram_df[i,] <- as.list(matched_factor)
}
}
}
ngram_df <- transform(ngram_df, count = as.numeric(count))
return (ngram_df[order(ngram_df$count, decreasing = TRUE),])
}
这里使用最小的ngram(只有两个字)是时间结果:
system.time(predict.next.word(c("abandon"), bigram_index))
user system elapsed
92.125 59.395 152.149
同样,再次传递的ngram只占生产数据的1%,当我进入三字和四字时,需要更长的时间。请提供您如何提高此功能的速度的见解。
答案 0 :(得分:0)
我不是循环遍历列,而是编写一个执行for()
循环键操作的函数,并使用apply()
(MARGIN=2
表示列,1表示行; I认为你将使用后者)将该函数应用于每一列(FUN=
参数集等于你的函数)。根据输出格式,apply可能不合适。此时,您可以查看plyr
包,dplyr
或我最喜欢的(但有点学习曲线,dplyr
} data.table
包。{ p>
一般情况下,请查看Hadley关于该主题的书籍章节:http://adv-r.had.co.nz/Performance.html
目前,你的代码没有利用这样一个事实,即所谓的“矢量化”R代码在C中执行循环,使它们更快(请原谅我,如果这种描述在技术上是不正确的;只是把想法推到一边)。
对于更具体的示例,查看输入(使用dput(data)
)和所需输出可能会有所帮助。然后我会更容易消化你想要的功能。
一些可以帮助的一般性观点,至少有一点:
ncol(ng_matrix)
次;相反,在开始时做nc.ngm < - ncol(ng_matrix)
一次。节省的费用很少,但这个想法仍然有用。first_word
秒等,而是执行words <- ng_matrix[i,]
之类的操作。然后使用前面提到的对象通过count_word
获取count_word <- words[nc.ngm]
,并将其他单词作为numbered_words <- words[nc.ngm]
。要将word
对象元素与words
元素进行比较,您甚至可以使用mapply
来获取逻辑。同样,如果没有一个例子,这有点难以理解。但总的来说,做“散装”(矢量化)。