【Python】GUI上で形態素解析してみた話【MeCab】

Python

こんにちは、Rumadra(@Rumadra)です。

 

前回の記事で、GUIアプリを作るライブラリTkinterについて紹介しました。

 

こちらのプログラムを拡張して行きたいと思います!

 

今回やること

 

・入力した文章を形態素解析する
・入力された文章を基に、形態素解析された結果をGUI上で表示
・表示結果を色分けして表示
レイアウトを調整する
今回は上4つを実装します!

GUIで入力された文章を形態素解析する

入力されたデータを内部でやりとりする方法は、前回実装しているので下のように形態素解析する処理を追加します。

 

import Mecab
mecab = MeCab.Tagger("-Ochasen")
malist = mecab.parse(self.text_box.get())
print(malist)

これだけ。簡単にできますね。

 

解析結果をGUI上に表示させる

画面に解析結果を出すまでの流れとして、

①入力された文章を形態素解析

②解析結果の「単語」と「品詞」の項目のみ抽出する

③「品詞」に応じて色わけする

色分けされた状態で画面に表示

というようにやっていきます。

①はすでに上で実装できているので、②以降について紹介します。

 

解析結果から使いたい項目だけを抽出する

解析結果は次のように出力されます:

世界	セカイ	世界	名詞-一般		
で	デ	で	助詞-格助詞-一般		
一番	イチバン	一番	名詞-副詞可能		
美しい	ウツクシイ	美しい	形容詞-自立	形容詞・イ段	基本形
山	ヤマ	山	名詞-一般		
を	ヲ	を	助詞-格助詞-一般		
見渡す	ミワタス	見渡す	動詞-自立	五段・サ行	基本形
。	。	。	記号-句点		
EOS

ここで分解された「単語」と、「品詞」の種類を抽出します。

 

今回は簡単に「名詞」、「動詞」、「形容詞」のみを抽出します。
そして、コードと結果がこちら:
def analize_phrase(self):
    txt = self.text_box.get()
    print("文字が決定されしました。:" + txt)
    mecab = MeCab.Tagger("-Ochasen")
    node = mecab.parseToNode(txt)
  
    noun = []
    verb = []
    adjective = []

    while node:
        if node.feature.split(",")[0] == u"名詞":
            noun.append(node.surface)
        elif node.feature.split(",")[0] == u"動詞":
            verb.append(node.feature.split(",")[6])
        elif node.feature.split(",")[0] == u"形容詞":
            adjective.append(node.feature.split(",")[6])
        node = node.next
    print('名詞 :')
        for n in noun: print(n)
    print('動詞 :')
    for v in verb: print(v)
    print('形容詞:')
    for a in adjective: print(a)

 

実行結果:

文字が決定されしました。:世界で一番美しい山を見渡す。
名詞 :
世界
一番
山
動詞 :
見渡す
形容詞:
美しい

まあちょっと見辛いですが、list型で分けることができました。

これを使って、GUI上に表示させたいと思います。

品詞の色分け

・「名詞」…
・「動詞」…
・「形容詞」…
このように色を分けることにします。

色分けして画面に表示する

ここが一番苦戦しました。

Labelを使うとテキストを表示させることができます。
先ほど仕分けた結果をそれぞれ配列で持っておき、Labelで配列ごとに配色して設置しました。
とりあえずごちゃごちゃになってしまいましたが、ソースコードです。
import tkinter as tk

import MeCab

class GuiApp(tk.Frame):
    noun = []
    verb = []
    adjective = []
    pw_main = tk
    pw_top = tk
    pw_bottom = tk

    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        self.pack()
        self.create_widgets()

    def create_widgets(self):
        self.pw_main = tk.PanedWindow(self.master, orient='vertical')
        self.pw_main.pack(expand=True, fill=tk.BOTH, side="top")

        self.pw_top = tk.PanedWindow(self.pw_main, bg="olivedrab", orient='vertical')
        self.pw_main.add(self.pw_top)
        self.pw_bottom = tk.PanedWindow(self.pw_main, bg="gray", orient='vertical')
        self.pw_main.add(self.pw_bottom)

        self.quit = tk.Button(self.pw_top, fg="olivedrab", text="終了",
                              command=self.master.destroy)
        self.quit.pack(side="right")

        self.submit_btn = tk.Button(self.pw_top, bg="olivedrab", text="決定", command=self.place_words)
        self.submit_btn.pack(side="right")

        self.text_box = tk.Entry(self.pw_top, width=20, fg="olivedrab")
        self.text_box.insert(tk.END, "何か入力してください。")
        self.text_box.pack(side="top")

    def place_words(self):
        self.analize_phrase()
        if self.pw_bottom.winfo_exists():
            

        for n in range(len(self.noun)):
            label_noun = tk.Label(self.pw_bottom, text=self.noun[n], width=20, bg="blue")
            label_noun.grid(row=n, column=0, padx=2, pady=2)

        for v in range(len(self.verb)):
            label_verb = tk.Label(self.pw_bottom, text=self.verb[v], width=20, bg="red")
            label_verb.grid(row=v, column=1, padx=2, pady=2)

        for a in range(len(self.adjective)):
            label_adjective = tk.Label(self.pw_bottom, text=self.adjective[a], width=20, bg="green")
            label_adjective.grid(row=a, column=2, padx=2, pady=2)

    def analize_phrase(self):
        txt = self.text_box.get()
        print("文字が入力されしました。:" + txt)
        mecab = MeCab.Tagger("-Ochasen")
        node = mecab.parseToNode(txt)
        malist = mecab.parse(txt)

        print(malist)

        while node:
            if node.feature.split(",")[0] == u"名詞":
                self.noun.append(node.surface)
            elif node.feature.split(",")[0] == u"動詞":
                self.verb.append(node.feature.split(",")[6])
            elif node.feature.split(",")[0] == u"形容詞":
                self.adjective.append(node.feature.split(",")[6])
            node = node.next

        print('名詞 :')
        for n in self.noun: print(n)
        print('動詞 :')
        for v in self.verb: print(v)
        print('形容詞:')
        for a in self.adjective: print(a)

root = tk.Tk()
root.geometry('600x400')
root.title('サンプルプログラム')

root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)

app = GuiApp(master=root)
app.mainloop()

まだPythonの言語特性を理解仕切れてない部分があるのでちょっとJavaっぽい書き方になってしましましたが。笑

 

スクショはこんな感じです。

 

中途半端になってしまいましたが、今回はこのあたりで終わります。

 

次回は機能のブラッシュアップをして行きます。

 

以上、Rumadraでした!

コメント

タイトルとURLをコピーしました