2016-02-29 6 views
0

Я изо всех сил пытаюсь выполнить свой подход для измерения сходства между строками. Что делает этот подход:Измерение подобия между строковым элементом по элементу вектора в R

Он измеряет сходство между любыми строковыми элементами с другими строковыми элементами в sentenceMatch data frame. Я использую levenshteinSimFunction для измерения подобия между строками, которые слегка исправлены levenshteinDist функция.

Ниже мой подход.

sentenceMatch <- data.frame(Sentence=c("job not ready time window pmg inc gvu austin timedout pmg inc plm", 
            "data delay hpsb unable deliver icon scp action required http hpedia osp", 
            "job completed abnormally wwapo bw kili inc promaster", 
            "job completed abnormally apo ww promaster net apoww abend apo ww", 
            "error occurred launching job apo ww inc promaster net errorlaunching apo")) 

sentenceMatch$Sentence <- as.character(sentenceMatch$Sentence) 

overallMatrix <- matrix(, nrow = dim(sentenceMatch)[1], ncol = dim(sentenceMatch)[1]) # creating output matrix 

for (k in 1:dim(sentenceMatch)[1]) { 
    for (l in 1:dim(sentenceMatch)[1]) { 
     ifelse(k == l, overallMatrix[k, l] <- 0, overallMatrix[k, l] <- levenshteinSimFunction(sentenceMatch[k, ], sentenceMatch[l, ])) 
     if (overallMatrix[k, l] < .2) {overallMatrix[k, l] <- 0} 
    } 
    } 

Это привело в матрицу этих сравнений, где каждый элемент выходной матрицы представляет levenshteinSimFunction (sentenceMatch [к,], sentenceMatch [л]), который возвращает номер (измерение подобия) между 0 и 1.

levenshteinSimFunction = function (str1, str2) 
{ 
    if (str1 != "" && str2 != "") { 
    return(1 - (levenshteinDist(str1, str2)/max(nchar(str1), 
              nchar(str2)))) 
    } 
    else {return (0)} 
} 

> overallMatrix 
      1   2   3   4   5 
1 0.0000000 0.2394366 0.2615385 0.2307692 0.3055556 
2 0.2394366 0.0000000 0.0000000 0.0000000 0.0000000 
3 0.2615385 0.0000000 0.0000000 0.5156250 0.2916667 
4 0.2307692 0.0000000 0.5156250 0.0000000 0.4444444 
5 0.3055556 0.0000000 0.2916667 0.4444444 0.0000000 

Все работает в соответствии с моим ожиданием, но я столкнулся с проблемой производительности из-за двух циклов.

Есть ли другое (лучшее) решение, как избежать этих двух циклов и ускорить работу.

Производительность определяется номером комбинации n выше 2, который экспоненциально увеличивает время обработки, поэтому, например, 1000 предложений, время вычисления составляет 257,97 секунд. В моем случае у меня есть 25 тысяч предложений.

+0

Откуда берутся levenshteinSimFunction? Ваш код не может быть протестирован или реплицирован без этой функции. – Heroka

+0

Извините за это. Я добавил эту функцию в описание. – martinkabe

+0

И откуда берется 'levenshteinDist'? –

ответ

0

Вы можете использовать пакет stringdist. С помощью команды stringdistmatrix вы можете вычислить значение stringdistance в матричной форме. И один из вариантов - запустить многопоточность, отметьте ??stringdistmatrix. В базовой форме он работает, как показано ниже.

library(stringdist) 

sentenceMatch <- data.frame(Sentence=c("job not ready time window pmg inc gvu austin timedout pmg inc plm", 
             "data delay hpsb unable deliver icon scp action required http hpedia osp", 
             "job completed abnormally wwapo bw kili inc promaster", 
             "job completed abnormally apo ww promaster net apoww abend apo ww", 
             "error occurred launching job apo ww inc promaster net errorlaunching apo")) 

sentenceMatch$Sentence <- as.character(sentenceMatch$Sentence) 

overallMatrix <- stringdistmatrix(sentenceMatch$Sentence, sentenceMatch$Sentence, method = "lv") 
+0

Это очень хорошо, спасибо за это. Но, к сожалению, он возвращает количество совпадающих символов для комбинации двух строк. Как я могу связать строку с большей длиной из каждой из этих двух строк? – martinkabe

+0

@martinkabe, см. [Эту ссылку] (http://stackoverflow.com/questions/35701428/max-nchar-from-two-strings-in-matrix) для аналогичного вопроса. – phiver

Смежные вопросы