R: Как использовать RegEx для поиска нескольких слов с помощью дизъюнкции - PullRequest
0 голосов
/ 23 декабря 2018

Позвольте мне объяснить, что я хочу сделать.У меня есть сводные данные (15 млн. Слов) о политической дискуссии, и я хочу найти совпадение двух терминов, скажем, в 10 тыс. Слов.

Я создаю два вектора позиций двух терминов: "false "и" law ".

false.v <- c(133844, 133880, 145106, 150995, 152516, 152557, 153697, 155507)   
law.v <- c(48064, 155644, 251315, 297303, 323417, 349576, 368052, 543487)

Затем я хочу собрать их в матрицу, чтобы увидеть совпадение, используя функцию" external ".Позиции взяты из одного и того же корпуса, поэтому я создаю матрицу различий:

distances <- outer(false.v, law.v, "-")

Чтобы упростить чтение, назовите их:

rownames(distances) <- paste0("False", false.v)  
colnames(distances) <- paste0("Law", law.v)

Хорошо, таку нас есть готовая матрица.Чтобы выяснить, какие пары позиций находились в пределах 10000 слов друг от друга, я просто набрал:

abs(distances) <= 10000

Поэтому я должен определить те моменты в политических дебатах, где эти случаи встречаются чаще.Здесь возникает проблема.Я должен сделать это более чем с парой слов (фактически с 5 парами слов или около того), поэтому было бы здорово, если бы я мог просто искать несколько слов вместо двух пар слов одновременно.Таким образом, вместо поиска «ложь» и «закон», ищите «ложь ИЛИ ложь ИЛИ что угодно» и «закон ИЛИ деньги ИЛИ все что угодно».Я полагаю, я должен использовать RegEx для этой задачи, не так ли?Я просто попробовал все, и ничего не получилось.

Пример, который я только что привел, является упрощением.Команда, которую я использую для поиска слов, создает вектор из корпуса:

positions.law.v <- which(C1.corpus.v == "law")

Так было бы здорово, если бы я мог просто использовать что-то вроде

which(C1.corpus.v == "law OR money OR prison OR ...")

which(C1.corpus.v == "false OR lie OR country OR ...")

Это все равно что сказать R«Эй, дайте мне позиции совместного вхождения любой возможной комбинации между первым рядом слов (закон или деньги или тюрьма ...) и вторым (ложь или ложь или страна ...). Я надеюсь, что яобъясняя это ясно. Извините за языковые ошибки. Спасибо !!

Ответы [ 3 ]

0 голосов
/ 23 декабря 2018
library(dplyr)

У меня также есть расширенный ответ, но он может быть таким простым:

mywords = c("law", "money", "prison", "false", "lie", "country")

which(C1.corpus.v %in% mywords)
0 голосов
/ 23 декабря 2018

Я думаю, что ваша проблема немного сложнее, чем использование регулярных выражений.Например, вы можете включить law, legal и legislation в одну группу, но не включайте lawless.Регулярное выражение типа \blaw.*\b не сильно вам поможет.По сути, вас интересует:

  • Создание матрицы совпадений объектов
  • Включение семантической близости слов

Матрица совпадений объектов

Это устоявшаяся задача, и я рекомендую вам использовать проверенное решение, например, функцию fcm.Чтобы представить пример из документации:

txt <- "A D A C E A D F E B A C E D"
fcm(txt, context = "window", window = 2)
fcm(txt, context = "window", count = "weighted", window = 3)
fcm(txt, context = "window", count = "weighted", window = 3, 
             weights = c(3, 2, 1), ordered = TRUE, tri = FALSE)

Ваше регулярное выражение

Чтобы предложить решение вашей конкретной проблемы.Это:

which(C1.corpus.v == "law OR money OR prison OR ...")

, где

C1.corpus.v <- c("law", "word", "something","legal", "stuff")

вы можете сделать

grep(
    pattern = paste("legal", "law", "som.*", sep = "|"),
    x = C1.corpus.v,
    perl = TRUE,
    value = FALSE
)

, где sep = "|" служит вашим ...OR....ИМХО, это не то, что вы хотите, так как не учитывает семантического сходства.Я бы посоветовал вам взглянуть на некоторые из хороших учебников, которые доступны в сети 1,2 .


1 Тейлор Арнольд и Лорен Тилтон Базовая обработка текста в R 2 Islam, Aminul & Inkpen, Diana.(2008). Семантическое подобие текста с использованием основанного на корпусе сходства слов и сходства строк .TKDD.2. 10.1145 / 1376815.1376819.

0 голосов
/ 23 декабря 2018

Попробуйте:

library(quanteda)

Я буду использовать предвыборные манифесты 9 политических партий Великобритании 2010 года:

data_char_ukimmig2010

Создать объект токенов (существует множество настроек - проверьтеout https://quanteda.io/)

mytoks <- data_char_ukimmig2010 %>%
  char_tolower() %>%
  tokens()

mywords = c("law", "money", "prison", "false", "lie", "country")

kwic "return [s] список ключевых слов, предоставленных пользователем в его непосредственном контексте, с указанием исходного текста и порядкового номера слова в исходном тексте" source

mykwic <- kwic(mytoks, mywords)

A kwic создает фрейм данных с различными функциями, одним из которых является начальная позиция целочисленного значения ваших ключевых слов (потому что вы можете использовать его для поиска фраз):

mykwic$from

Дает нам:

> mykwic$from
 [1]  130  438  943 1259 1281 1305 1339 1356 1743 1836 1859 2126 2187 2443 2546 2640 2763 2952 3186 3270  179    8  201
[24]  343  354  391  498   16  131  552   14   29  388   80  306  487  507
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...