Pythonを使った、形態素解析器での読みの取得

この記事から、能力2「文が五・七・五かを判定する」の獲得を目指します。

Q. 漢字の読みはどうやって見つけるの? A. 形態素解析器(例えばMeCab)を使うと見つけられる

松尾芭蕉の有名な「古池や蛙飛び込む水の音」を575だと判定するのは、大人の日本人には簡単だが、これを自作プログラムで行うのはとても難しいです。。例えば「古池」をなんと読むのかまで全部実装するのはめんどくさい……というか一大プロジェクトになってしまいます。

ここは先人の知恵を借りましょう。日本語の区切れを見つけたり発音を判別したりする具体的な手法さえ思いつけないのに、それをPythonで実装するのは私にはたぶん無理です。おくのほそ道編とは言いましたが、ここを歩くのはあまりにも無謀です。松尾芭蕉も船を使って移動しているんだし。

ということで、「日本語 読み python」で検索し日本語の発音を取得する【Python】【MeCab】 - Qiitaを見つけます。MeCabというものがあるらしいですね(実は形態素解析器のことは知っていましたし、sudachiなども使ったことはありますが、この知識は前提としていないので、知らない振りをしてMeCabを使っていきます)。

Q. その形態素解析器って何? A. 文を意味のある最小単位で区切って解析してくれるもの

形態素解析器……形態素を解析してくれそうです。「形態素」で検索し形態素 - Wikipediaを見つけます。「形態素とは、言語学の用語で、意味をもつ表現要素の最小単位。ある言語においてそれ以上分解したら意味をなさなくなるところまで分割して抽出された、音素のまとまりの1つ1つを指す。」とのことです。

「形態素」で画像検索すると、例えば「吾輩は猫である」は「吾輩/は/猫/で/ある」のように区切ってくれるようです。575の切れ目の候補に使えそうです。

Q. MeCabって他に何ができるの? A. 品詞分類や、原型や活用、読みも教えてくれる

「MeCab」で検索しMeCab: Yet Another Part-of-Speech and Morphological Analyzerを見つけます。表層形\t品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用型,活用形,原形,読み,発音 を出してくれるようで、今回使う「読み」もしくは「発音」があります。これは非常に使えそうです。

Q. MeCabはどうやって動かすの? A. brewやpipでinstallして、Pythonファイルを書けば動く

とりあえず手元で動かそうとします。使っている端末はMacなので、「mecab install python mac」で調べて【Python】MacにMeCabを入れて自然言語処理をしてみよう(unidic-lite編)にたどり着きます。

brew install mecab-ipadic
pip3 install mecab-python3
pip3 install unidic-lite

の順でターミナルで実行すれば良さそうです(pip3じゃなくpipでも良いかもしれません)。ターミナルでこの順に実行しました。

この状態で、日本語の発音を取得する【Python】【MeCab】 - Qiitaにあった以下のプログラムをそのまま実行してみましょう。

import MeCab
import jaconv

#記号を削除する関数
#(以下
#http://prpr.hatenablog.jp/entry/2016/11/23/Python%E3%81%A7%E5%85%A8%E8%A7%92%E3%83%BB%E5%8D%8A%E8%A7%92%E8%A8%98%E5%8F%B7%E3%82%92%E3%81%BE%E3%81%A8%E3%82%81%E3%81%A6%E6%B6%88%E3%81%97%E5%8E%BB%E3%82%8B
#よりそのまま引用)
import unicodedata
import string

def format_text(text):
    text = unicodedata.normalize("NFKC", text)  # 全角記号をざっくり半角へ置換(でも不完全)

    # 記号を消し去るための魔法のテーブル作成
    table = str.maketrans("", "", string.punctuation  + "「」、。・")
    text = text.translate(table)

    return text
#(引用ここまで)

m = MeCab.Tagger() #形態素解析用objectの宣言

def get_pronunciation(text):
    m_result = m.parse(text).splitlines() #mecabの解析結果の取得
    m_result = m_result[:-1] #最後の1行は不要な行なので除く

    pro = '' #発音文字列全体を格納する変数
    for v in m_result:
        if '\t' not in v: continue
        surface = v.split('\t')[0] #表層形
        p = v.split('\t')[1].split(',')[-1] #発音を取得したいとき
        #p = v.split('\t')[1].split(',')[-2] #ルビを取得したいとき
        #発音が取得できていないときsurfaceで代用
        if p == '*': p = surface
        pro += p

    pro = jaconv.hira2kata(pro) #ひらがなをカタカナに変換
    pro = format_text(pro) #余計な記号を削除

    return pro

#出力確認
text = '今日はよく寝ました'
print(text)
print(get_pronunciation(text))

すると以下のような結果が出ており、確かに発音が出てきています。

今日はよく寝ました
キョーワヨクネマシタ

この記事では、読みの判定を形態素解析器で実現しました。次の記事では、読みが575かを判定します。

© 2019- estie, inc.