Построить символьный вектор из нескольких словосочетаний с помощью регулярных выражений для построения DFM с использованием Quanteda в R - PullRequest
0 голосов
/ 20 мая 2018

Я с большим удовлетворением привык к работе с texttat_collocation () от quanteda для извлечения MWE.Сейчас я пытаюсь извлечь все совпадения, которые соответствуют определенному шаблону, независимо от их частоты.

Моя цель - создать вектор символов, извлекая имена умений из dfm (), созданного с помощью шаблона регулярных выражений.Затем я буду использовать этот символьный вектор в аргументе "select" для построения dfm.Я мог бы также захотеть использовать этот символьный вектор для добавления в словарь, который я использую в качестве онтологии для построения dfms на более поздних стадиях конвейера.

Шаблон: «возрасте xx-xx», где x - это цифра.

Я использовал шаблон регулярного выражения "age \ s ([0-9] {2} - [0-9] {2})" здесь и получил желаемые совпадения.Но когда я пробую это в R (добавив дополнительный "\" перед "\ s"), я не получаю никаких совпадений.

Когда я делаю:

txt <- c("In India, male smokers aged 20-45 perceive brandX positively.",
              "In Spain, female buyers aged 30-39 don't purchase brandY.")
ageGroups <- dfm(txt, select = "aged\\s([0-9]{2}-[0-9]{2})", valuetype = "regex")
featnames(ageGroups)

Я получаю:

character(0)

Однако, когда я пытаюсь:

ageGroups <- dfm(txt, select = "([0-9]{2}-[0-9]{2})", valuetype = "regex")
featnames(ageGroups)

Я получаю:

[1] "20-45" "30-39"

Кажется, я не могу захватить пустое пространство в регулярном выражении.Я рассмотрел много подобных вопросов в SO, возможно, , это , является наиболее актуальным, но я все еще не могу выполнить мою конкретную задачу.

Я также пытался:

tokens <- tokens(txt, remove_punct = FALSE, remove_numbers = FALSE, remove_symbols = FALSE)
tokensCompunded <- tokens_compound(tokens, pattern =  "aged\\s([0-9]{2}-[0-9]{2})", valuetype = "regex")
attr(tokensCompunded, "types")

Но я получаю все токены обратно:

[1] "In"         " "          "India"      ","          "male"       "smokers"    "aged"       "20-45"      "perceive"  
[10] "brandX"     "positively" "."          "Spain"      "female"     "buyers"     "30-39"      "don't"      "purchase"  
[19] "brandY" 

Я думаю, что может быть несколько других более эффективных подходов для извлечения векторов символов с использованием regex (или glob) с помощью quanteda, и я 'Я счастлив узнать новые способы использования этого удивительного пакета R.

Спасибо за вашу помощь!

Изменить на оригинальный вопрос:

Этот другой вопрос в SO имеетаналогичное требование, то есть обнаружение многословных фраз с использованием объектов kwic, и может быть дополнительно расширено для достижения целей, указанных выше, со следующим дополнением:

kwicObject <- kwic(corpus, pattern = phrase("aged ([0-9]{2}-[0-9]{2})"), valuetype = "regex")
unique(kwicObject$keyword)

Ответы [ 2 ]

0 голосов
/ 20 мая 2018

Проблема здесь в том, что целевой текст и мультислово pattern (которое содержит пробел) не размечаются одинаково.В вашем примере вы применили регулярное выражение для нескольких токенов (который включает разделитель пробелов), но цель для поиска уже была разбита на отдельные токены.

Мы разработали решение этой проблемы, функцию под названием phrase().Начиная с ?pattern:

Пробел не является привилегированным, поэтому в векторе символов пробел интерпретируется буквально.Если вы хотите рассматривать элементы, разделенные пробелами, как последовательности токенов, оберните аргумент в phrase().

Так что в этом случае:

pat <- "aged [0-9]{2}-[0-9]{2}"

toks2 <- tokens_select(toks, pattern = phrase(pat), valuetype = "regex")
toks2
# tokens from 2 documents.
# text1 :
# [1] "aged"  "20-45"
# 
# text2 :
# [1] "aged"  "30-39"

Здесь мы видим, чтовыбор сработал, потому что оболочка phrase() преобразовала шаблон в последовательность совпадений.

Если вы хотите сделать из них один токен, вы можете отправить тот же аргумент pattern на tokens_compound():

toks3 <- tokens_compound(toks2, pattern = phrase(pat), 
                         valuetype = "regex", concatenator = " ")
toks3
# tokens from 2 documents.
# text1 :
# [1] "aged 20-45"
# 
# text2 :
# [1] "aged 30-39"

Наконец, вы можете использовать это для построения dfm, где каждое совпадение из нескольких слов является функцией.Это не может работать, если вы сначала не выполнили объединение на этапе токенов, поскольку по определению dfm не имеет порядка в своих функциях.

dfm(toks3)
# Document-feature matrix of: 2 documents, 2 features (50% sparse).
# 2 x 2 sparse Matrix of class "dfm"
#        features
# docs    aged 20-45 aged 30-39
#   text1          1          0
#   text2          0          1
0 голосов
/ 20 мая 2018

Вы можете изменить шаблон регулярного выражения:

select = "aged.*([0-9]{2}-[0-9]{2})"
...