Skip to content

Instantly share code, notes, and snippets.

@Kesin11
Last active May 20, 2020 04:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Kesin11/3957809 to your computer and use it in GitHub Desktop.
Save Kesin11/3957809 to your computer and use it in GitHub Desktop.
ChaSen擬似Pythonラッパー
#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