比较两个大字符串向量需要太长时间(删除停用词)

时间:2016-08-15 12:10:09

标签: r string string-interpolation string-search stringi

我正在尝试为机器学习准备数据集。在这个过程中,我想删除(停止)几乎没有出现的单词(通常与糟糕的OCR读数有关)。目前我有一个包含大约1百万字的单词列表,我想删除。

但是,使用此设置处理我的数据集需要很长时间。

library(stringi)
#generate the stopword list
b <- stri_rand_strings(1000000, 4, pattern = "[A-Za-z0-9]")

#remove stopstopwords form the dataset
system.time({
  a <- stri_rand_strings(10, 4, pattern = "[A-Za-z0-9]") 
  c <- a[!(a %in% b)]
  c
})

user  system elapsed 
0.14    0.00    0.14 

似乎'%b'中的%不是(远离)O(N)。由于过程在几个小时内没有完成,因此在整个数据集上运行它是不可行的。

是否有更有效的方法来比较R中的两个向量?

我怀疑它的查找应该非常快。我用C#中的Dictionary做了一个测试,几分钟内完成。

1 个答案:

答案 0 :(得分:0)

stringi搜索功能stri_detect_fixed比%运算符中的%快。也许这会对你有所帮助:

  1. 使用这些字词不包含的分隔符粘贴所有停用词 - &gt;这将创建一个长字符串
  2. 在此长字符串上使用stri_detect_fixed
  3. 如果您的禁用词向量被粘贴一次并重复使用,此解决方案的速度提高了两倍甚至二十倍。

    基准测试的一些代码示例:

    library(stringi)
    require(microbenchmark)
    #generate the stopword list
    b <- stri_rand_strings(1000000, 4, pattern = "[A-Za-z0-9]")
    a <- stri_rand_strings(10, 4, pattern = "[A-Za-z0-9]") 
    
    #base R solution
    f1 <- function(a,b){
      a[!(a %in% b)]
    }
    
    # paste inside function
    f2 <- function(a,b){
      c <- stri_paste(b, collapse = ";")
      a[stri_detect_fixed(c, a)]
    }
    
    # paste before and use it later
    c <- stri_paste(b, collapse = ";")
    f3 <- function(a, c){
      a[stri_detect_fixed(c, a)]
    }
    
    microbenchmark(f1(a,b), f2(a,b), f3(a,c))
    # Unit: milliseconds
    #      expr      min        lq       mean     median         uq       max neval
    #  f1(a, b) 63.36563 67.931506 102.725257 116.128525 129.665107 208.46003   100
    #  f2(a, b) 52.95146 53.983946  58.490224  55.860070  59.863900  89.41197   100
    #  f3(a, c)  3.70709  3.831064   4.364609   4.023057   4.310221  10.77031   100