web-dev-qa-db-ja.com

nltkを使用したUnicodeのトークン化

'ö'、 'ü'などの文字を含むutf-8エンコーディングを使用するテキストファイルがあります。これらのファイルからテキストを解析したいのですが、トークナイザーを正しく機能させることができません。標準のnltkトークナイザーを使用する場合:

f = open('C:\Python26\text.txt', 'r') # text = 'müsli pöök rääk'
text = f.read()
f.close
items = text.decode('utf8')
a = nltk.Word_tokenize(items)

出力:[u'\ufeff', u'm', u'\xfc', u'sli', u'p', u'\xf6', u'\xf6', u'k', u'r', u'\xe4', u'\xe4', u'k']

パンクトトークナイザーの方がうまくいくようです:

f = open('C:\Python26\text.txt', 'r') # text = 'müsli pöök rääk'
text = f.read()
f.close
items = text.decode('utf8')
a = PunktWordTokenizer().tokenize(items)

出力:[u'\ufeffm\xfcsli', u'p\xf6\xf6k', u'r\xe4\xe4k']

私が理解できない最初のトークンの前にまだ '\ ufeff'があります(それを削除できないわけではありません)。私は何が間違っているのですか?よろしくお願いします。

19
root

_\uFEFF_文字がファイルから読み取られたコンテンツの一部である可能性が高くなります。トークナイザーによって挿入されたとは思えません。ファイルの先頭にある_\uFEFF_は、非推奨の形式である バイト順マーク です。それ以外の場所に表示される場合は、 ゼロ幅の改行なしスペース として扱われます。

ファイルはMicrosoftのメモ帳で作成されましたか?から コーデックモジュールのドキュメント

UTF-8エンコーディングを検出できる信頼性を高めるために、Microsoftはメモ帳プログラム用にUTF-8のバリアント(Python 2.5は「utf-8-sig」を呼び出す)を発明しました。 Unicode文字のいずれかがファイルに書き込まれる前に、UTF-8でエンコードされたBOM(バイトシーケンスとして次のようになります:0xef、0xbb、0xbf)が書き込まれます。

代わりに codecs.open() を使用してファイルを読み取ってみてください。 BOMを消費する_"utf-8-sig"_エンコーディングに注意してください。

_import codecs
f = codecs.open('C:\Python26\text.txt', 'r', 'utf-8-sig')
text = f.read()
a = nltk.Word_tokenize(text)
_

実験:

_>>> open("x.txt", "r").read().decode("utf-8")
u'\ufeffm\xfcsli'
>>> import codecs
>>> codecs.open("x.txt", "r", "utf-8-sig").read()
u'm\xfcsli'
>>> 
_
20
Shawn Chin

Unicode文字列をnltkトークナイザーに渡していることを確認する必要があります。私の側に両方のトークナイザーを使用して、文字列の次の同一のトークン化を取得します。

import nltk
nltk.wordpunct_tokenize('müsli pöök rääk'.decode('utf8'))
# output : [u'm\xfcsli', u'p\xf6\xf6k', u'r\xe4\xe4k']

nltk.Word_tokenize('müsli pöök rääk'.decode('utf8'))
# output: [u'm\xfcsli', u'p\xf6\xf6k', u'r\xe4\xe4k']
13

uFEEコードは「ZEROWIDTHNO-BREAK SPACE」文字であり、これはreモジュールではスペースとは見なされないため、正規表現を使用するPunktWordTokenizer() _r'\w+|[^\w\s]+'_ Unicodeフラグとdotallフラグを使用すると、この文字が単語として認識されます。文字を手動で削除したくない場合は、次のトークナイザーを使用できます。

_nltk.RegexpTokenizer(u'\w+|[^\w\s\ufeff]+')
_
4
shenshei