2012-02-05 47 views
7

我想從德語文檔中提取單詞,當我使用nLtk教程中描述的下列方法時,我無法獲取具有特定語言特殊字符的單詞。使用nltk從德語文本中提取單詞

ptcr = nltk.corpus.PlaintextCorpusReader(Corpus, '.*'); 
words = nltk.Text(ptcr.words(DocumentName)) 

我應該怎麼做才能得到文檔中的單詞列表?

nltk.tokenize.WordPunctTokenizer()爲德國短語Veränderungen über einen Walzer示例如下:

In [231]: nltk.tokenize.WordPunctTokenizer().tokenize(u"Veränderungen über einen Walzer") 

Out[231]: [u'Ver\xc3', u'\xa4', u'nderungen', u'\xc3\xbcber', u'einen', u'Walzer'] 

在這個例子中「A」被視爲一個分隔符,即使「ü」沒有。

+2

你會得到什麼而不是單詞列表?你知道你的輸入文件的編碼嗎? – shenshei 2012-02-05 13:52:12

+0

我得到一個異常分隔的單詞列表,例如德語字母'ä'被視爲分隔符。編碼是'utf-8'。 – red 2012-02-05 13:58:59

+0

這很奇怪,因爲PlaintextCorpusReader使用WordPunctTokenizer()來處理unicode來標記文本。你可以給我一個使用nltk.tokenize.WordPunctTokenizer()的bug的例子。tokenize(「你有錯誤的文本」) – shenshei 2012-02-05 15:29:18

回答

1

你可能會嘗試一個簡單的正則表達式。如果你只想要這些單詞,下面就足夠了。它會吞下所有標點符號:

>>> import re 
>>> re.findall("\w+", "Veränderungen über einen Walzer.".decode("utf-8"), re.U) 
[u'Ver\xe4nderungen', u'\xfcber', u'einen', u'Walzer'] 

注意re.U改變的\w基於當前區域的RE的意思,所以一定要確保我們設置正確。我已將它設置爲en_US.UTF-8,這對您的示例來說顯然已經足夠好了。

另請注意,"Veränderungen über einen Walzer".decode("utf-8")u"Veränderungen über einen Walzer"是不同的字符串。

3

看看http://text-processing.com/demo/tokenize/ 由於演示中的WordPunctTokenizer可以處理單詞,因此我不確定您的文本是否獲得了正確的編碼。 PunktWordTokenizer也是如此。

+0

我檢查過,但我認爲他們隱式處理問題:D。 – red 2012-02-09 18:03:40

11
與參數編碼= 'UTF-8'

呼叫PlaintextCorpusReader:

ptcr = nltk.corpus.PlaintextCorpusReader(Corpus, '.*', encoding='utf-8') 

編輯:我看......你這裏有兩個不同的問題:

一)符號化的問題:當您測試用德文的文字字符串, you 認爲你是 進入unicode。實際上,你告訴python在引號之間取字節 並將它們轉換爲unicode字符串。但是你的字節被誤解爲 。修復:在 源文件的頂部添加以下行。

# -*- coding: utf-8 -*- 

突然你的常量將可以看到並正確標記化:

german = u"Veränderungen über einen Walzer" 
print nltk.tokenize.WordPunctTokenizer().tokenize(german) 

問題二:原來,Text()不使用unicode!如果您將 傳遞給一個unicode字符串,它會嘗試將其轉換爲純ASCII字符串 ,這當然會在非ascii輸入上失敗。啊。

解決方案:我的建議是完全避免使用nltk.Text,並直接與語料庫讀者一起工作。 (這通常是一個好主意:請參閱nltk.Text的自己的文檔)。

但是,如果你必須使用nltk.Text與德國的數據,這裏是如何:讀您的 數據正確,因此它可以被符號化,但隨後「編碼」你的unicode回str列表。對於德國人來說, 對於只使用Latin-1編碼可能最安全,但utf-8似乎也可以工作 。

ptcr = nltk.corpus.PlaintextCorpusReader(Corpus, '.*', encoding='utf-8'); 

# Convert unicode to utf8-encoded str 
coded = [ tok.encode('utf-8') for tok in ptcr.words(DocumentName) ] 
words = nltk.Text(coded) 
+0

這給了我的單詞列表,當我用nltk.Text封裝時,我得到「'ascii'編解碼器無法編碼字符u'\ xdf'在位置2:序號不在範圍(128)」中。我認爲這是一個編碼解碼問題。 – red 2012-02-09 18:10:09

+0

你肯定有一個編碼問題,或者說兩個。查看更新後的答案。 – alexis 2012-02-29 12:55:39

相關問題