Строковое нечеткое соответствие в кадре данных

avatar
ML_Enthousiast
8 апреля 2018 в 06:33
821
1
0

У меня есть кадр данных, содержащий заголовок статьи и связанные URL-ссылки.

Моя проблема в том, что URL-ссылка не нужна в строке соответствующего заголовка, например:

               title                  |                     urls
    Who will be the next president?   | https://website/5-ways-to-make-a-cocktail.com 
    5 ways to make a cocktail         | https://website/who-will-be-the-next-president.com
    2 millions raised by this startup | https://website/how-did-you-find-your-house.com 
    How did you find your house       | https://website/2-millions-raised-by-this-startup.com
    How did you find your house       | https://washingtonpost/article/latest-movies-in-theater.com
    Latest movies in Theater          | www.newspaper/mynews/what-to-cook-in-summer.com
    What to cook in summer            | https://website/2-millions-raised-by-this-startup.com

Я предполагаю, что мне нужно подумать о такой нечеткой логике сопоставления, но я не уверен, как это сделать. Для дубликатов я просто использую функцию unique.

Я начал использовать функцию levenshteinSim из пакета RecordLinkage, которая дает оценку сходства для каждой строки, но, очевидно, поскольку строки не совпадают, оценка сходства везде низкая.

Я также слышал о функции stringdistmatrix из пакета stringdist, но не знаю, как ее использовать здесь.

Источник
David Arenburg
8 апреля 2018 в 06:40
0

Эта структура "website/[string].com" всегда присутствует или это только ваш пример? Если это так, вы можете использовать простое регулярное выражение, чтобы удалить его и выполнить точное совпадение.

ML_Enthousiast
8 апреля 2018 в 06:54
0

Привет, да, я знаю регулярное выражение, но нет, оно сильно различается, так как существует много разных веб-сайтов:/

David Arenburg
8 апреля 2018 в 07:44
3

Вам, вероятно, следует сделать свой пример более репрезентативным, потому что в его нынешнем виде довольно легко предоставить решение для приведенного вами примера.

Seymour
8 апреля 2018 в 08:01
0

@DavidArenburg полностью согласен

ML_Enthousiast
8 апреля 2018 в 09:57
0

Спасибо за отзыв, я его отредактировал

Jan
9 апреля 2018 в 08:20
0

@DavidArenburg: я опубликовал ответ, но меня интересует, возможно, более простое решение.

Ответы (1)

avatar
Jan
8 апреля 2018 в 19:54
1

Конечно, можно оптимизировать, но это может помочь вам начать:

  1. Функция matcher() преобразует, сравнивает обе строки и возвращает результат
  2. После этого мы попытаемся сопоставить титулы с matcher() и набрать наибольшее количество очков
  3. Если невозможно найти оценку выше порогового значения, выдайте NA


В R:
matcher <- function(needle, haystack) {
  ### Analyzes the url part, converts them to lower case words
  ### and calculates a score to return

  # convert url
  y <- unlist(strsplit(haystack, '/'))
  y <- tolower(unlist(strsplit(y[length(y)], '[-.]')))

  # convert needle
  x <- needle

  # sum it up
  (z <- (sum(x %in% y) / length(x) + sum(y %in% x) / length(y)) / 2)
}

pairer <- function(titles, urls, threshold = 0.75) {
  ### Calculates scores for each title -> url combination
  result <- vector(length = length(titles))
  for (i in seq_along(titles)) {
    needle <- tolower(unlist(strsplit(titles[i], ' ')))
    scores <- unlist(lapply(urls, function(url) matcher(needle, url)))
    high_score <- max(scores)

    # above threshold ?
    result[i] <- ifelse(high_score >= threshold, 
                        urls[which(scores == high_score)], NA)
  }
  return(result)
}

df$guess <- pairer(df$title, df$urls)
df

Это дает

                              title                                                        urls                                                       guess
1   Who will be the next president?               https://website/5-ways-to-make-a-cocktail.com          https://website/who-will-be-the-next-president.com
2         5 ways to make a cocktail          https://website/who-will-be-the-next-president.com               https://website/5-ways-to-make-a-cocktail.com
3 2 millions raised by this startup             https://website/how-did-you-find-your-house.com       https://website/2-millions-raised-by-this-startup.com
4       How did you find your house       https://website/2-millions-raised-by-this-startup.com             https://website/how-did-you-find-your-house.com
5       How did you find your house https://washingtonpost/article/latest-movies-in-theater.com             https://website/how-did-you-find-your-house.com
6          Latest movies in Theater             www.newspaper/mynews/what-to-cook-in-summer.com https://washingtonpost/article/latest-movies-in-theater.com
7            What to cook in summer       https://website/2-millions-raised-by-this-startup.com             www.newspaper/mynews/what-to-cook-in-summer.com
> 
ML_Enthousiast
11 июня 2018 в 15:54
0

эй, извините за мой супер поздний ответ! Большое спасибо ! Я пробовал ваши функции, но в ответ получаю «Ошибка в strsplit (dataf $ url, «/»): несимвольный аргумент», поэтому не уверен, что мне там не хватает...