2016-09-12 2 views
3

단어 목록을 문장 목록과 대조하고 일치하는 단어와 문장이있는 데이터 프레임을 구성하려고합니다.단어 목록을 문장 목록과 일치 시키려고 할 때 성능 문제가 발생했습니다. R

sentences            words 
This document is far better        better 
This is a great app          great 
The night skies were sombre and starless     sombre 
The app is too good and i am happy using it    good, happy 
This is how it works          - 

을 내가 이것을 달성하기 위해 다음 코드를 사용하고 예를 들어 다음과 같이

words <- c("far better","good","great","sombre","happy") 
sentences <- c("This document is far better","This is a great app","The night skies were sombre and starless", "The app is too good and i am happy using it", "This is how it works") 

예상되는 결과 (A dataframe)입니다.

lengthOfData <- nrow(sentence_df) 
pos.words <- polarity_table[polarity_table$y>0]$x 
neg.words <- polarity_table[polarity_table$y<0]$x 
positiveWordsList <- list() 
negativeWordsList <- list() 
for(i in 1:lengthOfData){ 
     sentence <- sentence_df[i,]$comment 
     #sentence <- gsub('[[:punct:]]', "", sentence) 
     #sentence <- gsub('[[:cntrl:]]', "", sentence) 
     #sentence <- gsub('\\d+', "", sentence) 
     sentence <- tolower(sentence) 
     # get unigrams from the sentence 
     unigrams <- unlist(strsplit(sentence, " ", fixed=TRUE)) 

     # get bigrams from the sentence 
     bigrams <- unlist(lapply(1:length(unigrams)-1, function(i) {paste(unigrams[i],unigrams[i+1])})) 

     # .. and combine into data frame 
     words <- c(unigrams, bigrams) 
     #if(sentence_df[i,]$ave_sentiment) 

     pos.matches <- match(words, pos.words) 
     neg.matches <- match(words, neg.words) 
     pos.matches <- na.omit(pos.matches) 
     neg.matches <- na.omit(neg.matches) 
     positiveList <- pos.words[pos.matches] 
     negativeList <- neg.words[neg.matches] 

     if(length(positiveList)==0){ 
      positiveList <- c("-") 
     } 
     if(length(negativeList)==0){ 
      negativeList <- c("-") 
     } 
     negativeWordsList[i]<- paste(as.character(unique(negativeList)), collapse=", ") 
     positiveWordsList[i]<- paste(as.character(unique(positiveList)), collapse=", ") 

     positiveWordsList[i] <- sapply(positiveWordsList[i], function(x) toString(x)) 
     negativeWordsList[i] <- sapply(negativeWordsList[i], function(x) toString(x)) 

    }  
positiveWordsList <- as.vector(unlist(positiveWordsList)) 
negativeWordsList <- as.vector(unlist(negativeWordsList)) 
scores.df <- data.frame(ave_sentiment=sentence_df$ave_sentiment, comment=sentence_df$comment,pos=positiveWordsList,neg=negativeWordsList, year=sentence_df$year,month=sentence_df$month,stringsAsFactors = FALSE) 

28k 문장과 65k 단어가 있습니다. 위의 코드는 작업을 완료하는 데 45 초가 걸립니다. 현재 접근 방식으로 코드의 성능을 향상시키는 방법에 대한 제안은 많은 시간이 필요합니까?

편집 : 나는 정확하게 문장에있는 단어와 일치하는 경우에만 해당 단어를 얻고 싶은

. 예를 들면 :

sentences               words 
Since the app crashes frequently, I advice you guys to fix  crahses 
the issue ASAP 
+1

당신은 병렬로 그것을 할 수 있습니다. –

+1

그게 더 나아 졌습니까? '도서관 (stringi); –

+0

@David 나는이 솔루션을 사용하여 계산 시간을 줄 였지만 출력을 데이터 프레임으로 필요로 할 때 그 방법을 말해 줄 수 있습니까? (예 : 문장, function (x) toString (words [stri_detect_fixed (x, words)]) – Venu

답변

1

내가 약간의 수정과 함께 @ 데이비드 Arenburg 답변을 사용할 수 있었다 다음과 같이

words <- c('sin','vice','crashes') 
sentences <- ('Since the app crashes frequently, I advice you guys to fix the issue ASAP') 

지금 위의 경우 내 출력해야한다. 여기 내가 한 일이있다. 데이비드 (David)가 제안한 다음을 사용하여 데이터 프레임을 구성했습니다.

df <- data.frame(sentences) ; 
df$words <- sapply(sentences, function(x) toString(words[stri_detect_fixed(x, words)])) 

위의 접근 방식의 문제점은 정확한 단어 일치를 수행하지 않는다는 것입니다. 그래서 다음 문장을 사용하여 문장의 단어와 정확히 일치하지 않는 단어를 필터링했습니다.

df <- data.frame(fil=unlist(s),text=rep(df$sentence, sapply(s, FUN=length))) 

위의 행을 적용한 후 출력 데이터 프레임은 다음과 같이 변경됩니다.

sentences              words 
This document is far better         better 
This is a great app           great 
The night skies were sombre and starless      sombre 
The app is too good and i am happy using it     good 
The app is too good and i am happy using it     happy 
This is how it works           - 
Since the app crashes frequently, I advice you guys to fix  
the issue ASAP             crahses 
Since the app crashes frequently, I advice you guys to fix  
the issue ASAP             vice 
Since the app crashes frequently, I advice you guys to fix  
the issue ASAP             sin 

이제 다음 필터를 데이터 프레임에 적용하여 문장에있는 단어와 정확하게 일치하지 않는 단어를 제거하십시오.

df <- df[apply(df, 1, function(x) tolower(x[1]) %in% tolower(unlist(strsplit(x[2], split='\\s+')))),] 

내 결과 데이터 프레임은 다음과 같습니다.

sentences              words 
    This document is far better         better 
    This is a great app           great 
    The night skies were sombre and starless      sombre 
    The app is too good and i am happy using it     good 
    The app is too good and i am happy using it     happy 
    This is how it works           - 
    Since the app crashes frequently, I advice you guys to fix  
    the issue ASAP             crahses 

stri_detect_fixed stri_detect_fixed는 내 계산 시간을 크게 줄입니다. 나머지 프로세스는 많은 시간을 소비하지 않았습니다. 나를 올바른 방향으로 인도 해 주신 @David에게 감사드립니다.

0

당신은 extract_sentiment_terms와 sentimentr 의 최신 버전에서이 작업을 수행 할 수 있습니다하지만 당신은 먼저 감정 키 확인해야하고 단어에 값을 할당 할 수 있습니다 :

pos <- c("far better","good","great","sombre","happy") 
neg <- c('sin','vice','crashes') 

sentences <- c('Since the app crashes frequently, I advice you guys to fix the issue ASAP', 
    "This document is far better", "This is a great app","The night skies were sombre and starless", 
    "The app is too good and i am happy using it", "This is how it works") 

library(sentimentr) 
(sentkey <- as_key(data.frame(c(pos, neg), c(rep(1, length(pos)), rep(-1, length(neg))), stringsAsFactors = FALSE))) 

##    x y 
## 1: crashes -1 
## 2: far better 1 
## 3:  good 1 
## 4:  great 1 
## 5:  happy 1 
## 6:  sin -1 
## 7:  sombre 1 
## 8:  vice -1 

extract_sentiment_terms(sentences, sentkey) 

## element_id sentence_id negative positive 
## 1:   1   1 crashes   
## 2:   2   1   far better 
## 3:   3   1    great 
## 4:   4   1    sombre 
## 5:   5   1   good,happy 
## 6:   6   1