2015-05-11 1 views
1

Целью моего проекта является ответить на такие вопросы, как, например: «Я ищу американских женщин в возрасте от 20 до 30 лет, которые работают в Google» Я тогда должен обработать запрос и посмотреть в БД, чтобы найти ответ.NLTK: объединение stanford tagger и персонального tagger

Для этого мне нужно будет объединить NERTagger 3-го класса Stanford и собственный теггер. Действительно, мой теггер NER может помечать возраст, национальности и пол. Но мне нужен теггер Стэнфорда, чтобы тегировать организации, так как у меня нет учебного файла для этого.

Прямо сейчас, у меня есть такой код:

def __init__(self, q): 
    self.userQuery = q 
def get_tagged_tokens(self): 
    st = NERTagger('C:\stanford-ner-2015-01-30\my-ner-model.ser.gz','C:\stanford-ner-2015-01-30\stanford-ner.jar') 
    result = st.tag(self.userQuery.split())[0] 
    return result 

И я хотел бы иметь что-то вроде этого:

def get_tagged_tokens(self): 
    st = NERTagger('C:\stanford-ner-2015-01-30\my-ner-model.ser.gz','C:\stanford-ner-2015-01-30\stanford-ner.jar') 
    st_def = NERTagger('C:\stanford-ner-2015-01-30\classifiers\english.all.3class.distsim.crf.ser.gz','C:\stanford-ner-2015-01-30\stanford-ner.jar') 
    tagger = BackoffTagger([st, st_def]) 
    result = st.tag(self.userQuery.split())[0] 
    return result 

Это будет означать, что Таггер первый использует мой Tagger, а затем Стэнфорд, чтобы пометить непомеченные слова.

Возможно ли совместить мою модель с моделью Стэнфорда, чтобы пометить организации? Если да, то каков наилучший способ выполнить это?

Спасибо!

ответ

5

Новый NERClassifierCombiner с Stanford CoreNLP 3.5.2 или новый Stanford NER 3.5.2 добавил функциональность командной строки, которая позволяет легко получить этот эффект с помощью NLTK.

Когда вы предоставляете список сериализованных классификаторов, NERClassifierCombiner будет запускать их последовательно. После того, как один теггер отправляет предложение, никакие другие метки не будут помечать теки, которые уже были помечены. Поэтому в моем демо-коде обратите внимание на 2 классификатора. Они запускаются в том порядке, в котором вы их размещаете. Я считаю, что вы можете поставить до 10, если я правильно помню!

Прежде всего, убедитесь, что у вас есть последняя копия Stanford CoreNLP 3.5.2 или Stanford NER 3.5.2, так что у вас есть правый .jar-файл с этой новой функциональностью.

Во-вторых, убедитесь, что ваша пользовательская модель NER была построена с помощью Stanford CoreNLP или Stanford NER, это не сработает иначе! Это должно быть хорошо, если вы использовали более старые версии.

В-третьих, я предоставил некоторые примеры кода, который должен работать, основная суть этого подкласса NERTagger:

Если люди хотели бы я мог смотреть в толкая это NLTK так там по умолчанию!

Вот пример кода (это немного взломано, так как я просто торопился выходить из двери, например, в конструкторе NERComboTagger нет никакого смысла, чтобы первый аргумент был classifier_path1, но код сработал бы, если бы я didn ' т поставить правильный файл там):

#!/usr/bin/python 

from nltk.tag.stanford import NERTagger 

class NERComboTagger(NERTagger): 

    def __init__(self, *args, **kwargs): 
    self.stanford_ner_models = kwargs['stanford_ner_models'] 
    kwargs.pop("stanford_ner_models") 
    super(NERComboTagger,self).__init__(*args, **kwargs) 

    @property 
    def _cmd(self): 
    return ['edu.stanford.nlp.ie.NERClassifierCombiner', 
      '-ner.model', 
      self.stanford_ner_models, 
      '-textFile', 
      self._input_file_path, 
      '-outputFormat', 
      self._FORMAT, 
      '-tokenizerFactory', 
      'edu.stanford.nlp.process.WhitespaceTokenizer', 
      '-tokenizerOptions', 
      '\"tokenizeNLs=false\"'] 

classifier_path1 = "classifiers/english.conll.4class.distsim.crf.ser.gz" 
classifier_path2 = "classifiers/english.muc.7class.distsim.crf.ser.gz" 

ner_jar_path = "stanford-ner.jar" 

st = NERComboTagger(classifier_path1,ner_jar_path,stanford_ner_models=classifier_path1+","+classifier_path2) 

print st.tag("Barack Obama is from Hawaii .".split(" ")) 

Обратите внимание на существенное изменение в подклассе является то, что возвращается _cmd.

Также обратите внимание, что я запустил это в распакованной папке stanford-ner-2015-04-20, поэтому пути к этому относятся.

я получаю этот выход:

[('Barack','PERSON'), ('Obama', 'PERSON'), ('is','O'), ('from', 'O'), ('Hawaii', 'LOCATION'), ('.', 'O')] 

Вот ссылка на страницу Stanford РЭК:

http://nlp.stanford.edu/software/CRF-NER.shtml

Пожалуйста, дайте мне знать, если вам нужна дополнительная помощь или если есть какие-либо ошибки в моем коде, я, возможно, допустил ошибку при расшифровке, но это работает на моем ноутбуке!

+0

Большое спасибо! Это то, что мне нужно. Я думаю, было бы хорошо, если бы он был по умолчанию в NLTK, но это просто мое мнение! – LM91