2016-01-06 22 views
5

Sto usando sia python che java per eseguire il tagger Stanford NER ma sto vedendo la differenza nei risultati.Differenza dei risultati nel tagger NER di Stanford NLTK (python) vs JAVA

Per esempio, quando ho ingresso la frase "coinvolti in tutti gli aspetti della modellazione dei dati utilizzando ERwin come il software principale per questo.",

JAVA Risultato:

"ERwin": "PERSON" 

Python Risultato:

In [6]: NERTagger.tag("Involved in all aspects of data modeling using ERwin as the primary software for this.".split()) 
Out [6]:[(u'Involved', u'O'), 
(u'in', u'O'), 
(u'all', u'O'), 
(u'aspects', u'O'), 
(u'of', u'O'), 
(u'data', u'O'), 
(u'modeling', u'O'), 
(u'using', u'O'), 
(u'ERwin', u'O'), 
(u'as', u'O'), 
(u'the', u'O'), 
(u'primary', u'O'), 
(u'software', u'O'), 
(u'for', u'O'), 
(u'this.', u'O')] 

Il wrapper nltk Python non può prendere "ERwin" come PERSON.

Ciò che è interessante qui è che sia Python che Java utilizzano gli stessi dati addestrati (inglese.all.3class.caseless.distsim.crf.ser.gz) rilasciati nel 2015-04-20.

Il mio obiettivo finale è far funzionare Python nello stesso modo in cui lo fa Java.

Sto guardando StanfordNERTagger in nltk.tag per vedere se c'è qualcosa che posso modificare. Di seguito è riportato il codice wrapper:

class StanfordNERTagger(StanfordTagger): 
""" 
A class for Named-Entity Tagging with Stanford Tagger. The input is the paths to: 

- a model trained on training data 
- (optionally) the path to the stanford tagger jar file. If not specified here, 
    then this jar file must be specified in the CLASSPATH envinroment variable. 
- (optionally) the encoding of the training data (default: UTF-8) 

Example: 

    >>> from nltk.tag import StanfordNERTagger 
    >>> st = StanfordNERTagger('english.all.3class.distsim.crf.ser.gz') # doctest: +SKIP 
    >>> st.tag('Rami Eid is studying at Stony Brook University in NY'.split()) # doctest: +SKIP 
    [('Rami', 'PERSON'), ('Eid', 'PERSON'), ('is', 'O'), ('studying', 'O'), 
    ('at', 'O'), ('Stony', 'ORGANIZATION'), ('Brook', 'ORGANIZATION'), 
    ('University', 'ORGANIZATION'), ('in', 'O'), ('NY', 'LOCATION')] 
""" 

_SEPARATOR = '/' 
_JAR = 'stanford-ner.jar' 
_FORMAT = 'slashTags' 

def __init__(self, *args, **kwargs): 
    super(StanfordNERTagger, self).__init__(*args, **kwargs) 

@property 
def _cmd(self): 
    # Adding -tokenizerFactory edu.stanford.nlp.process.WhitespaceTokenizer -tokenizerOptions tokenizeNLs=false for not using stanford Tokenizer 
    return ['edu.stanford.nlp.ie.crf.CRFClassifier', 
      '-loadClassifier', self._stanford_model, '-textFile', 
      self._input_file_path, '-outputFormat', self._FORMAT, '-tokenizerFactory', 'edu.stanford.nlp.process.WhitespaceTokenizer', '-tokenizerOptions','\"tokenizeNLs=false\"'] 

def parse_output(self, text, sentences): 
    if self._FORMAT == 'slashTags': 
     # Joint together to a big list  
     tagged_sentences = [] 
     for tagged_sentence in text.strip().split("\n"): 
      for tagged_word in tagged_sentence.strip().split(): 
       word_tags = tagged_word.strip().split(self._SEPARATOR) 
       tagged_sentences.append((''.join(word_tags[:-1]), word_tags[-1])) 

     # Separate it according to the input 
     result = [] 
     start = 0 
     for sent in sentences: 
      result.append(tagged_sentences[start:start + len(sent)]) 
      start += len(sent); 
     return result 

    raise NotImplementedError 

Oppure, se è a causa dell'utilizzo di classificatore diversa (nel codice Java, sembra di usare AbstractSequenceClassifier, d'altra parte, pitone NLTK involucro utilizza il CRFClassifier.) C'è un modo che posso usare AbstractSequenceClassifier nel wrapper python?

+0

L'utilizzo di CoreNLP è la strada da seguire per un uso flessibile degli strumenti Stanford con interfaccia python. Ma lasciami provare se riesco ad entrare in questo modo, dopo colazione però;) – alvas

+0

Qual è il comando Java che hai eseguito? L'hai eseguito sulla riga di comando? – alvas

+0

la soluzione di Gabor Angeli funzionava o no? – user1412066

risposta

5

Provare a impostare maxAdditionalKnownLCWords su 0 nel file di proprietà (o riga di comando) per CoreNLP e, se possibile, anche per NLTK. Ciò disabilita un'opzione che consente al sistema NER di imparare un po 'dai dati del tempo di test, il che potrebbe causare occasionalmente risultati leggermente diversi.

+0

posso sapere come impostare maxAdditionalKnownLCWords? – Amir

+0

@Gabor Puoi spiegare un po 'su questo? – Anish

+0

@Gabor Puoi aiutarmi a impostare maxAdditionalKnownLCWords? –