57414


一日中詰まっています...アドバイスいただきましたら幸いです。

Windows10 64bit版 でMeCabをUTF8指定でインストールし、anaconda3上のpython3.6.5で使用しようとしています。  
一通りpathを通し、ラッパーとしてmecab-python-windows0.996をpipインストールしました。  
MeCabそのものは正常に動いていて、コマンドプロンプトで以下のように入力すると文字化けせずに出力されます。

<入力>

[code]

    C:\User\username>mecab
    すもももももももものうち
    
[/code]

<出力>

[code]

    すもも　名詞, 一般, .*** ......
    .......
    
[/code]

一方、pythonのライブラリを使うと以下のように出力されてしまいます。

<入力>

[code]

    C:\User\username>python
    .>>> import MeCab
    .>>> m = MeCab.Tagger()
    .>>> m.parse("すもももももももものうち")
    
[/code]

<出力>

[code]

    'す\udce3\t\udc96\udcbc\ucd8c, \udc88\udcca.....
    .......
    
[/code]

import, Tagger等の段階ではエラーは出ません。  
普段テキストデータを扱う際、UTF8では詰まってしまい、utf-8-sigでエンコーディングしているので、そのあたりが問題なのかなと思っていますが、どのように対処すればよいのか検討が付きません...。  
少しでもアドバイスをいただけましたら大変助かります。  
どうぞよろしくお願いいたします。


CC BY-SA 4.0
2019-08-16T10:10:41.807
57405
2020-08-01T08:57:25.017
2019-08-16T15:51:15.120
29826
27030
question
python python3 anaconda mecab unicode
PythonでMeCabを使うと出力が文字化けしてしまいます。


MeCabをSHIFT-JISでインストールした時の現象と酷似しています。  
コマンドラインやPowerShellから下記のコマンドを実行して、標準で使う[辞書の文字コードを確認](http://www.mwsoft.jp/programming/munou/mecab_command.html#dictionary-
info)してください。

[code]

    PS D:\root\usr\MeCab> mecab -D
    filename:       D:\root\usr\MeCab\etc\..\dic\ipadic\sys.dic
    version:        102
    charset:        SHIFT-JIS
    type:   0
    size:   392126
    left size:      1316
    right size:     1316
    
[/code]

`charset: SHIFT-JIS`になっている場合は、SHIFT-JISの辞書を読み込んでいることが原因です。  
もし`charset: UTF-8`になっている場合は、私の回答とは原因と対策が異なります。

なお下記のコマンドはUTF-8でインストールした時の辞書を読み込んだ結果を表示しています。

[code]

    PS D:\root\usr\MeCab> mecab -D -r .\etc\mecabrc_utf8
    filename:       .\etc\..\dic\ipadic_utf8\sys.dic
    version:        102
    charset:        UTF-8
    type:   0
    size:   392126
    left size:      1316
    right size:     1316
    
[/code]

`charset: SHIFT-JIS`の場合は、もう一度MeCabをUTF-8で再インストールすると正しく動作する可能性が高いです。  
※アンインストールは不要です。インストーラから同一フォルダに上書き可能です。  
[![インストーラ](https://i.stack.imgur.com/Cgc5Y.png)](https://i.stack.imgur.com/Cgc5Y.png)

既存の辞書と共存させたい場合は[辞書フォルダをバックアップ](https://qiita.com/zincjp/items/55960801d99e55c9f2a6)しておいてください。  
※上記リンク先のQiita記事を8/17版でそのまま実行すると「PythonからMeCabでの形態素解析」の章でSyntaxError例外が発生しますので、`MeCab.Tagger("-r
C:\...`を`MeCab.Tagger(r"-r C:\...`に読み替えてダブルクォーテーションの前に`r`を付けてください。

または[mecab-ipadic-neologd](https://github.com/neologd/mecab-ipadic-
neologd/blob/master/README.ja.md)という強力な辞書を使って(utf8の辞書なので結果的に)文字化け対策することも可能です。  
※※neologdの辞書作成にはWSL (Windows Subsystem for Linux)などの導入が必要なので非常に苦労する場合もあります。

[code]

    import MeCab
    #todo MeCabのインストールフォルダに書き換え
    root = r"D:\root\usr\MeCab"
    tagger_sjis = MeCab.Tagger()  # SHIFT-JIS
    tagger_sjis.parse("メロンパン")
    # '\udce3\udc83\t\udc96\udcbc\udc8e\udc8c,\udc88\udcea\udc94\udcca,*,*,*,*,*\n\udca1\t\udc96\udcbc\udc8e\udc8c,\udc83T\udc95ϐڑ\udcb1,*,*,*,*,*\n\udce3\udc83\t\udc96\udcbc\udc8e\udc8c,\udc88\udcea\udc94\udcca,*,*,*,*,*\n\udcad\t\udc96\udcbc\udc8e\udc8c,\udc88\udcea\udc94\udcca,*,*,*,*,*\n\udce3\udc83\t\udc96\udcbc\udc8e\udc8c,\udc88\udcea\udc94\udcca,*,*,*,*,*\n\udcb3\t\udc96\udcbc\udc8e\udc8c,\udc88\udcea\udc94\udcca,*,*,*,*,*\nパ\udce3\t\udc96\udcbc\udc8e\udc8c,\udc88\udcea\udc94\udcca,*,*,*,*,*\n\udc83\udcb3\t\udc8bL\udc8d\udc86,\udc83A\udc83\udc8b\udc83t\udc83@\udc83x\udc83b\udc83g,*,*,*,*,\udc83\udcb3,\udc83t\udc83@\udc83C,\udc83t\udc83@\udc83C\nEOS\n'
    tagger_utf8 = MeCab.Tagger(r"-r {}\etc\mecabrc_utf8".format(root)) # 共存させたutf8の辞書をリソースで指定
    tagger_utf8.parse("メロンパン")
    # 'メロン\t名詞,一般,*,*,*,*,メロン,メロン,メロン\nパン\t名詞,一般,*,*,*,*,パン,パン,パン\nEOS\n'
    tagger_neologd = MeCab.Tagger(r"-d {}\dic\mecab-ipadic-neologd".format(root)) # 作成したneologdの辞書をディレクトリで指定
    tagger_neologd.parse("メロンパン")
    # 'メロンパン\t名詞,固有名詞,一般,*,*,*,メロンパン,メロンパン,メロンパン\nEOS\n'
    
[/code]

### python 3.7 でSHIFT-JIS版を使えないか

難しいと思います。

parseにsjisを渡そうとしても文字列はUTF-8です。  
文字列をTaggerでparseすると、sjisを必要とするmecabにUTF-8を渡し、戻ってくるsjisをUTF-8と解釈してエンコードに失敗します。

parseにバイト配列を渡すこともSJISファイルを直接読み込ませることもできません。

[code]

    tagger_sjis.parse('あ'.encode('sjis'))
    # TypeError: in method 'Tagger_parse', argument 2 of type 'char const *'
    
[/code]

出力で`\udce3`などを表示する理由は、parseの戻り値が不明なsjisの場合[超要約すると、PythonがサロゲートコードポイントのうちU+DC80からU+DCFFを私的に流用してるってことのよう](https://autumnas.wordpress.com/2016/10/31/trouble_autoexecute_script_on_nas/)です。  
サロゲートペアの下位をencodeするとエラーとなります。

[code]

    tagger_sjis.parse('あ').encode()
    # UnicodeEncodeError: 'utf-8' codec can't encode characters in position 0-1: surrogates not allowed
    
[/code]

SJISファイルに出力を試みてもSJISへのencodeと同一のエラーになります。

[code]

    tagger_sjis.parse('あ').encode('sjis')
    # UnicodeEncodeError: 'shift_jis' codec can't encode character '\udce3' in position 0: illegal multibyte sequence
    
    with open('test.txt', 'w', encoding='sjis') as f:
        f.write(tagger_sjis.parse('あ'))
    # UnicodeEncodeError: 'shift_jis' codec can't encode character '\udce3' in position 0: illegal multibyte sequence
    
[/code]

デフォルトエンコーディングをSJISに変える方法も3.7では使えません。

[code]

    import sys
    import importlib
    importlib.reload(sys)
    sys.setdefaultencoding('cp932')
    # AttributeError: module 'sys' has no attribute 'setdefaultencoding'
    
[/code]

Popenからコマンドラインでmecabを呼び出すことはできますが、それでは本末転倒です。

以上の試行錯誤の結果から、pythonで形態素解析する場合はMeCabをUTF-8でインストールするかkakashiを使う方が簡単であるという結論に至りました。


CC BY-SA 4.0
2019-08-17T04:46:55.990
57414
2019-08-17T04:46:55.990
9820
57405
answer


私も全く同じ事象に出くわしました。解決したのでご報告。

64bit版のPythonに対して、32bit版のMeCabを使っていないでしょうか？  
私の場合、有志の方が投稿されているMeCabの64bit版をインストールしなおしたら解決しました。


CC BY-SA 4.0
2020-08-01T08:57:25.017
69161
2020-08-01T08:57:25.017
41336
57405
answer