2016-11-25 2 views
4

Мне нужно рассчитать сходство Jaccard между каждым словом в 2 вектора. Каждое слово по каждому слову. И извлечь наиболее похожее слово.Рассчитайте сходство Jaccard между двумя словами в 2 векторах

Вот мой плохой плохой медленный код:

txt1 <- c('The quick brown fox jumps over the lazy dog') 
txt2 <- c('Te quick foks jump ovar lazzy dogg') 

words <- strsplit(as.character(txt1), " ") 
words.p <- strsplit(as.character(txt2), " ") 

r <- length(words[[1]]) 
c <- length(words.p[[1]]) 

m <- matrix(nrow=r, ncol=c) 
for (i in 1:r){ 
    for (j in 1:c){ 
    m[i,j] = stringdist(tolower(words.p[[1]][j]), tolower(words[[1]][i]), method='jaccard', q=2) 
    } 
} 

ind <- which(m == min(m))-nrow(m) 
words[[1]][ind] 

Пожалуйста, помогите мне улучшить и украсить этот код для большого кадра данных.

+0

Насколько велика «большой», и сколько времени это займет, используя код? – lukeA

+0

Попробуйте это 'sapply (words.p, function (x) mapply (stringdist, words, x, method = 'jaccard'))'. Это напрямую даст вам матрицу, которую вы можете легко изучить. –

ответ

3

Подготовка (добавлено tolower здесь):

txt1 <- c('The quick brown fox jumps over the lazy dog') 
txt2 <- c('Te quick foks jump ovar lazzy dogg') 

words <- unlist(strsplit(tolower(as.character(txt1)), " ")) 
words.p <- unlist(strsplit(tolower(as.character(txt2)), " ")) 

Получит расстояния для каждого слова:

dists <- sapply(words, Map, f=stringdist, list(words.p), method="jaccard") 

Для каждого слова в words найти ближайшее слово из words.p:

matches <- words.p[sapply(dists, which.min)] 

cbind(words, matches) 
       matches 
[1,] "the" "te" 
[2,] "quick" "quick" 
[3,] "brown" "ovar" 
[4,] "fox" "foks" 
[5,] "jumps" "jump" 
[6,] "over" "ovar" 
[7,] "the" "te" 
[8,] "lazy" "lazzy" 
[9,] "dog" "dogg" 

EDIT:

Чтобы получить лучшее соответствие пару слов, сначала нужно выбрать минимальное расстояние от каждого слова в words для всех слов в words.p:

mindists <- sapply(dists, min) 

Это позволит получить ваши лучшие возможные расстояния для каждого слова. Затем вы выбираете слово из words с минимальным расстоянием:

words[which.min(mindists)] 

Или в одной строке:

words[which.min(sapply(dists, min))] 
+0

Спасибо! Но я хочу получить только одно лучшее слово, в этом случае это «быстро». Как его извлечь? – Dennix

+0

@ Dennix добавила строку о том, как это сделать в ответе (после EDIT) –

+0

@ KarolisKoncevičius, Спасибо за ваше решение. Я искал что-то подобное, но для сопоставления списка адресов. Поэтому у меня есть набор данных, содержащий около 70 тыс. Разных адресов и еще один большой набор данных, который содержит около 4 недочетов (0,4 млн.). Я хочу сопоставить каждый адрес с большим набором данных, глядя на слова адреса. Как я могу это достичь? Я отправил вопрос по ссылке http://stackoverflow.com/questions/42486172/r-string-match-for-address-using-stringdist-stringdistmatrix Пожалуйста, помогите !! – user1412

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