Last active
May 20, 2020 04:04
-
-
Save Kesin11/3957809 to your computer and use it in GitHub Desktop.
ChaSen擬似Pythonラッパー
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#coding: utf-8 | |
""" | |
ChaSenの擬似ラッパー | |
""" | |
import subprocess | |
class UnidicTagger(object): | |
''' | |
MeCabのTaggerライクなChaSenのTagger | |
今のところ unidic+utf-8環境専用 | |
MeCabバインディングと異なり、pythonライクにfor文とリスト内包表記が使えます。逆にwhile文に未対応。 | |
シェルを通して無理やりchasenを呼び出し、parseToNodeがジェネレーターを返す仕組みになってます | |
基本形や品詞などに直接アクセスできるので公式のMeCabバインディングより少し便利です | |
使い方: | |
main関数のサンプルを見てください | |
変数へのアクセス: | |
.raw: ipadic形式のChaSenの出力そのもの | |
.surface: 出現形 | |
.yomi: ヨミ | |
.base: 基本形 | |
.pos: 品詞('-'区切り) | |
.feature: 活用型,活用形 | |
''' | |
def __init__(self, rc_path=None, bin_path=None): | |
'''コンストラクタ | |
引数: | |
bin_path: chasenまでのパス | |
rc_path: 使用するchasenrcまでのパス | |
''' | |
#bin_pathが無ければシステムデフォルトのChaSenを使用 | |
try: | |
self._path = bin_path if bin_path else subprocess.check_output(('which chasen'), shell=True).strip() | |
#Eclipse環境だとシェルからchasenへのパスを取得できない | |
except subprocess.CalledProcessError: | |
raise AssertionError, 'Please input chasen binary path' | |
#rc_pathが与えられなければデフォルトのchasenrcを使用 | |
self._option = '-r ' + rc_path if rc_path else '' | |
#ipadicと同じ出力フォーマット 出現形/ヨミ/基本形/品詞/活用型/活用形 | |
self._format = '"%m\\t%y\\t%M\\t%U(%P-)\\t%T \\t%F \\n"' | |
self._option += ' -iw -F %s' % self._format | |
def parseToNode(self, string): | |
"""与えられた文字列を形態素解析し、MeCabライクなイテレータnodeを返す | |
MeCabとは異なり、戻り値はPythonのイテレータなのでwhileで使うときはnode.next()を呼び出す。 | |
その代わり、MeCabでは不可能であったPythonライクなfor文や内包表記をサポートしています。 | |
""" | |
string = string.strip() | |
raws = subprocess.check_output(('echo "%s" | %s %s' %(string, self._path, self._option)), shell=True).strip().split('\n') | |
for raw in raws: | |
if raw: | |
self.node = Node() | |
splited = raw.split('\t') | |
self.node.raw = raw | |
self.node.surface = splited[0] | |
self.node.yomi = splited[1] | |
self.node.base = splited[2] | |
self.node.pos = splited[3] | |
self.node.feature = ','.join(splited[4:]) | |
else: | |
continue | |
yield self.node | |
class Node(object): | |
"""parseToNodeの結果にnode.surfaceなどのようにアクセスしやすくするために、構造体的に使用するオブジェクト""" | |
def __init__(self): | |
self.raw='' | |
self.surface='' | |
self.yomi='' | |
self.base='' | |
self.pos='' | |
self.feature='' | |
def __str__(self): | |
return self.raw | |
if __name__ == '__main__': | |
t = UnidicTagger(rc_path='/opt/local/lib/chasen/dic/unidic/chasenrc', bin_path='/opt/local/bin/chasen') | |
#pythonライクなfor文 | |
for node in t.parseToNode('大阪観光したいと思っている'): | |
print node.surface, #出現形 | |
print node.yomi, #ヨミ | |
print node.base, #基本形 | |
print node.pos, #品詞 | |
print node.feature #活用型,活用形 | |
''' | |
>>大阪 オオサカ 大阪 名詞-固有名詞-地名-一般 , | |
>>観光 カンコウ 観光 名詞-普通名詞-サ変可能 , | |
>>し シ する 動詞-非自立可能 サ行変格,連用形-一般 | |
>>たい タイ たい 助動詞 助動詞-タイ,終止形-一般 | |
>>と ト と 助詞-格助詞 , | |
>>思っ オモッ 思う 動詞-一般 五段-ワア行-一般,連用形-促音便 | |
>>て テ て 助詞-接続助詞 , | |
>>いる イル いる 動詞-非自立可能 上一段-ア行,終止形-一般 | |
''' | |
#リスト内包表記にも対応 | |
bases = [node.base for node in t.parseToNode('大阪観光したいと思っている')] | |
'''>>大阪 観光 する たい と 思う て いる''' | |
print '\t'.join(bases) | |
#インスタンス.base, またはインスタンスそのものを呼び出すとchasenの生の出力 | |
for node in t.parseToNode('豊橋'): | |
print node.raw #ipadicと同じ出力形式 出現形/ヨミ/基本形/品詞/活用型/活用形 | |
print node | |
''' | |
>>豊橋 トヨハシ 豊橋 名詞-固有名詞-地名-一般 | |
>>豊橋 トヨハシ 豊橋 名詞-固有名詞-地名-一般 | |
''' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment