Сопоставление строк с очень большим файлом в R

У меня есть очень большой файл статей RDS (13 ГБ). Размер фрейма данных в глобальной среде R составляет ~ 6 ГБ.

Каждая статья имеет идентификатор, дату, основной текст с тегами POS, шаблон, который представляет собой не что иное, как два или три слова с их тегом POS. и некоторые другие метаданные.

structure(list(an = c("1", "2", "3", "4", "5"), pub_date = structure(c(11166, 8906, 12243, 4263, 13077), class = "Date"), 
source_code = c("1", "2", "2", "3", "2"), word_count = c(99L, 
97L, 30L, 68L, 44L), POStagged = c("the_DT investment_NN firm_NN lehman_NN brothers_NNS holdings_NNS said_VBD yesterday_NN that_IN it_PRP would_MD begin_VB processing_VBG its_PRP$ own_JJ stock_NN trades_NNS by_IN early_RB next_JJ year_NN and_CC end_VB its_PRP$ existing_VBG tradeclearing_NN contract_NN with_IN the_DT bear_NN stearns_VBZ companies_NNS lehman_NN which_WDT is_VBZ the_DT last_JJ big_JJ securities_NNS firm_NN to_TO farm_VB out_RP its_PRP$ stock_NN trade_NN processing_NN said_VBD it_PRP would_MD save_VB million_CD to_TO million_CD annually_RB by_IN clearing_VBG its_PRP$ own_JJ trades_NNS a_DT bear_NN stearns_VBZ spokesman_NN said_VBD lehmans_NNS business_NN contributed_VBD less_JJR than_IN percent_NN to_TO bear_VB stearnss_NN clearing_NN operations_NNS", 
"six_CD days_NNS after_IN she_PRP was_VBD introduced_VBN as_IN womens_NNS basketball_NN coach_NN at_IN wisconsin_NN with_IN a_DT fouryear_JJ contract_NN nell_NN fortner_NN resigned_VBD saying_VBG she_PRP wants_VBZ to_TO return_VB to_TO louisiana_JJR tech_NN as_IN an_DT assistant_NN im_NN shocked_VBN said_VBD associate_JJ athletic_JJ director_NN cheryl_NN marra_NN east_JJ carolina_NN came_VBD from_IN behind_IN with_IN two_CD runs_NNS in_IN the_DT seventh_JJ inning_NN and_CC defeated_VBD george_NN mason_NN in_IN the_DT colonial_JJ athletic_JJ association_NN baseball_NN tournament_NN in_IN norfolk_NN johnny_NN beck_NN went_VBD the_DT distance_NN for_IN the_DT pirates_NNS boosting_VBG his_PRP$ record_NN to_TO the_DT patriots_NNS season_NN closed_VBD at_IN", 
"tomorrow_NN clouds_NNS and_CC sun_NN high_JJ low_JJ", "the_DT diversity_NN of_IN the_DT chicago_NN financial_JJ future_NN markets_NNS the_DT chicagoans_NNS say_VBP also_RB enhances_VBG their_PRP$ strength_NN traders_NNS and_CC arbitragers_NNS can_MD exploit_VB price_NN anomalies_NNS for_IN example_NN between_IN cd_NN and_CC treasurybill_NN futures_NNS still_RB nyfe_JJ supporters_NNS say_VBP their_PRP$ head_NN start_VB in_IN cd_NN futures_NNS and_CC technical_JJ advantages_NNS in_IN the_DT contract_NN traded_VBN on_IN the_DT nyfe_NN mean_VBP that_IN the_DT chicago_NN exchanges_NNS will_MD continue_VB to_TO play_VB catchup_NN", 
"williams_NNS industries_NNS inc_IN the_DT manufacturing_NN and_CC construction_NN company_NN provides_VBZ steel_NN products_NNS to_TO build_VB major_JJ infrastructure_NN it_PRP has_VBZ been_VBN involved_VBN with_IN area_NN landmark_NN projects_NNS including_VBG rfk_JJ stadium_NN left_VBD the_DT woodrow_JJ wilson_NN bridge_NN and_CC the_DT mixing_NN bowl_NN"
), phrases = c("begin processing", "wants to return", "high", 
"head start in", "major"), repeatPhraseCount = c(1L, 1L, 
1L, 1L, 1L), pattern = c("begin_V", "turn_V", "high_JJ", 
"start_V", "major_JJ"), code = c(NA_character_, NA_character_, 
NA_character_, NA_character_, NA_character_), match = c(TRUE, 
TRUE, TRUE, TRUE, TRUE)), .Names = c("an", "pub_date", "source_code", "word_count", "POStagged", "phrases", "repeatPhraseCount", "pattern", 
"code", "match"), row.names = c("4864065", "827626", "6281115", 
"281713", "3857705"), class = "data.frame")

Моя цель - обнаружить (для каждой строки) наличие шаблона в POStagged.

Столбец шаблонов - это фиксированный список, который я составил лично. В списке 465 слов / словосочетаний с их точками продажи.

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

Однако в некоторых случаях вместо слов у меня есть фразы, в которых конец фразы может быть изменяющимся шаблоном. Например, фраза «может быть не в состоянии заключить сделку», где «иметь возможность заключить сделку» может быть любой глагольной фразой (например, иметь возможность заключить сделку). Мои попытки были разными, и я не уверен, что поступаю правильно:

--might_MD not_RB _VP (this works and picks up ***might not*** but is clearly wrong since the verb phrase after it is not picked)

Если я использую fixed () и просто тогда, str_detect работает, и выполнение выполняется очень быстро. Однако fixed () в некоторых случаях (как описано выше) наверняка не хватает, и я не могу точно сравнить результаты. Вот пример:

str_detect("might_MD not_RB be able to make the deal", "might_MD not_RB [A-Za-z]+(?:\\s+[A-Za-z]+){0,6}")
TRUE

str_detect("might_MD not_RB be able to make the deal", fixed("might_MD not_RB [A-Za-z]+(?:\\s+[A-Za-z]+){0,6}"))
FALSE

https://stackoverflow.com/a/51406046/3290154

Мой желаемый результат - это дополнительный столбец в моем фрейме данных с результатом ИСТИНА / ЛОЖЬ, сообщающий мне, виден ли шаблон в POStagged или нет.

## Attempt 1 - R fatally crashes
## this works in a smaller sample but bombs R in a large dataframe
df$match <- str_detect(df$POStagged, df$pattern)

## Attempt 2
## This bombs (using multidplyr and skipping some lines of code)
partition(source_code, cluster=cl) %>%
    mutate(match=str_detect(POStagged, pattern)) %>%
    filter(!(match==FALSE)) %>%
    filter(!is.na(match)) %>%
    collect()

##I get this error: Error in serialize(data, node$con) : error writing to connection

Насколько я понимаю, это связано с ограничениями в том, как multidplyr обрабатывает память и как загружает данные в память (https://github.com/hadley/multidplyr/blob/master/vignettes/multidplyr.md). Однако, поскольку multidplyr использует параллельный пакет, и если я экстраполирую здесь, я все равно буду в порядке - если я разделю, скажем, свои данные на 5 копий, тогда 6 * 5 = 30 ГБ плюс любые пакеты и так далее.

## Attempt 3 - I tried to save the RDS to a csv/txt file and use the chuncked package, however, the resulting csv/txt was over 100GB.

## Attempt 4 - I tried to run a for loop, but I estimate it will take ~12days to run

Я немного прочитал о жадности регулярных выражений и поэтому попытался изменить свой столбец шаблона (сделать мое регулярное выражение ленивым), добавив? +. Однако переход по этому маршруту означает, что я не могу использовать fixed (), поскольку все мои совпадения ложны. Любая помощь в правильном направлении приветствуется!

https://stringr.tidyverse.org/articles/regular-expressions.html

Что означают слова «ленивый» и «жадный» в контексте регулярных выражений?

Я пытаюсь понять вашу цель на основе вашего кода, но не уверен, что понимаю. Не могли бы вы выразить это словами? Похоже, вы пытаетесь обнаружить и пометить все строки вашего фрейма данных, где (некоторые? Все?) Строки, разделенные пробелами в столбце pattern, встречаются в столбце POStagged. Это верно? И вы используете str_detect ... потому что думаете, что он будет быстрее, чем grepl? Также будет полезно, если вы поделитесь несколькими строками данных (скажем, 5-10) с желаемыми результатами. Не видя этого, очень сложно понять, является ли fixed() жизнеспособным вариантом.

Gregor Thomas 25.09.2018 15:42

И почему вы используете lapply внутри preprocess, когда кажется, что вы вводите только строковый столбец? Я не уверен, на чем вы его запускаете, потому что вы запускаете его на df$variable, но ваши образцы данных не содержат столбца с именем variable ... df$variable - это столбец списка? В противном случае lapply кажется огромной неэффективностью. Когда вы делитесь дополнительными примерами данных, делайте это так, чтобы классы столбцов были ясными - dput() лучше всего подходит для этого, поскольку он дает копируемую / вставляемую версию точной структуры данных.

Gregor Thomas 25.09.2018 15:48

Спасибо @Gregor - я добавил дополнительную информацию

Cola4ever 27.09.2018 15:59

Новый пример очень помогает. Остаются некоторые вопросы: (1) Я не знаю, что вы имеете в виду под "Мне не нужно точное совпадение, поэтому, например, я хотел бы определить" вероятно ", а также" очень вероятно ". Ни слова «вероятно», ни «очень вероятно» не появляются в ваших данных - это должен быть пример строк для сопоставления, или вы не уверены в том, насколько вероятно совпадение на самом деле? Насколько близким должно быть совпадение? Можете ли вы привести примеры неточных совпадений, которые вам все же хотелось бы уловить?

Gregor Thomas 27.09.2018 17:15

(2) Первые три шаблона в вашем примере кажутся отдельными терминами (я так думаю?), Но четвертый шаблон - "the_DT _JJS NP". Вам нужно найти этот термин полностью, или вы ищете, скажите все "the_DT`, _JJS и NP где угодно, но не обязательно последовательно? данные делают?)

Gregor Thomas 27.09.2018 17:20

(3) Насколько я могу судить, шаблоны в ваших данных выборки не встречаются в столбце POStagged, поэтому правильный результат - FALSE. Не могли бы вы отредактировать данные примера так, чтобы некоторые результаты были верными, или объяснить, почему я ошибаюсь в отношении всех ложных результатов?

Gregor Thomas 27.09.2018 17:26

С того места, где мы сейчас находимся, мы видим, что str_detect - хороший выбор, потому что вам нужно что-то векторизованное как по строке, так и по шаблону, а grepl векторизуется только по строке. Однако любые шаблоны регулярных выражений для таких больших данных могут быть довольно медленными. Как только мы получим более четкое представление о вашей проблеме, самым простым способом ускорить процесс будет отредактировать ваши данные, чтобы мы могли использовать фиксированные шаблоны вместо регулярного выражения (если это возможно). Но мне нужно, чтобы вы были более конкретными, прежде чем я смогу сказать, возможно ли это.

Gregor Thomas 27.09.2018 17:36

Наконец, ни один из ваших шаблонов (по крайней мере, в данных, которыми вы поделились) не имеет таких квантификаторов, как ?, *, +, поэтому бит о ленивых и жадных квантификаторах кажется совершенно неуместным. Добавление квантификаторов (если они не нужны) просто замедлит работу. Я бы предложил отредактировать его, исключив из вашего вопроса, чтобы немного очистить ситуацию. (Или, если вам нужны квантификаторы, покажите, почему / где.)

Gregor Thomas 27.09.2018 17:39

Спасибо @Gregor - я скоро обновлю вопрос и примеры и проясню вопрос о квантификаторах - я сделал некоторые обновления со вчерашнего дня.

Cola4ever 27.09.2018 17:44

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

Gregor Thomas 27.09.2018 18:00
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
10
692
1

Ответы 1

Возможно, вы сможете добиться большего прогресса и получить лучшие результаты, если будете использовать Открытый исходный код BERT: современная предварительная подготовка для обработки естественного языка вместо этого? Это совершенно другой подход, конечно, я знаю, извините. Так что на случай, если вы по какой-то причине не в курсе.

Другие вопросы по теме