#r
#r #сравнение
Вопрос:
Я хочу сравнить два текста на предмет сходства, поэтому мне нужна простая функция для четкого и хронологического перечисления слов и фраз, встречающихся в обоих текстах. эти слова / предложения должны быть выделены или подчеркнуты для лучшей визуализации)
на основе идей @joris Meys я добавил массив для разделения текста на предложения и придаточные предложения.
вот как это выглядит:
textparts <- function (text){
textparts <- c("\,", "\.")
i <- 1
while(i<=length(textparts)){
text <- unlist(strsplit(text, textparts[i]))
i <- i 1
}
return (text)
}
textparts1 <- textparts("This is a complete sentence, whereas this is a dependent clause. This thing works.")
textparts2 <- textparts("This could be a sentence, whereas this is a dependent clause. Plagiarism is not cool. This thing works.")
commonWords <- intersect(textparts1, textparts2)
commonWords <- paste("\<(",commonWords,")\>",sep="")
for(x in commonWords){
textparts1 <- gsub(x, "\1*", textparts1,ignore.case=TRUE)
textparts2 <- gsub(x, "\1*", textparts2,ignore.case=TRUE)
}
return(list(textparts1,textparts2))
Однако иногда это работает, иногда нет.
Я хотел бы получить такие результаты:
> return(list(textparts1,textparts2))
[[1]]
[1] "This is a complete sentence" " whereas this is a dependent clause*" " This thing works*"
[[2]]
[1] "This could be a sentence" " whereas this is a dependent clause*" " Plagiarism is not cool" " This thing works*"
в то время как я не получаю никаких результатов.
Комментарии:
1. Взгляните на CRAN taskview для обработки естественного языка для вдохновения: cran.r-project.org/web/views/NaturalLanguageProcessing.html
2. спасибо, я знаю об этом сайте. Есть детектор предложений, который мог бы быть полезен для меня, но нет ни одного сравнения предложений, выделяющего то, что я ищу
3. хехе, теперь вы вводите людей в заблуждение. Вы можете добавлять комментарии, если решение не то, что вы ищете, но вам не следует изменять содержание вашего вопроса. Это совершенно другой вопрос. Во-вторых, вы не кодируете C, вы кодируете R. Эта конструкция while() отвратительна. сделайте
for(i in textparts)
и удалите все остальное. И затем вы должны взглянуть на то, что происходит. У вас могут быть пробелы здесь и там, что испортит ваш результат. У вас могут быть различия в верхнем и нижнем регистре. Просмотрите файлы справки и проверьте свои промежуточные результаты, и вы решите проблему.
Ответ №1:
Есть некоторые проблемы с ответом @Chase :
- различия в прописных буквах не учитываются
- вмешательство может испортить результаты
- если есть более одного похожего слова, то вы получаете много предупреждений из-за вызова gsub.
Основываясь на его идее, существует следующее решение, которое использует tolower()
и некоторые приятные функциональные возможности регулярных выражений :
compareSentences <- function(sentence1, sentence2) {
# split everything on "not a word" and put all to lowercase
x1 <- tolower(unlist(strsplit(sentence1, "\W")))
x2 <- tolower(unlist(strsplit(sentence2, "\W")))
commonWords <- intersect(x1, x2)
#add word beginning and ending and put words between ()
# to allow for match referencing in gsub
commonWords <- paste("\<(",commonWords,")\>",sep="")
for(x in commonWords){
# replace the match by the match with star added
sentence1 <- gsub(x, "\1*", sentence1,ignore.case=TRUE)
sentence2 <- gsub(x, "\1*", sentence2,ignore.case=TRUE)
}
return(list(sentence1,sentence2))
}
Это дает следующий результат :
text1 <- "This is a test. Weather is fine"
text2 <- "This text is a test. This weather is fine. This blabalba This "
compareSentences(text1,text2)
[[1]]
[1] "This* is* a* test*. Weather* is* fine*"
[[2]]
[1] "This* text is* a* test*. This* weather* is* fine*. This* blabalba This* "
Комментарии:
1. большое спасибо. еще 1 вопрос: это очень полезно для одного или двух предложений. я хотел бы проанализировать тексты из 10-15 предложений. Другими словами, было бы лучше выполнить поиск по триграммам.
2. @digitalaxp: у вас есть все строительные блоки. Смотрите
?regex
и?strsplit
, например. Это не сложно, но и бесплатно нанять программиста не получится.3. @joris-meys извините, это моя вина! в любом случае, я попробовал это самостоятельно и отредактировал свой первый пост.
Ответ №2:
Я уверен, что на странице обработки естественного языка есть гораздо более надежные функции, но вот одно решение, использующее intersect()
для поиска общих слов. Подход заключается в том, чтобы прочитать два предложения, определить общие слова и gsub()
их комбинацию из слова и прозвища по нашему выбору. Здесь я решил использовать *
, но вы могли бы легко изменить это или добавить что-то еще.
sent1 <- "I shot the sheriff."
sent2 <- "Dick Cheney shot a man."
compareSentences <- function(sentence1, sentence2) {
sentence1 <- unlist(strsplit(sentence1, " "))
sentence2 <- unlist(strsplit(sentence2, " "))
commonWords <- intersect(sentence1, sentence2)
return(list(
sentence1 = paste(gsub(commonWords, paste(commonWords, "*", sep = ""), sentence1), collapse = " ")
, sentence2 = paste(gsub(commonWords, paste(commonWords, "*", sep = ""), sentence2), collapse = " ")
))
}
> compareSentences(sent1, sent2)
$sentence1
[1] "I shot* the sheriff."
$sentence2
[1] "Dick Cheney shot* a man."
Комментарии:
1. Ну, человек, которого застрелил Чейни, технически был адвокатом.
2. 1 для пересечения. Я взял вашу идею и немного доработал ее для получения более общего решения.