インカゼブログ - 中風博客

興味のあるものを紹介していきます

MeCabをPythonで使う - 文字コードの取扱い

Windows 8.1 64 bit Python 32 bit 環境でMeCabを使う。

上記環境でのインストールは以下の記事通りに進めることでできました。感謝。

WindowsでMeCab Pythonを使う - 人工知能に関する断創録

インストール後に問題が。外部テキストファイルを読み込んで形態素解析し、テキストファイル"test_anal.txt"に出力するというもの。

# -*- coding: utf-8 -*-
import MeCab
import sys
m = MeCab.Tagger("-Ochasen")
f = open('test.txt','r')
try:
    text = f.read()
finally:
    f.close()
f = open('test_anal.txt','w')
try:
    f.write(m.parse(text))
finally:
    f.close()

結果は文字化け。

>test_anal.txt

今日はチ・今日はチ・今日はチ・險伜捷-荳闊ャ		
L	L	L	蜷崎ゥ・蝗コ譛牙錐隧・邨・ケ・	
ン・ン・ン・險伜捷-荳闊ャ		
^	^	^	蜷崎ゥ・繧オ螟画磁邯・	
・・・險伜捷-荳闊ャ		
c	c	c	蜷崎ゥ・蝗コ譛牙錐隧・邨・ケ・	
・・・險伜捷-荳闊ャ		
^	^	^	蜷崎ゥ・繧オ螟画磁邯・	
弁当が・弁当が・弁当が・險伜捷-荳闊ャ		
H	H	H	蜷崎ゥ・蝗コ譛牙錐隧・邨・ケ・	
べたい・べたい・べたい・險伜捷-荳闊ャ		
ナ・ナ・ナ・蜷崎ゥ・蝗コ譛牙錐隧・邨・ケ・	
キ・キ・キ・險伜捷-荳闊ャ		
B	B	B	蜷崎ゥ・蝗コ譛牙錐隧・邨・ケ・	
Python	Python	Python	蜷崎ゥ・荳闊ャ		
-	-	-	蜷崎ゥ・繧オ螟画磁邯・	
MeCab	MeCab	MeCab	蜷崎ゥ・荳闊ャ		
の・の・の・險伜捷-荳闊ャ		
e	e	e	蜷崎ゥ・蝗コ譛牙錐隧・邨・ケ・	
・・・險伜捷-荳闊ャ		
X	X	X	蜷崎ゥ・蝗コ譛牙錐隧・邨・ケ・	
・・・險伜捷-荳闊ャ		
g	g	g	蜷崎ゥ・蝗コ譛牙錐隧・邨・ケ・	
・・・險伜捷-荳闊ャ		
B	B	B	蜷崎ゥ・蝗コ譛牙錐隧・邨・ケ・	
EOS

ここでUTF-8で受け渡ししないといけないことに気付く。

# -*- coding: utf-8 -*-
import MeCab
import sys
m = MeCab.Tagger("-Ochasen")
f = open('test.txt','r')
try:
    text = f.read().decode('utf-8') #ここも変更したのだが・・・以下エラーにつながる。
finally:
    f.close()
f = open('test_anal.txt','w')
try:
    f.write(m.parse(text.encode('utf-8'))) #ここが大事。
finally:
    f.close()


ところがエラー。

C:\temp\>python test014.py
Traceback (most recent call last):
  File "test014.py", line 6, in <module>
    text = f.read().decode('utf-8')
  File "C:\Python27\lib\encodings\utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeDecodeError: 'utf8' codec can't decode byte 0x8d in position 0: invalid start byte

悩んだ結果、文章を読み込む側のtest.txtのエンコーディングshift_jisだったことに気づく。
test.txtをf.read()のエンコーディングで'shift_jis'を指定しなければ。

# -*- coding: utf-8 -*-
import MeCab
import sys
m = MeCab.Tagger("-Ochasen")
f = open('test.txt','r')
try:
    text = f.read().decode('shift_jis') #読み込むファイルのエンコーディングはshift_jis
finally:
    f.close()
f = open('test_anal.txt','w')
try:
    f.write(m.parse(text.encode('utf-8')))
finally:
    f.close()

やった。

>test_anal.txt

今日	キョウ	今日	名詞-副詞可能		
は	ハ	は	助詞-係助詞		
チキンタツタ	チキンタツタ	チキンタツタ	名詞-一般		
弁当	ベントウ	弁当	名詞-一般		
が	ガ	が	助詞-格助詞-一般		
食べ	タベ	食べる	動詞-自立	一段	連用形
たい	タイ	たい	助動詞	特殊・タイ	基本形
です	デス	です	助動詞	特殊・デス	基本形
。	。	。	記号-句点		
Python	Python	Python	名詞-一般		
-	-	-	名詞-サ変接続		
MeCab	MeCab	MeCab	名詞-一般		
の	ノ	の	助詞-連体化		
テスト	テスト	テスト	名詞-サ変接続		
。	。	。	記号-句点		
EOS

まとめ
1) MeCabにはstrで渡す。
2) 'xxx'.decode('文字コード')は文字列'xxx'を'文字コード' -> unicodeに変換するもの。

参考
WindowsでMeCab Pythonを使う - 人工知能に関する断創録