2013-05-30 2 views
1

Я хотел бы добавить вывод в части правового речи Tagger в существующий файл XML с POS-тегов как пары значений атрибутов в существующий текстовый элемент:Добавить POS-теги в качестве атрибута элемента XML

house/N + <w>house</w> --> <w pos="N">house</w> 

Я думал, что я мог бы дать уникальные идентификаторы слова, совпадают, а затем добавить POS-тег в существующий файл XML, поэтому я разработал следующую функцию в Python:

import xml.etree.ElementTree as ET 

def add_postags(POSfile, xmlfile): 
    """ 
    Function that takes two arguments (POSfile, xmlfile). 
    If the value of the word <w>'s attribute 'id' in the POSfile matches 
    the value of 'id' in the existing xml file, 
    it adds the pos tags that are stored as attribute-value pairs in (POSfile) 
    to the xml file and writes this to a new document 'xmlPOS'. 
    """ 

    treePOS = ET.parse(POSfile) 
    rootPOS = treePOS.getroot() 
    tree = ET.parse(xmlfile) 
    root = tree.getroot() 


    for w in rootPOS.iter('w'): 
     idPOS = w.get('id') 

    for w in root.iter('w'): 
     idxml = w.get('id') 

    for w in rootPOS.iter('w'): 
     POSval = w.get('pos') 

    if idPOS == idxml:   
     w.set('pos', POSval) 

    tree.write('xmlPOS.xml') 

    return xmlPOS 

для этой работы я 'd необходимо преобразовать вывод тегатора' house/N 'в формат xml:

<w id="1" pos="N">house</w> 

Но даже если я это сделаю, а затем импортирую вышеуказанный модуль в Python, я, похоже, не могу добавить теги POS в существующий xml-файл (который, конечно, содержит более редакционную разметку, чем приведенный выше пример). Возможно, я должен использовать XSLT вместо этого Python xml parser? Я еще не очень хорошо знаком с XSLT, поэтому решил, что сначала попробую это на Python.

Любые комментарии или предложения будут высоко оценены: спасибо заранее!

ответ

0

Метод set - это подходящий способ установки атрибутов в ElementTree, и я просто протестировал его, когда он применяется к XML-файлу, считываемому с диска.

Интересно, является ли ваша проблема алгоритмической - алгоритм, который вы написали, не похож на то, что вы хотите. idPOS, idxml и POSval будут равны последним сопоставимым значениям в каждом файле, а w будет равен последнему тегу <w>. Он может только изменить одно слово, последнее. Если вы собираетесь настраивать часть речевых атрибутов навалом, возможно, вам нужно что-то более похожее на следующее (вам может потребоваться настроить его, если я сделал некоторые ошибочные предположения о том, как структурируется POSfile):

# load all "pos" attributes into a dictionary for fast lookup 
posDict = {} 
for w in rootPOS.iter("w"): 
    if w.get("pos") is not None: 
     posDict[w.text] = w.get("pos") 

# if we see any matching words in the xmlfile, set their "pos" attrbute 
for w in root.iter("w"): 
    if w.text in posDict: 
     w.set("pos", posDict[w.text]) 
+0

Спасибо вам большое! Похоже, что это работает над моим упрощенным тестовым файлом. Теперь я попытаюсь заставить его работать с фактическими файлами с большим количеством элементов и атрибутов, которые ему нужно будет пропустить. Ваш фрагмент кода - большая помощь: очень ценится! – lothelanor

+0

Хорошо, теперь я считаю, что это работает для тестового файла только потому, что все слова в этом маленьком файле образца уникальны. Однако в фактическом тексте это не так, поэтому я в первую очередь дал уникальные идентификаторы, чтобы я мог их сопоставить. Например. слово «играть» на английском языке иногда имеет POS-тег «N (oun)», а иногда POS-тег «V (erb)» в зависимости от контекста, поэтому, если я сохраню их в словаре, как вы предлагаете, это уникальный контекст потерян, не так ли? Вот почему я думал, что должен добавить уникальные идентификаторы, но, возможно, есть способ построить это в нем? – lothelanor

+0

Чтобы определить часть речи по контексту, потребуется обработка естественного языка, что будет значительно более сложным алгоритмом, чем мы говорили. Вероятно, самый простой подход, который мог бы быть на 90% точным (грубые цифры), - это сделать n-граммовый анализ, где вы ищете пары слов и сопоставляете их с парами частей речи. Например, «дети играют» всегда будут существительным-глаголом. Мало того, что это увеличивает сложность альгортма, но набор данных должен быть намного больше, потому что для поиска более чем двух словных комбинаций существует намного больше двух слов. –

0

Я выполнил тегирование, но мне нужно написать вывод te в XML-файл. Выход Таггер выглядит следующим образом:

The/DET house/N is/V big/ADJ ./PUNC 

XML файл, из которого текст пришел будет выглядеть следующим образом:

<s> 
<w>The</w> 
<w>house</w> 
<w>is</w> 
<w>big</w> 
<w>.</w> 
</s> 

Теперь я хотел бы добавить POS-теги в виде пар атрибут-значение для xml-элементы:

<s> 
<w pos="DET">The</w> 
<w pos="N">house</w> 
<w pos="V">is</w> 
<w pos="ADJ">big</w> 
<w pos="PUNC">.</w> 
</s> 

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

0

я теперь удалось сделать что-то подобное с ElementTree:

import sys 
import os 
import re 
import tree 

def xmldump(file_name, xmldump): 

    """ 
    Function takes one argument (file_name), and returns a list 
    containing (for every sentence) a list of word-pos pairs 
    It then converts this output to xml. 
    """ 

text = ' '.join(open(file_name).readlines()) 

#split the text into sentences 
sentences = re.split("\.\/PUNC", text) 

xmlcorpus = [] 

#convert sentences to xml  
for s in sentences: 
    t = tree.xml(s) 
    xmlcorpus.append(t) 

#write xmlcorpus to new file 
with open(xmldump, 'w') as f: 
    for sent in xmlcorpus: 
     f.write(sent) 

return xmldump 

Этот вид работ, хотя в настоящее время существует «щель» и элементы «Chunk» автоматически генерируется «дерево» в ElementTree модуль, Я никак не могу избавиться.

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