нечеткое извлечение имен (хранящихся в векторе) из текстового столбца в R - PullRequest
0 голосов
/ 10 июля 2020

У меня есть данные, содержащие текст, и я хотел бы попытаться извлечь названия компаний из текста. Данные выглядят так:

d <- data.frame(
  textColumn = c(
    "Apple CEO reports positive growth in Iphone sales",
    "Apple's quarterly results are expected to beat that of Intel's",
    "Microsoft is expected to release a new product which rivales Apple's Iphone which uses Intels processors",
    "Intel Corporation seeks to hire 5000 new staff",
    "Amazon enters a new market, the same as Intel"
  )
)

Данные:

                                                                   textColumn
1                           Apple CEO reports positive growth in Iphone sales
2              Apple's quarterly results are expected to beat that of Intel's
3 Microsoft is expected to release a new product which rivales Apple's Iphone
4                              Intel Corporation seeks to hire 5000 new staff
5                               Amazon enters a new market, the same as Intel

В векторе у меня есть несколько названий компаний.

companyNames <- c(
  "Apple Inc",
  "Intel Corp",
  "Microsoft Corporation",
  "Amazon Company"
)

Данные:

[1] "Apple Inc"             "Intel Corp"            "Microsoft Corporation" "Amazon Company"  

Данные в тексте не позволяют мне точно извлечь названия компаний, поскольку символьная строка в основном содержит полное название компании Apple Inc, Intel Corp et c. но текстовые данные относятся только к компании Apple и Intel et c.

Я хотел бы использовать извлечение нечеткой строки, чтобы попытаться извлечь названия компаний из текста, чтобы ожидаемый результат с использованием этот пример будет:

c(
  "Apple",
  "Apple | Intel",
  "Microsoft | Apple | Intel",
  "Intel",
  "Amazon | Intel"
)

Данные:

[1] "Apple"                     "Apple | Intel"             "Microsoft | Apple | Intel" "Intel"                     "Amazon | Intel" 

Поскольку Apple встречается только один раз в первой строке текстовых данных, тогда как Apple и Intel оба встречаются во второй строке (поэтому я разделяю их |). Я просматриваю fuzzyExtract из пакета fuzzywuzzyR здесь , но я не могу заставить его работать с моими образцами данных.

Ответы [ 2 ]

1 голос
/ 10 июля 2020

Здесь используется stringr, чтобы очистить названия компаний, извлечь их, а затем свернуть имена в вектор. Я уверен, что это потребует некоторой адаптации с вашей стороны, но это определенно должно помочь вам начать работу. Кроме того, \\b в регулярном выражении является границей - он защищает от частичных совпадений для элементов org_type. Надеюсь, это поможет !!

library(stringr)

# Removing the organization types  you listed (e.g., Inc)
# You may also grab the first word, I chose types because it was more explicit
# but it would reqiure checking on your part (either option will)
org_type <- c("Inc", "Corp", "Corporation", "Company")

company_clean <- str_remove_all(companyNames, str_c("\\s*\\b", org_type, "\\b", collapse = "|"))

# Extracting the company name matches from the list and pasting them together
sapply(str_extract_all(d$textColumn, str_c(company_clean, collapse = "|")), paste0, collapse = " | ")
[1] "Apple"                     "Apple | Intel"             "Microsoft | Apple | Intel" "Intel"                     "Amazon | Intel"    
0 голосов
/ 20 июля 2020

Что вам действительно нужно, так это точное совпадение (при условии, что названия компаний одинаковы как в 'd' data.frame, так и в векторе 'companyNames'),


    # use stringsAsFactors = FALSE
    d <- data.frame(
      textColumn = c(
        "Apple CEO reports positive growth in Iphone sales",
        "Apple's quarterly results are expected to beat that of Intel's",
        "Microsoft is expected to release a new product which rivales Apple's Iphone which uses Intels processors",
        "Intel Corporation seeks to hire 5000 new staff",
        "Amazon enters a new market, the same as Intel"
      ), stringsAsFactors = FALSE
    )
    
    companyNames <- c(
      "Apple Inc",
      "Intel Corp",
      "Microsoft Corporation",
      "Amazon Company"
    )
    
    
    # extract the company names (without the extensions Inc, Corp etc.)
    companyNames = unlist(lapply(strsplit(companyNames, ' '), function(x) x[1]))
    
    
    # use 'gregexpr' and 'substr' to append the company names to the 'output' vector
    output = rep(NA, nrow(d))
    
    for (ROW in 1:nrow(d)) {
      
      iter_row = d[ROW, , drop = T]
      iter_vec = c()
      
      for (NAME in companyNames) {
        iter_match = gregexpr(pattern = NAME, text = iter_row)
        
        for (idx_match in 1:length(iter_match)) {
          if (iter_match[[idx_match]] != -1) {
          
            match_start_idx = iter_match[[idx_match]][1]
            match_length = attr(iter_match[[idx_match]], "match.length")
            
            iter_company = substr(iter_row, match_start_idx, match_start_idx + match_length - 1)
            iter_vec = append(iter_vec, iter_company)
          }
        }
      }
      
      output[ROW] = paste(iter_vec, collapse = ' | ')
    }

Это дает:


[1] "Apple"   "Apple | Intel"   "Apple | Intel | Microsoft"   "Intel"   "Intel | Amazon"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...