SIGMA-SE Math & Tech Library

SIGMA-SE Math & Tech Library


数学と情報技術をテーマに、書籍や教材だけではつかみにくい考え方を具体例とともに簡潔にわかりやすく伝える解説サイトです。
技術の歴史や背景、関連知識の整理、学習のための覚書や要約記事も掲載しています。

Python - タスク指向型対話:1/5 状態遷移ベースの環境準備(MeCab・SCXML)

概要

状態遷移ベースのタスク指向型対話システムを作るために、MeCabとSCXMLの役割、インストール手順、全体構成を整理する。

状態遷移ベースでは、ユーザーの発話を解析し、現在の状態に応じて次の応答や処理を決める。形態素解析を行うMeCabと、状態遷移を表現するSCXMLを理解しておくと、後続の天気案内Bot実装を追いやすくなる。

ここでは、対話システムの構成、MeCabによる発話解析、SCXMLによる状態定義の準備を確認する。

この記事の構成

対象環境と利用上の注意

  • 本文記載時の環境
    CentOS \(7\)、Python \(3.6\)系、PySide2 \(5.15.0\)、Windows \(10\)版Telegramを前提とした手順。
  • 確認時期
    2026年8月にMeCab、SCXML、Qt for Pythonの公式資料と照合し、記載内容を見直した。
  • 現在そのまま利用できない箇所
    掲載コマンドとコード全体は現行環境で再実行していない。
    CentOS \(7\)とPython \(3.6\)は新規構築に使用せず、現行のサポート対象OS・PythonとPySide6への移行資料を確認する。

作業時の注意点

  • MeCabの役割
    応答を生成するライブラリではなく、発話を解析するための形態素解析器。
  • SCXMLの役割
    処理そのものを書くのではなく、状態と遷移の構造を表す。
  • 状態遷移ベースの限界
    想定した状態と遷移を設計する必要があり、自由な雑談には向かない。

解説と実装サンプル

タスク指向型対話システム (状態遷移ベース) のシステム構成について

  • 構成要素と処理の流れ

    タスク指向型とは、対話システムが特定のタスクを遂行することを指し、これから次の記事以降でも継続して解説する天気情報案内や特定の業務を対象とした予約システム、検索システムなど遂行業務を定めている分類のことをいう。

    また、これと対極する非タスク指向型は、雑談システムなどの特定タスク遂行を目的とせず、遂行業務を定めていない分類のことをいう。

    システム構成は、Pythonで作成する対話システムTelegramサーバーTelegramをインストールしたクライアント端末(Android、iPhone、Windows、Linux、Macなど)の単純な \(3\) 構成でデータベースも使わない。
    ※ 以降、Telegramインストールした端末をTelegramクライアントと表現する。

    大まかな処理の流れとしては、Pythonで作成する対話システムを起動すると、 これがBotとしてTelegramクライアントに表示され、ユーザー要求の入力待ち状態となる。

    そして、ユーザーが要求(入力)するとTelegramサーバーを介し、対話システム(Bot)の応答制御処理を経て、結果をユーザーに返し、対話をしていく。

    ここからは、外部ライブラリとなるMeCabSCXMLの概要とインストール手順を確認する。 これ以外にも使用するTelegramOpenWeatherMapについては、次の記事以降で扱う。

    以降の実装では、TelegramクライアントをWindows 10、Pythonの対話システムをLinux(CentOS 7)で動かす前提としている。コマンドやファイルパスは、自身の環境に合わせて読み替える。

対話の文章を解析する「MeCab」の概要とインストール

  • 形態素解析の準備

    まずは、大前提となる文章解析について
    対話の文章解析用に形態素解析(*1)エンジンのオープンソースであるMeCabを用いて作成する。
    (*1)文章を解析し、最小単位の単語(形態素)に分割すること。

    MeCabについて、ここではインストールと呼出し方のみ解説し、理屈や詳細については触れない。

    ※ MeCabについての詳細は、下記公式サイトを参考。
    MeCab: Yet Another Part-of-Speech and Morphological Analyzer

    • MeCabインストール
      Groongaレポジトリの追加とパッケージの最新情報を取得し、mecab本体と辞書ファイルをインストール。

      • Groongaレポジトリ追加
        $ sudo yum install -y https://packages.groonga.org/centos/groonga-release-latest.noarch.rpm
        
      • パッケージ情報の更新
        $ sudo yum makecache
        
      • MeCab本体と辞書ファイルをインストール
        $ sudo yum install mecab mecab-devel mecab-ipadic
        
      • 呼出し確認
        $ mecab
        昨日はいい天気でしたね
        昨日 名詞,副詞可能,*,*,*,*,昨日,キノウ,キノー
        は 助詞,係助詞,*,*,*,*,は,ハ,ワ
        いい 形容詞,自立,*,*,形容詞・イイ,基本形,いい,イイ,イイ
        天気 名詞,一般,*,*,*,*,天気,テンキ,テンキ
        でし 助動詞,*,*,*,特殊・デス,連用形,です,デシ,デシ
        た 助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
        ね 助詞,終助詞,*,*,*,*,ね,ネ,ネ
        EOS
        
      • mecab-python3のインストール
        最後に上記でインストールしたMeCabをPython3から呼び出せるようにmecab-python3をインストールし、Pythonからの呼出しを確認。
        $ pip3 install mecab-python3
        
    • Pythonから呼出し確認
      以下、呼出し確認のサンプルコードmecab-python3_test.py

      import MeCab
      
      mecab = MeCab.Tagger()
      
      # python3-mecabのバグ回避のため,空文字をparse
      mecab.parse('')
      
      # 標準入力からテキストを受け取る
      text = input(">")
      
      node = mecab.parseToNode(text)
      while node:
          print(node.surface, node.feature)
          node = node.next
      

      このまま、上記サンプルコードを実行すると、3行目のMeCab.TaggerでMeCabのインスタンス生成時に近代文語と言われるunidic-liteのインストールpip install unidic-liteコマンドで実施するようエラーがでる。

      • 対話モード (インタプリタ)で確認

        $ python
        >>> import MeCab
        >>>
        >>> mecab = MeCab.Tagger() # MeCabのインスタンス生成
        Failed when trying to initialize MeCab. Some things to check:
        ...(省略)...
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
          File "/var/www/vops/lib64/python3.6/site-packages/MeCab/__init__.py", line 105, in __init__
            super(Tagger, self).__init__(args)
        RuntimeError
        >>>
        

        この環境では、PythonからMeCabを呼び出す際にunidic-liteの追加インストールが必要だった。MeCab本体と辞書を入れていてもPythonバインディング側で辞書を見つけられないことがあるため、まずはエラーメッセージに従って不足している辞書を追加。

        エラーメッセージの通りunidic-liteをインストール。

        $ pip3 install unidic-lite
        
      • 再度、呼出し確認
        今度は、対話モード (インタプリタ)でなくプログラムファイルを実行。

        $ python ~/gitlocalrep/dsbook/mecab-python3_test.py
        >昨日はいい天気でしたね
        BOS/EOS,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*
        昨日 名詞,普通名詞,副詞可能,*,*,*,キノウ,昨日,昨日,キノー,昨日,キノー,和,*,*,*,*,キノウ,キノウ,キノウ,キノウ,*,*,"2,0",C2,*
        は 助詞,係助詞,*,*,*,*,ハ,は,は,ワ,は,ワ,和,*,*,*,*,ハ,ハ,ハ,ハ,*,*,*,"動詞%F2@0,名詞%F1,形容詞%F2@-1",*
        いい 形容詞,非自立可能,*,*,形容詞,連体形-一般,ヨイ,良い,いい,イー,いい,イー,和,*,*,*,*,イイ,イイ,イイ,イイ,*,*,1,C3,*
        天気 名詞,普通名詞,一般,*,*,*,テンキ,天気,天気,テンキ,天気,テンキ,漢,*,*,*,*,テンキ,テンキ,テンキ,テンキ,*,*,1,C1,*
        でし 助動詞,*,*,*,助動詞-デス,連用形-一般,デス,です,でし,デシ,です,デス,和,*,*,*,*,デシ,デス,デシ,デス,*,*,*,"形容詞%F2@-1,動詞%F2@0,名詞%F2@1",*
        た 助動詞,*,*,*,助動詞-タ,終止形-一般,タ,た,た,タ,た,タ,和,*,*,*,*,タ,タ,タ,タ,*,*,*,"動詞%F2@1,形容詞%F4@-2",*
        ね 助詞,終助詞,*,*,*,*,ネ,ね,ね,ネ,ね,ネ,和,*,*,*,*,ネ,ネ,ネ,ネ,*,*,*,"動詞%F1,名詞%F1,形容詞%F1",*
        BOS/EOS,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*
        

        上記が形態素解析した結果となる。

        また、実行環境によっては 下記(*2)の文字コードに起因するエラーになるため、下記(*3)を参考に文字コードをUTF8等 に変換後、実行すること。

        • (*2)文字コードに起因するエラー

          $ python ~/gitlocalrep/dsbook/mecab-python3_test.py
          >昨日はいい天気でしたね
          Traceback (most recent call last):
          File "~/gitlocalrep/dsbook/mecab-python3_test.py", line 11, in <module>
              node = mecab.parseToNode(text)
          TypeError: in method 'Tagger_parseToNode', argument 2 of type 'char const *'
          
        • (*3)文字コードをUTF8に変換

          $ LANG=ja_JP.UTF8
          $ nkf -w8 --overwrite ~/gitlocalrep/dsbook/mecab-python3_test.py
          

状態遷移によるタスクを遂行する「SCXML」の概要とインストール

  • 状態遷移の準備

    状態遷移とは、状態遷移ベースまたは、ネットワーク方式とも呼ばれ、天気情報案内を例にすると場所日付など、天気情報を取得する(絞込む)ための条件を対話で聞き出し、次の要求状態へと遷移させ、これを繰返し業務遂行する手法のこと。

    状態遷移ベースは、タスク指向型対話システムの遂行手法としては、最もシンプルだが、情報を一つ一つ聞き出すといったシステム主導型の対話になる。 一問一答でユーザーを問い詰めるような遂行ではなく、一度に複数の情報を受け付けるフレームベースという遂行方法もあり、この詳細については次の記事以降で扱う。

    また、それぞれの状態遷移や受け付ける動作、組合わせなどの情報を表現するモデルのことを有限状態オートマトン(有限状態機械)といい、このモデルを状態遷移させてタスクを遂行する。

    有限状態オートマトンの詳細には深く触れないが、状態設計をすべてコードで表すと複雑になりやすい。そこで、有限状態オートマトンを記述するためのマークアップ言語であるSCXML(State Chart XML)を用いて状態遷移を表現する。

    • SCXMLのインストール(PySide2)
      PythonでGUI作成のために用いられる Qtライブラリの処理系であるQt for Python(PySide2)のQScxmlStateMachineという 有限状態オートマトンを表現するクラスを使用。

      PySide2をインストール(ver.2-5.15.0)

      $ source /var/www/vops/bin/activate # 仮想環境起動
      $ pip3.6 install PySide2 # PySide2をインストール
      

      上記でPythonから SCXML を使えるようになった。

      ここでは、次に示す SCXML 各要素の解説に留め、次の記事以降でPythonから呼び出す実装サンプルを確認。

    • 天気情報案内の状態遷移図(SCXML)
      以下、SCXML で記載した天気情報案内の状態遷移図。

      states.scxml

      <?xml version="1.0" encoding="UTF-8"?>
      <scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="ask_place">
        <state id="ask_place">
          <transition event="place" target="ask_date"/>
        </state>
        <state id="ask_date">
          <transition event="date" target="ask_type"/>
        </state>
        <state id="ask_type">
          <transition event="type" target="tell_info"/>
        </state>
        <final id="tell_info"/>
      </scxml>
      

    state要素は通常の状態、final要素は状態機械の終了を示す最終状態を表す。状態から別の状態へ移る規則はtransition要素で定義する。

    transitioneventには、アプリケーション側から状態機械へ送るイベント名を指定する。SCXML自体が「福岡県福岡市」などの自然言語を判定するわけではない。アプリケーションが発話から地名を抽出できた場合にplaceイベントを送信すると、targetに指定したask_dateへ遷移する。

    アプリケーションが対応するイベントを送らなければ遷移は発生せず、現在の状態に留まる。

    上記の要領でask_place(地名指定)→ ask_date(日時指定)→ ask_type(種別:天気 or 気温)と状態遷移が進むと、最後にfinal要素の天気情報の取得結果を返す状態に遷移し、天気情報を返して処理を終了する。

    以上でMeCabSCXMLの環境準備が完了。

まとめ

  • 状態遷移ベースは、現在の状態と入力に応じて次の処理を決める方式。
  • MeCabは日本語発話を単語に分割するために使う。
  • SCXMLは対話状態と遷移条件を表現するために使う。

参考文献

この記事を共有
Xで共有 Facebookで共有 LINEで共有



Copyright SIGMA-SE All Rights Reserved.
s-hama@sigma-se.jp