2015-05-09 67 views
0

我是斯坦福大學NLP和NER的新手,並嘗試使用貨幣和國家數據集來訓練自定義分類器。在訓練數據currency.tsv如何在斯坦福NER分類器中抑制不匹配的單詞?

我的訓練數據的模樣 -

USD CURRENCY 
GBP CURRENCY 

而且,在訓練數據countries.tsv訓練數據的模樣 -

USA COUNTRY 
UK COUNTRY 

而且,分類屬性看起來像 -

trainFileList = classifiers/training-data-currency.tsv,classifiers/training-data-countries.tsv 
ner.model=classifiers/english.conll.4class.distsim.crf.ser.gz,classifiers/english.muc.7class.distsim.crf.ser.gz,classifiers/english.all.3class.distsim.crf.ser.gz 
serializeTo = classifiers/my-classification-model.ser.gz 
map = word=0,answer=1 

useClassFeature=true 
useWord=true 
useNGrams=true 
#no ngrams will be included that do not contain either the 
#beginning or end of the word 
noMidNGrams=true 
useDisjunctive=true 
maxNGramLeng=6 
usePrev=true 
useNext=true 
useSequences=true 
usePrevSequences=true 
maxLeft=1 
#the next 4 deal with word shape features 
useTypeSeqs=true 
useTypeSeqs2=true 
useTypeySequences=true 
wordShape=chris2useLC 

用於查找類別的Java代碼是 -

LinkedHashMap<String, LinkedHashSet<String>> map = new<String, LinkedHashSet<String>> LinkedHashMap(); 
NERClassifierCombiner classifier = null; 
try { 
    classifier = new NERClassifierCombiner(true, true, 
      "C:\\Users\\perso\\Downloads\\stanford-ner-2015-04-20\\stanford-ner-2015-04-20\\classifiers\\my-classification-model.ser.gz" 
      ); 
} catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 
List<List<CoreLabel>> classify = classifier.classify("Zambia"); 
for (List<CoreLabel> coreLabels : classify) { 
    for (CoreLabel coreLabel : coreLabels) { 

     String word = coreLabel.word(); 
     String category = coreLabel 
       .get(CoreAnnotations.AnswerAnnotation.class); 
     if (!"O".equals(category)) { 
      if (map.containsKey(category)) { 
       map.get(category).add(word); 
      } else { 
       LinkedHashSet<String> temp = new LinkedHashSet<String>(); 
       temp.add(word); 
       map.put(category, temp); 
      } 
      System.out.println(word + ":" + category); 
     } 

    } 

} 

當我運行上面的代碼,輸入爲「USD」或「UK」時,我得到預期結果爲「CURRENCY」或「COUNTRY」。但是,當我輸入「俄羅斯」之類的東西時,返回值是來自屬性中第一個列車文件的「CURRENCY」。我期待'O'會返回這些值,這是我的訓練數據中不存在的。

我該如何實現這種行爲?任何指向我出錯的指針都會非常有幫助。

回答

2

嗨,我會盡力幫助!

所以它聽起來像你對我有一個字符串列表,應該叫「貨幣」,而你有一個字符串列表,應該被稱爲「國家」,等等

而你要根據列表標記字符串的東西。所以當你看到「俄羅斯」時,你希望它被標記爲「COUNTRY」,當你看到「USD」時,你希望它被標記爲「CURRENCY」。

我認爲,這些工具將是對你更有幫助(尤其是第一個):

http://nlp.stanford.edu/software/regexner/

http://nlp.stanford.edu/software/tokensregex.shtml

的NERClassifierCombiner被設計爲在大量標記的句子的訓練,看看各種各樣的功能,包括大寫字母和周圍的單詞來猜測給定單詞的NER標籤。

但你聽起來對我來說你只是想根據你預先定義的列表明確標記某些序列。所以我會探索我上面提供的鏈接。

請讓我知道如果您需要任何幫助,我會很樂意跟進!

+0

感謝您指出基於正則表達式的工具。但是,我現在面臨的問題是,即使我傳遞了像「abcd」這樣的輸入值,這在我的自定義分類器和標準的7class,4class或3class CRF分類器中都不存在,但我仍然得到如「CURRENCY 」。我期待我不應該回到任何定義的值。 – rockcode

+0

分類器仍會標記未包含在訓練數據中的未知單詞。他們看前綴/後綴,周圍的單詞,大寫等功能...例如,看看在這個例子句子上運行NER的結果,在這個例子中,我剛剛插入了一個構成詞:喬/ PERSON是/ O從/ O/O國家/ O/Blahadfablah/LOCATION。/ O – StanfordNLPHelp

+0

所以,如果你使用正則表達式,你可以明確地說明哪些標記應該被標記爲特定的方式,未知的標記不會被標記。當你用你的字典訓練一個CRFClassifier時,你正在訓練的模型不僅僅是單詞,還包括大寫字母,前綴等......所以我懷疑你正在訓練的模型是學習期望未知單詞是「貨幣」。這尤其不足爲奇,因爲您的培訓數據表明每個單詞都是「貨幣」或「國家」。 – StanfordNLPHelp