Python: TaggedCorpusReader, как перейти от STTS к универсальному набору тегов

Я работаю над POS Tagger, используя Python и Keras. Данные, которые у меня есть, используют теги STTS, но я должен создать Tagger для универсального набора тегов. Так что мне нужно перевести это.

Сначала я подумал сделать словарь и просто заменить теги поиском, но потом увидел вариант установки набора тегов с помощью TaggedCorpusReader. (например, «коричневый»)

Но мне не хватает списка возможных наборов тегов, которые можно там использовать. Могу ли я как-то использовать набор тегов STTS или мне нужно сделать словарь самому?

Пример источника: Код № 3: сопоставление тегов корпуса с универсальным набором тегов https://www.geeksforgeeks.org/nlp-customization-using-tagged-corpus-reader/

corpus = TaggedCorpusReader(filePath, "standard_pos_tagged.txt", tagset='STTS') #?? doesn't work sadly
# ....
trainingCorpus.tagged_sents(tagset='universal')[1]

В итоге получилось примерно так: (большое спасибо alexis)

with open(resultFileName, "w") as output:
    for sent in stts_corpus.tagged_sents():
        for word, tag in sent:
            try:
                newTag = mapping_dict[tag];
                output.write(word+"/"+newTag+" ")               
            except:
                print("except "  + str(word) + " - " + str(tag))
        output.write("\n")

person Hans Vader    schedule 04.05.2019    source источник


Ответы (1)


Просто создайте словарь и замените теги, как вы и предполагали. Поддержка универсального набора тегов nltk обеспечивается модулем nltk/tag/mapping.py. Он опирается на набор файлов отображения, которые вы найдете в NLTK_DATA/taggers/universal_tagset. Например, в en-brown.map вы найдете такие строки, которые сопоставляют целую кучу тегов с PRT, ABX с DET и так далее:

ABL     PRT
ABN     PRT
ABN-HL  PRT
ABN-NC  PRT
ABN-TL  PRT
ABX     DET
AP      ADJ

Эти файлы считываются в словарь, который используется для перевода. Создав файл сопоставления в том же формате, вы можете использовать функции nltk для выполнения перевода, но, честно говоря, если ваша задача состоит в том, чтобы просто создать корпус в универсальном формате, я бы просто сделал перевод вручную. Но не с помощью «поиска-замены»: работайте с кортежами, предоставленными средствами чтения корпуса nltk, и просто заменяйте теги POS прямым поиском в вашем словаре сопоставлений.

Предположим, вы знаете, как убедить nltk TaggedCorpusReader прочитать ваш корпус, и теперь у вас есть объект читателя stts_corpus с методами tagged_words(), tagged_sents() и т. д. Вам также нужен словарь отображения, ключи которого являются тегами STTS, а значения — универсальными тегами; если ABL был тегом STTS, mapping_dict["ABL"] должно возвращать значение PRT. Затем ваше переназначение выглядит примерно так:

for filename in stts_corpus.fileids():
    with open("new_dir/"+filename, "w") as output:
        for word, tag in stts_corpus.tagged_words():
            output.write(word+"/"+mapping_dict[tag]+" ")
        output.write("\n")

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

person alexis    schedule 05.05.2019
comment
Работает отлично. Хотя пришлось воспользоваться роскошью новых строк :) - person Hans Vader; 22.05.2019
comment
Для справки, есть два простых подхода к новым строкам: а) зациклить tagged_sents() и вывести новую строку после каждого предложения; или б) собрать вывод в строку и запустить ее через textrwrap.fill() перед записью в файл. - person alexis; 23.05.2019
comment
Я выбрал первый. Перебрал каждый кортеж в tagged_sents и добавил новую строку в конце. А вот второй для меня новый. Спасибо за вклад - person Hans Vader; 23.05.2019