Вы можете сформировать все нграммы от 1 до 5, а затем выбрать все из. Но для больших текстов это было бы очень неэффективно. Вот более прямой путь. Я воспроизвел всю проблему здесь с помощью нескольких модификаций (например, stringsAsFactors = FALSE
и пропуская некоторые ненужные шаги).
Конечно, это не в два раза учитывает термины, как в ожидаемом вами примере, но я утверждаю, что Вы, вероятно, не хотели этого. Зачем считать «мозг», если он произошел внутри «опухоли мозга»? Вы бы лучше считали «опухоль головного мозга», когда она встречается как эта фраза, и «мозг» только тогда, когда это происходит без «опухоли». Приведенный ниже код делает это.
library(quanteda)
## Package version: 2.0.1
raw <- data.frame(
"doc_id" = c("1", "2", "3"),
"text" = c(
"diffuse intrinsic pontine glioma are highly aggressive and difficult to treat brain tumors found at the base of the brain.",
"magnetic resonance imaging (mri) is a medical imaging technique used in radiology to form pictures of the anatomy and the physiological processes of the body.",
"radiation therapy or radiotherapy, often abbreviated rt, rtx, or xrt, is a therapy using ionizing radiation, generally as part of cancer treatment to control or kill malignant cells and normally delivered by a linear accelerator."
),
stringsAsFactors = FALSE
)
dict <- dictionary(list(
term = c(
"diffuse intrinsic pontine glioma",
"brain tumors", "brain", "pontine glioma", "mri", "medical imaging",
"radiology", "anatomy", "physiological processes", "radiation therapy",
"radiotherapy", "cancer treatment", "malignant cells"
)
))
Вот ключ к ответу: сначала используйте словарь, чтобы выбрать токены, затем объединить их, а затем изменить их по одному совпадению словаря для каждого нового «документа». На последнем шаге создается нужный вам фрейм данных.
toks <- corpus(raw) %>%
tokens() %>%
tokens_select(dict) %>% # select just dictionary values
tokens_compound(dict, concatenator = " ") %>% # turn phrase into single "tokens"
tokens_segment(pattern = "*") # make one token per "document"
# make into data.frame
data.frame(
doc_id = docid(toks), term = as.character(toks),
stringsAsFactors = FALSE
)
## doc_id term
## 1 1 diffuse intrinsic pontine glioma
## 2 1 brain tumors
## 3 1 brain
## 4 2 mri
## 5 2 medical imaging
## 6 2 radiology
## 7 2 anatomy
## 8 2 physiological processes
## 9 3 radiation therapy
## 10 3 radiotherapy
## 11 3 cancer treatment
## 12 3 malignant cells