2016-08-15 2 views
3

機械学習用のデータセットを準備しようとしています。このプロセスでは、(ほとんどの場合、悪いOCRの読みに関連する)出現の少ない単語を削除(停止)したいと考えています。現在、私は削除したい約1mioの単語を含む単語のリストを持っています。2つの大きな文字列ベクトルの比較に時間がかかりすぎる(ストップワードを削除する)

ただし、この設定でデータセットを処理するのに時間がかかります。

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 

「a%in%b」はO(N)ではないようです。プロセスが数時間以内に完了しないため、データセット全体でこれを実行することは不可能です。

Rの2つのベクトルを比較する効率的な方法はありますか?

私はそれがルックアップとして非常に速くなければならないと思う。私は数分で完了するC#で辞書を使ってテストを行いました。

+0

data.table'が速くすなわちあるべき 'から'%の顎% 'で試してみてください' system.time({C < - [(%の顎% b)]}) #user system elapsed 0.01 0.00 0.02 'は%in%に基づいて' 0.13'と比較しています – akrun

答えて

0

stringistri_detect_fixedのような検索機能は%in%演算子よりも高速です。多分これはあなたを助ける:

  1. これらの単語が含まれていないことを、いくつかの分離器を使用して、すべてのストップワードを貼り付け - >これは1つの長い文字列を作成します
  2. この長い文字列にstri_detect_fixed使用

このストップワードベクタを1度貼り付けて再利用すると、ソリューションは2倍または20倍高速になります。

ベンチマークといくつかのコード例:!

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 
関連する問題