2013-04-19 4 views
2

Я хочу text-mine набор файлов на основе формы ниже. Я могу создать корпус, где каждый файл является документом (с использованием), но я думаю, что было бы лучше создать корпус, где каждый раздел в таблице 2-й формы был документом, имеющим следующие метаданные:извлечение полуструктурированного текста из документов Word

Author  : John Smith 
    DateTimeStamp: 2013-04-18 16:53:31 
    Description : 
    Heading  : Current Focus 
    ID   : Smith-John_e.doc Current Focus 
    Language  : en_CA 
    Origin  : Smith-John_e.doc 
    Name   : John Smith 
    Title  : Manager 
    TeamMembers : Joe Blow, John Doe 
    GroupLeader : She who must be obeyed 

где Имя, Название, Члены Команды и GroupLeader извлекаются из первой таблицы в форме. Таким образом, каждый фрагмент текста, который будет анализироваться, будет поддерживать некоторый контекст.

Каков наилучший способ приблизиться к этому? Я могу думать о 2 способах:

  • как-нибудь разобрать тело, которое у меня есть в детских корпусах.
  • каким-то образом проанализируйте документ в подзаголовках и сделайте из них корпус.

Любые указатели будут очень признательны.

Это форма: HR form

Here is an RData file из корпуса с 2-х документов. exc [[1]] пришел из .doc и exc [[2]] из docx. Они оба использовали форму выше.

+0

Можете ли вы добавить вывод 'dput (mycorpus)' или подмножества к вашему вопросу? – Ben

+0

@Ben: данные, к сожалению, конфиденциальны. Но форма преобразуется в текст перед чтением в корпус. Если бы поддельные данные были бы полезны, я мог бы опубликовать их в понедельник. – dnagirl

+1

Ваш вопрос получит больше «укусов» с небольшим масштабом, самосохраняемым воспроизводимым примером вашей проблемы. – Ben

ответ

2

Вот быстрый набросок метода, мы надеемся, это может спровоцировать кого-то более талантлив, чтобы остановить и предложить что-то более эффективное и надежное ... Используя RData файл в вашем вопросе, я обнаружил, что doc и docx файлы имеют немного разные структуры и поэтому требуют немного разных подходов (хотя я вижу в метаданных, что ваш docx является «fake2.txt», так ли это действительно docx? Я вижу в вашем другом Q, что вы использовали конвертер вне R, это должно быть поэтому это txt).

library(tm) 

Сначала получите дополнительные метаданные для файла doc. Я не эксперт регулярных выражений, как вы можете видеть, но это грубо «избавиться от задних и ведущих пробелов», затем «избавиться от„Слов“», а затем избавиться от знаков препинания ...

# create User-defined local meta data pairs 
meta(exc[[1]], type = "corpus", tag = "Name1") <- gsub("^\\s+|\\s+$","", gsub("Name", "", gsub("[[:punct:]]", '', exc[[1]][3]))) 
meta(exc[[1]], type = "corpus", tag = "Title") <- gsub("^\\s+|\\s+$","", gsub("Title", "", gsub("[[:punct:]]", '', exc[[1]][4]))) 
meta(exc[[1]], type = "corpus", tag = "TeamMembers") <- gsub("^\\s+|\\s+$","", gsub("Team Members", "", gsub("[[:punct:]]", '', exc[[1]][5]))) 
meta(exc[[1]], type = "corpus", tag = "ManagerName") <- gsub("^\\s+|\\s+$","", gsub("Name of your", "", gsub("[[:punct:]]", '', exc[[1]][7]))) 

сейчас посмотрим на результат

# inspect 
    meta(exc[[1]], type = "corpus") 
Available meta data pairs are: 
    Author  : 
    DateTimeStamp: 2013-04-22 13:59:28 
    Description : 
    Heading  : 
    ID   : fake1.doc 
    Language  : en_CA 
    Origin  : 
User-defined local meta data pairs are: 
$Name1 
[1] "John Doe" 

$Title 
[1] "Manager" 

$TeamMembers 
[1] "Elise Patton Jeffrey Barnabas" 

$ManagerName 
[1] "Selma Furtgenstein" 

сделать то же самое для docx файла

# create User-defined local meta data pairs 
meta(exc[[2]], type = "corpus", tag = "Name2") <- gsub("^\\s+|\\s+$","", gsub("Name", "", gsub("[[:punct:]]", '', exc[[2]][2]))) 
meta(exc[[2]], type = "corpus", tag = "Title") <- gsub("^\\s+|\\s+$","", gsub("Title", "", gsub("[[:punct:]]", '', exc[[2]][4]))) 
meta(exc[[2]], type = "corpus", tag = "TeamMembers") <- gsub("^\\s+|\\s+$","", gsub("Team Members", "", gsub("[[:punct:]]", '', exc[[2]][6]))) 
meta(exc[[2]], type = "corpus", tag = "ManagerName") <- gsub("^\\s+|\\s+$","", gsub("Name of your", "", gsub("[[:punct:]]", '', exc[[2]][8]))) 

И посмотрите

# inspect 
meta(exc[[2]], type = "corpus") 
Available meta data pairs are: 
    Author  : 
    DateTimeStamp: 2013-04-22 14:06:10 
    Description : 
    Heading  : 
    ID   : fake2.txt 
    Language  : en 
    Origin  : 
User-defined local meta data pairs are: 
$Name2 
[1] "Joe Blow" 

$Title 
[1] "Shift Lead" 

$TeamMembers 
[1] "Melanie Baumgartner Toby Morrison" 

$ManagerName 
[1] "Selma Furtgenstein" 

Если у вас есть большое количество документов, то функция lapply, которая включает в себя эти функции meta, будет способом.

Теперь, когда мы получили пользовательские метаданные, мы можем подмножество документов, чтобы исключить ту часть текста:

# create new corpus that excludes part of doc that is now in metadata. We just use square bracket indexing to subset the lines that are the second table of the forms (slightly different for each doc type) 
excBody <- Corpus(VectorSource(c(paste(exc[[1]][13:length(exc[[1]])], collapse = ","), 
         paste(exc[[2]][9:length(exc[[2]])], collapse = ",")))) 
# get rid of all the white spaces 
excBody <- tm_map(excBody, stripWhitespace) 

взглянуть:

inspect(excBody) 
A corpus with 2 text documents 

The metadata consists of 2 tag-value pairs and a data frame 
Available tags are: 
    create_date creator 
Available variables in the data frame are: 
    MetaID 

[[1]] 
|CURRENT RESEARCH FOCUS |,| |,|Lorem ipsum dolor sit amet, consectetur adipiscing elit. |,|Donec at ipsum est, vel ullamcorper enim. |,|In vel dui massa, eget egestas libero. |,|Phasellus facilisis cursus nisi, gravida convallis velit ornare a. |,|MAIN AREAS OF EXPERTISE |,|Vestibulum aliquet faucibus tortor, sed aliquet purus elementum vel. |,|In sit amet ante non turpis elementum porttitor. |,|TECHNOLOGY PLATFORMS, INSTRUMENTATION EMPLOYED |,| Vestibulum sed turpis id nulla eleifend fermentum. |,|Nunc sit amet elit eu neque tincidunt aliquet eu at risus. |,|Cras tempor ipsum justo, ut blandit lacus. |,|INDUSTRY PARTNERS (WITHIN THE PAST FIVE YEARS) |,| Pellentesque facilisis nisl in libero scelerisque mattis eu quis odio. |,|Etiam a justo vel sapien rhoncus interdum. |,|ANTICIPATED PARTICIPATION IN PROGRAMS, EITHER APPROVED OR UNDER DEVELOPMENT |,|(Please include anticipated percentages of your time.) |,| Proin vitae ligula quis enim vulputate sagittis vitae ut ante. |,|ADDITIONAL ROLES, DISTINCTIONS, ACADEMIC QUALIFICATIONS AND NOTES |,|e.g., First Aid Responder, Other languages spoken, Degrees, Charitable Campaign |,|Canvasser (GCWCC), OSH representative, Social Committee |,|Sed nec tellus nec massa accumsan faucibus non imperdiet nibh. |,, 

[[2]] 
CURRENT RESEARCH FOCUS,,* Lorem ipsum dolor sit amet, consectetur adipiscing elit.,* Donec at ipsum est, vel ullamcorper enim.,* In vel dui massa, eget egestas libero.,* Phasellus facilisis cursus nisi, gravida convallis velit ornare a.,MAIN AREAS OF EXPERTISE,* Vestibulum aliquet faucibus tortor, sed aliquet purus elementum vel.,* In sit amet ante non turpis elementum porttitor. ,TECHNOLOGY PLATFORMS, INSTRUMENTATION EMPLOYED,* Vestibulum sed turpis id nulla eleifend fermentum.,* Nunc sit amet elit eu neque tincidunt aliquet eu at risus.,* Cras tempor ipsum justo, ut blandit lacus.,INDUSTRY PARTNERS (WITHIN THE PAST FIVE YEARS),* Pellentesque facilisis nisl in libero scelerisque mattis eu quis odio.,* Etiam a justo vel sapien rhoncus interdum.,ANTICIPATED PARTICIPATION IN PROGRAMS, EITHER APPROVED OR UNDER DEVELOPMENT ,(Please include anticipated percentages of your time.),* Proin vitae ligula quis enim vulputate sagittis vitae ut ante.,ADDITIONAL ROLES, DISTINCTIONS, ACADEMIC QUALIFICATIONS AND NOTES,e.g., First Aid Responder, Other languages spoken, Degrees, Charitable Campaign Canvasser (GCWCC), OSH representative, Social Committee,* Sed nec tellus nec massa accumsan faucibus non imperdiet nibh.,, 

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

Конечно, все это зависит от того, насколько документы очень регулярны. Если в каждой таблице в каждом документе есть разные числа строк, тогда простой метод индексирования может оказаться неудачным (попробуйте и посмотрите, что произойдет), и вам понадобится нечто более надежное.

UPDATE: более надежный метод

Имея немного более внимательно прочитать вопрос, и got a bit more education about regex, вот метод, который является более надежным и не зависит от индексации конкретных строк документов. Вместо этого мы используем регулярные выражения для извлечения текста из между двумя словами, чтобы сделать метаданные и разделить документ

Вот как мы делаем локальные данные мета определяемые пользователем (метод замены выше одного)

library(gdata) # for the trim function 
txt <- paste0(as.character(exc[[1]]), collapse = ",") 

# inspect the document to identify the words on either side of the string 
# we want, so 'Name' and 'Title' are on either side of 'John Doe' 
extract <- regmatches(txt, gregexpr("(?<=Name).*?(?=Title)", txt, perl=TRUE)) 
meta(exc[[1]], type = "corpus", tag = "Name1") <- trim(gsub("[[:punct:]]", "", extract)) 

extract <- regmatches(txt, gregexpr("(?<=Title).*?(?=Team)", txt, perl=TRUE)) 
meta(exc[[1]], type = "corpus", tag = "Title") <- trim(gsub("[[:punct:]]","", extract)) 

extract <- regmatches(txt, gregexpr("(?<=Members).*?(?=Supervised)", txt, perl=TRUE)) 
meta(exc[[1]], type = "corpus", tag = "TeamMembers") <- trim(gsub("[[:punct:]]","", extract)) 

extract <- regmatches(txt, gregexpr("(?<=your).*?(?=Supervisor)", txt, perl=TRUE)) 
meta(exc[[1]], type = "corpus", tag = "ManagerName") <- trim(gsub("[[:punct:]]","", extract)) 

# inspect 
meta(exc[[1]], type = "corpus") 

Available meta data pairs are: 
    Author  : 
    DateTimeStamp: 2013-04-22 13:59:28 
    Description : 
    Heading  : 
    ID   : fake1.doc 
    Language  : en_CA 
    Origin  : 
User-defined local meta data pairs are: 
$Name1 
[1] "John Doe" 

$Title 
[1] "Manager" 

$TeamMembers 
[1] "Elise Patton Jeffrey Barnabas" 

$ManagerName 
[1] "Selma Furtgenstein" 

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

txt <- paste0(as.character(exc[[1]]), collapse = ",") 
CURRENT_RESEARCH_FOCUS <- trim(gsub("[[:punct:]]","", regmatches(txt, gregexpr("(?<=CURRENT RESEARCH FOCUS).*?(?=MAIN AREAS OF EXPERTISE)", txt, perl=TRUE)))) 
[1] "Lorem ipsum dolor sit amet consectetur adipiscing elit        Donec at ipsum est vel ullamcorper enim           In vel dui massa eget egestas libero            Phasellus facilisis cursus nisi gravida convallis velit ornare a" 


MAIN_AREAS_OF_EXPERTISE <- trim(gsub("[[:punct:]]","", regmatches(txt, gregexpr("(?<=MAIN AREAS OF EXPERTISE).*?(?=TECHNOLOGY PLATFORMS, INSTRUMENTATION EMPLOYED)", txt, perl=TRUE)))) 
    [1] "Vestibulum aliquet faucibus tortor sed aliquet purus elementum vel     In sit amet ante non turpis elementum porttitor" 

И так далее. Надеюсь, это немного ближе к тому, что вам нужно. Если нет, лучше всего разбить задачу на множество более мелких, более сфокусированных вопросов и спросить их отдельно (или дождаться, когда один из гуру остановится по этому вопросу!).

+0

Я сделал обновление, я думаю, что я немного приближаюсь к тому, что вам нужно ... – Ben

+0

выглядит так, чтобы сделать это с любой эффективностью, мне нужно будет обрабатывать файлы .doc и .docx отдельно , иначе регулярные выражения должны быть OR'd. Затем, как только все будет в одном формате, я смогу объединить корпуса. Попробуйте это сейчас. – dnagirl

+0

Если вы просто используете мой «более надежный метод», вы должны иметь возможность делать «doc» и «docx» вместе. Любопытно узнать, как проходят ваши испытания ... – Ben

Смежные вопросы