Как я могу удалить POS-теги перед косой чертой в nltk?

Это часть моего проекта, где мне нужно представить вывод после обнаружения фразы следующим образом: (a,x,b), где a, x, b — фразы. Я построил код и получил вывод следующим образом:

(CLAUSE (NP Jack/NNP) (VP loved/VBD) (NP Peter/NNP))
(CLAUSE (NP Jack/NNP) (VP stayed/VBD) (NP in/IN London/NNP))
(CLAUSE (NP Tom/NNP) (VP is/VBZ) (NP in/IN Kolkata/NNP))

Я хочу сделать его таким же, как предыдущее представление, что означает, что я должен удалить теги «CLAUSE», «NP», «VP», «VBD», «NNP» и т. Д.

Как это сделать?

Что я пробовал

Сначала написал это в текстовом файле, токенизировал и использовал list.remove('word'). Но это совсем не полезно. Я еще немного уточняю.

Мой вклад

(CLAUSE (NP Jack/NNP) (VP loved/VBD) (NP Peter/NNP)) (CLAUSE (NP Jack/NNP) (VP stayed/VBD) (NP in/IN London/NNP))

Выход будет

[Джек,любил,Питер], [Джек,остался,в Лондоне] Вывод только по фигурным скобкам и без тегов.


person Salah    schedule 14.11.2015    source источник
comment
Пожалуйста, поделитесь соответствующей частью вашего кода   -  person bigOther    schedule 14.11.2015
comment
Какую часть кода вы хотите в основном? В любом случае Text=open('phrase_output.txt') t=Text.read() text=nltk.word_tokenize(t); вывести текст text.remove('CLAUSE') text.remove('NP')   -  person Salah    schedule 14.11.2015
comment
странно, потому что nltk.word_tokenize(t); дает мне список слов, без тегов: ['Julia', 'loves', 'Peter'] ...вы используете какую-то другую конфигурацию или что-то в этом роде?   -  person bigOther    schedule 14.11.2015
comment
что вы вводили? Это «Юлия любит Питера»?   -  person Salah    schedule 14.11.2015
comment
да 'Julia loves Peter'   -  person bigOther    schedule 14.11.2015
comment
Мой ввод был «(CLAUSE (NP Jack/NNP) (VP любимый/VBD) (NP Peter/NNP))».   -  person Salah    schedule 14.11.2015
comment
Это проблема синтаксического анализа, а не проблема nltk   -  person bigOther    schedule 14.11.2015
comment
@SoubhikR Кстати, как вы извлекли пункт?   -  person alvas    schedule 14.11.2015
comment
@bigOTHER можете конкретно предложить?   -  person Salah    schedule 15.11.2015
comment
Я думаю, что @alvas дал вам хороший ответ   -  person bigOther    schedule 15.11.2015
comment
Можете ли вы отредактировать свой вопрос и добавить точно то, что вы хотите видеть в качестве очищенной версии ваших трех предложений? Вы думаете, что вы чисты, но это не так.   -  person alexis    schedule 16.11.2015
comment
@alexis Спасибо за комментарий. Я сделал некоторые улучшения.   -  person Salah    schedule 17.11.2015


Ответы (4)


Поскольку вы пометили это nltk, давайте воспользуемся синтаксическим анализатором деревьев NLTK для обработки ваших деревьев. Мы прочитаем каждое дерево, а затем просто распечатаем листья. Сделанный.

>>> text ="(CLAUSE (NP Jack/NNP) (VP stayed/VBD) (NP in/IN London/NNP))"
>>> tree = nltk.Tree.fromstring(text, read_leaf=lambda x: x.split("/")[0])
>>> print(tree.leaves())

['Jack', 'stayed', 'in', 'London']

Лямбда-форма разбивает каждую пару word/tag и отбрасывает тег, оставляя только слово.

Несколько деревьев

Я знаю, вы спросите меня, как обрабатывать целый файл таких деревьев, и некоторые из них занимают больше одной строки. Это работа BracketParseCorpusReader NLTK, но он ожидает, что терминалы будут в форме (POS word) вместо word/POS. Я не буду делать это таким образом, так как еще проще заставить Tree.fromstring() читать все ваши деревья, как если бы они были ветвями одного дерева:

allmytext = """
(CLAUSE (NP Jack/NNP) (VP loved/VBD) (NP Peter/NNP))
(CLAUSE (NP Jack/NNP) (VP stayed/VBD) (NP in/IN London/NNP))
(CLAUSE (NP Tom/NNP) (VP is/VBZ) (NP in/IN Kolkata/NNP))
"""
wrapped = "(ROOT "+ allmytext + " )"  # Add a "root" node at the top
trees = nltk.Tree.fromstring(wrapped, read_leaf=lambda x: x.split("/")[0])
for tree in trees:
    print(tree.leaves())

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

person alexis    schedule 17.11.2015
comment
Спасибо @alexis. Этот материал полезен. - person Salah; 18.11.2015
comment
Пожалуйста. Когда вы увидите ответ, решающий вашу проблему, примите его, нажав на большую галочку рядом с ним. (Вы также можете голосовать за любые ответы, которые вы считаете полезными). - person alexis; 19.11.2015
comment
Я думаю, что мне не нужно этого делать, потому что '(CLAUSE (NP Jack/NNP) (VPloved/VBD) (NP Peter/NNP))' — это дерево. показать только tree.leaves() и бум! - person Salah; 20.11.2015
comment
Если у вас есть способ разделить ввод на предложения с одним деревом, то у вас его нет. - person alexis; 21.11.2015

>>> import re
>>> clause = "(CLAUSE (NP Jack/NNP) (VP loved/VBD) (NP Peter/NNP))"
>>> pattern = r'\w+:?(?=\/)'
>>> re.findall(pattern, clause)
['Jack', 'loved', 'Peter']

ОТРЕДАКТИРОВАНО

Для нескольких предложений:

>>> import re
>>> pattern = r'\w+:?(?=\/)'
>>> clauses = """(CLAUSE (NP school/NN) (VP is/VBZ situated/VBN) (NP in/IN London/NNP)) (CLAUSE (NP The/DT color/NN of/IN the/DT sky/NN) (VP is/VBZ) (NP pink/NN))"""
>>> [re.findall(pattern, clause) for clause in clauses.split(' (CLAUSE ')]
[['school', 'is', 'situated', 'in', 'London'], ['The', 'color', 'of', 'the', 'sky', 'is', 'pink']]

Если пункты разделены новой строкой:

>>> import re
>>> pattern = r'\w+:?(?=\/)'
>>> clauses = """(CLAUSE (NP Jack/NNP) (VP loved/VBD) (NP Peter/NNP))
... (CLAUSE (NP Jack/NNP) (VP stayed/VBD) (NP in/IN London/NNP))
... (CLAUSE (NP Tom/NNP) (VP is/VBZ) (NP in/IN Kolkata/NNP))"""
>>> [re.findall(pattern, clause) for clause in clauses.split('\n')]
[['Jack', 'loved', 'Peter'], ['Jack', 'stayed', 'in', 'London'], ['Tom', 'is', 'in', 'Kolkata']]

Чтобы объединить вывод в строку:

>>> " ".join(['Jack', 'loved', 'Peter'])
'Jack loved Peter'

>>> clauses = [['Jack', 'loved', 'Peter'], ['Jack', 'stayed', 'in', 'London'], ['Tom', 'is', 'in', 'Kolkata']]
>>> [" ".join(cl) for cl in clauses]
['Jack loved Peter', 'Jack stayed in London', 'Tom is in Kolkata']
person alvas    schedule 14.11.2015
comment
моя цель состоит в том, чтобы идентифицировать фразу, а не слова, и если вы возьмете более одного предложения, ваш код будет генерировать нежелательный результат. Одним из решений может быть сохранение брекетов. Вы принимаете это как ввод и изменяете свой код: (CLAUSE (NP school/NN) (VP is/VBZ situated/VBN) (NP in/IN London/NNP)) (CLAUSE (NP The/DT color/NN of/IN the/DT sky/NN) (VP is/VBZ) (NP pink/NN)) @alvas - person Salah; 15.11.2015
comment
возможно, я не очень ясно выразился. На самом деле вы прекрасно понимаете, что то, что я сделал, полностью основано на фразах. Теперь я хочу различать их запятыми и фигурными скобками, чтобы мы могли легко использовать их в различных аспектах, например, при анализе ассоциативных правил, обработке текста и т. д. Теперь я отредактировал вопрос. Я думаю, теперь цель вам совершенно ясна. Спасибо за ваши усилия, @alvas - person Salah; 17.11.2015

Я пытаюсь что-то вроде этого:

import re
tmp = '(CLAUSE (NP Jack/NNP) (VP loved/VBD) (NP Peter/NNP))'

tmp = re.split(r'[()/ ]', tmp)
#Use 're.split()' to split by character that was not a letter.
>>> ['', 'CLAUSE', '', 'NP', 'Jack', 'NNP', '', '', 'VP', 'loved', 'VBD', '', '', 'NP', 'Peter', 'NNP', '', '']

result = (tmp[4], tmp[9], tmp[14])
>>> ('Jack', 'loved', 'Peter')

Это то, что вы хотите?

ИЗМЕНИТЬ:

надо было подумать :(.

import re
tmp = '(CLAUSE (NP Jack/NNP) (VP loved/VBD) (NP Peter/NNP))'

tmp = re.sub(r'[()]', '', tmp)
>>> 'CLAUSE NP Jack/NNP VP loved/VBD NP Peter/NNP'
result = re.findall(r'[a-zA-Z]*/', tmp)
>>> ['Jack/', 'loved/', 'Peter/']
#Now create a generator.
gen = (i[:-1] for i in result)
tuple(gen)
>>> ('Jack', 'loved', 'Peter')
person SimonShyu    schedule 14.11.2015
comment
результат = (tmp[4], tmp[9], tmp[14]), Как найти позиции для большого количества данных? - person Salah; 14.11.2015
comment
@SoubhikR Я должен был все обдумать :(. - person SimonShyu; 14.11.2015
comment
(ПЛАТА (НП ст/НН) (ВП есть/ВБЗ расположена/ВБН) (НП в/В Лондоне/ННП)) (ПЛАТА (НП В/ДТ цвет/НН/В/ДТ небо/НН) (ВП есть /ВБЗ) (НП розовый/НН)) - person Salah; 14.11.2015
comment
Держите брекеты. В противном случае невозможно различить несколько строк. В любом случае отличная работа, чувак. - person Salah; 14.11.2015
comment
Спасибо и ценю ваш комментарий, он вернул меня на правильный путь. :) - person SimonShyu; 14.11.2015
comment
Ты заслужил это, @SimonShyu. Но все же есть необходимость исправить это. Вы пробовали это для многострочного? Вы можете попробовать его для (ПУТ (НП школа/НН) (ВП есть/ВБЗ расположена/ВБН) (НП в/В Лондоне/ННП)) (ПУТ (НП В/ДТ цвет/НН оф/В/ДТ небо/ НН) (ВП есть/ВБЗ) (НП розовый/НН)) это предложение. - person Salah; 14.11.2015

Когда выходы такие: (CLAUSE (NP Jack/NNP) (VP loved/VBD) (NP Peter/NNP)) (CLAUSE (NP Jack/NNP) (VP stayed/VBD) (NP in/IN London/NNP)) (CLAUSE (NP Tom/NNP) (VP is/VBZ) (NP in/IN Kolkata/NNP)) Совершенно очевидно, что это дерево. Так что просто используйте Tree.leaves(). Вот полный код:

def leaves(self):
    """
    Return the leaves of the tree.

        >>> t = Tree.fromstring("(S (NP (D the) (N dog)) (VP (V chased) (NP (D the) (N cat))))")
        >>> t.leaves()
        ['the', 'dog', 'chased', 'the', 'cat']

    :return: a list containing this tree's leaves.
        The order reflects the order of the
        leaves in the tree's hierarchical structure.
    :rtype: list
    """
    leaves = []
    for child in self:
        if isinstance(child, Tree):
            leaves.extend(child.leaves())
        else:
            leaves.append(child)
    return leaves

Вы можете найти его здесь: http://www.nltk.org/_modules/nltk/tree.html

person Salah    schedule 20.11.2015