2012-09-18 84 views
4

我將獲取用中文書寫的文檔,我必須標記並保存在數據庫表中。我正在嘗試Lucene的CJKBigramFilter,但它所做的只是將兩個字符合並在一起,因爲它們的含義與文檔中的含義不同。假設這是文件「Hello My name is Pradeep」中的一行,在中國傳統中是「你好我的名字是普拉迪普」。當我標記它時,它將轉換爲下面的2個字母的單詞。 你好 - 你好 名字 - 命名 好我 - 嗯,我 字是 - 字是 我的 - 我的 拉迪 - 拉迪 是普 - 是對S & P 普拉 - 普拉 的名 - 在迪普 - 迪普的名字 。 我只需要將它轉換成相同的英文翻譯。 我爲此使用Lucene ...如果您有任何其他有利的opne資源,請直接告訴我。 預先感謝如何標記中文文檔

+0

此信息可能會有所幫助http://stackoverflow.com/questions/7626912/how -does-tokenization-and-pattern-matching-work-in-chinese –

+0

這是完全不同的意義,斯坦福擁有自己的設置標記中文字符,我不能使用,因爲我使用的是Lucene。我只是想知道,在Lucene中,我怎麼能象我在問題描述中所描述的那樣標記中文字符。 – Pradeep

回答

3

雖然可能爲時已晚,但您可以試試U-Tokenizer這是一個在線API,它可以免費使用。 見http://tokenizer.tool.uniwits.com/

+0

你可以多加一點給你的答案,並解釋如何使用該網站。 –

+0

請閱讀http://tokenizer.tool.uniwits.com/qx-cmd-api.html獲取指南。如果您有詳細的問題,我會盡力回答。 – Afante

+0

它已經死了,不見了 – Henry

3

如果你想要一個完全成熟的NLP解析器,結賬出來http://nlp.stanford.edu

如果你想爲中國的一個簡單的,一次性的解決方案,這是我用什麼。

首先將中文字典加載到Trie(前綴樹)中以減少內存佔用量。然後,我在字典中查看字符,觀察詞典中存在的枯萎子串。如果他們這樣做,我會把它解析爲一個令牌。該算法可能會大大改善,但這對我來說很好。 :)

public class ChineseWordTokenizer implements WordTokenizer { 

    private static final int MAX_MISSES = 6; 

    // example implementation: http://www.kennycason.com/posts/2012-03-20-java-trie-prefix-tree.html 
    private StringTrie library; 

    private boolean loadTraditional; 

    public ChineseWordTokenizer() { 
     this(true); 
    } 

    public ChineseWordTokenizer(boolean loadTraditional) { 
     loadLibrary(); 
     this.loadTraditional = loadTraditional; 
    } 

    @Override 
    public String[] parse(String sentence) { 
     final List<String> words = new ArrayList<>(); 
     String word; 
     for (int i = 0; i < sentence.length(); i++) { 
      int len = 1; 
      boolean loop = false; 
      int misses = 0; 
      int lastCorrectLen = 1; 
      boolean somethingFound = false; 
      do { 
       word = sentence.substring(i, i + len); 
       if (library.contains(word)) { 
        somethingFound = true; 
        lastCorrectLen = len; 
        loop = true; 
       } else { 
        misses++; 
        loop = misses < MAX_MISSES; 
       } 
       len++; 
       if(i + len > sentence.length()) {; 
        loop = false; 
       }   
      } while (loop); 

      if(somethingFound) { 
       word = sentence.substring(i, i + lastCorrectLen); 
       if (StringUtils.isNotBlank(word)) { 
        words.add(word); 
        i += lastCorrectLen - 1; 
       } 
      } 
     } 
     return words.toArray(new String[words.size()]); 
    } 

    private void loadLibrary() { 
     library = new StringTrie(); 
     library.loadFile("classify/nlp/dict/chinese_simple.list"); 
     if(loadTraditional) { 
      library.loadFile("classify/nlp/dict/chinese_traditional.list"); 
     } 
    } 

} 

這裏是一個單元測試

public class TestChineseWordTokenizer { 

    @Test 
    public void test() { 
     long time = System.currentTimeMillis(); 
     WordTokenizer tokenizer = new ChineseWordTokenizer(); 
     System.out.println("load time: " + (System.currentTimeMillis() - time) + " ms"); 

     String[] words = tokenizer.tokenize("彈道導彈"); 
     print(words); 
     assertEquals(1, words.length); 

     words = tokenizer.tokenize("美國人的文化.dog"); 
     print(words); 
     assertEquals(3, words.length); 

     words = tokenizer.tokenize("我是美國人"); 
     print(words); 
     assertEquals(3, words.length); 

     words = tokenizer.tokenize("政府依照法律行使執法權,如果超出法律賦予的權限範圍,就是「濫用職權」;如果沒有完全行使執法權,就是「不作爲」。兩者都是政府的錯誤。"); 
     print(words); 

     words = tokenizer.tokenize("國家都有自己的政府。政府是稅收的主體,可以實現福利的合理利用。"); 
     print(words); 
    } 

    private void print(String[] words) { 
     System.out.print("[ "); 
     for(String word : words) { 
      System.out.print(word + " "); 
     } 
     System.out.println("]"); 
    } 
} 

這裏是結果

Load Complete: 102135 Entries 
load time: 236 ms 
[ 彈道導彈 ] 
[ 美國人 的 文化 ] 
[ 我 是 美國人 ] 
[ 政府 依照 法律 行使 執法 權 如果 超出 法律 賦予 的 權限 範圍 就是 濫用職權 如果 沒有 完全 行使 執法 權 就是 不 作爲 兩者 都 是 政府 的 錯誤 ] 
[ 國家 都 有 自己 的 政府 政府 是 稅收 的 主體 可以 實現 福利 的 合理 利用 ] 
+0

嗨,Kenny!我想嘗試解決您的解決方案,並將其性能與當前的標記器進行比較。你能指點我在哪裏尋找一個可用的字典嗎?我沒有在你的github存儲庫以及stanford nlp數據中找到它...非常感謝! – wojtuch