2017-11-23 16 views
0

私は、ほぼ14000の文書間の類似度を計算します。しかし、コードは実行に時間がかかりすぎている。同じ作業をより速く行うための他の方法はありますか?私はこのコードを、2時間で実行される最初の文書を実行するとrの文書集合の余弦とjaccardの類似度を計算する

は、ここに私のコード

wb=createWorkbook() #create workbook 
addWorksheet(wb,"absSim") #create worksheet 
listoffiles=list.files() #get list of documents from current working directory 
fileslength=length(listoffiles) #no of documents in directory 
for(i in 1:fileslength-1) 
{ 
    d1=readLines(listoffiles[i])# read first document 
    k=i+1 
    for(j in k:fileslength) 
    { 
    d2=readLines(listoffiles[j]) #read second document 
    #make a vector of two documents 
    myvector=c(d1,d2) 
    #making corpus of two documents 
    mycorpus=Corpus(VectorSource(myvector)) 
    #preprocessing of corpus 
    mycorpus=tm_map(mycorpus,removePunctuation) 
    mycorpus=tm_map(mycorpus,removeNumbers) 
    mycorpus=tm_map(mycorpus,stripWhitespace) 
    mycorpus=tm_map(mycorpus,tolower) 
    mycorpus=tm_map(mycorpus,function(x) removeWords(x,stopwords("english"))) 
    mycorpus=tm_map(mycorpus,function(x) removeWords(x,"x")) 
    #make a document term matrix now 
    dtm=as.matrix(DocumentTermMatrix(mycorpus)) 
    #compute distance of both documents using proxy package 
    cdist=as.matrix(dist(dtm,method = "cosine")) 
    jdist=as.matrix(dist(dtm,method = "jaccard")) 
    #compute similarity 
    csim=1-cdist 
    jsim=1-jdist 
    #get similarity of both documents 
    cos=csim[1,2] 
    jac=jsim[1,2] 
    if(cos>0 | jac>0) 
    { 
    writeData(wb,"absSim",cos,startCol = 1,startRow = rownum) 
    writeData(wb,"absSim",jac,startCol = 2,startRow = rownum) 
    saveWorkbook(wb,"abstractSimilarity.xlsx",overwrite = TRUE) 
    rownum=rownum+1 
    } 
    } 
} 

です。コサインとジャカードの類似性をより速く計算する考えはありますか?

+0

私の経験では、現在この種のタスクの中で最も速いパッケージである 'text2vec'を見てみましょう。いくつかの良いチュートリアルは[text2vec.org](http://text2vec.org/)から入手できます。さらに、あなたのファイルを読む方法はちょっと複雑です。 'list.files()'の使用を検討し、一度にすべての文書を読み込むことができます。 'lapply'を経由して、このオブジェクトからコーパスとdtmを構築します。それは役に立ちますか? –

+0

私は膨大な文書を集めており、さらに多くのスペースを必要とします。 dtmを大規模なコレクションのために非常に複雑にするようにします。 – Alvi

+0

あなたの巨大な意味は何ですか?いくつのドキュメント、平均で1つのドキュメントあたりの用語の数はいくつですか? –

答えて

1

次のコードを試してみることもできます。 text2vecの使い方を説明するだけで、クリーニングやプルーニングが不要な非常に単純化されたバージョンです。私はまた、text2vecのトークナイザより少し速いので、tokenizersパッケージをトークン化に使用しました。私はthis question/answerのためにZachによって提供されたサンプリング機能を使用しました。私のマシンでは1分もかからずに完了します。もちろん、他の類似性の測定または前処理の統合も可能である。私はこれがあなたが探しているものであることを願っています。

library(text2vec) 
library(tokenizers) 

samplefun <- function(n, x, collapse){ 
    paste(sample(x, n, replace=TRUE), collapse=collapse) 
} 

words <- sapply(rpois(10000, 8) + 1, samplefun, letters, '') 

#14000 documents, each with 100 lines (pasted together) of several words 
docs <- sapply(1:14000, function(x) { 

    paste(sapply(rpois(100, 5) + 1, samplefun, words, ' '), collapse = ". ") 

}) 

iterator <- itoken(docs, 
        ,tokenizer = function(x) tokenizers::tokenize_words(x, lowercase = FALSE) 
        ,progressbar = FALSE 
        ) 

vocabulary <- create_vocabulary(iterator) 

dtm <- create_dtm(iterator, vocab_vectorizer(vocabulary)) 

#dtm 
#14000 x 10000 sparse Matrix of class "dgCMatrix" 
#.... 

#use, e.g., the first and second half of the dtm as document sets 
similarity <- sim2(dtm[1:(nrow(dtm)/2),] 
        , dtm[(nrow(dtm)/2+1):nrow(dtm),] 
        , method = "jaccard" 
        , norm = "none") 

dim(similarity) 
#[1] 7000 7000 
関連する問題