FUORI DALLA ZANZARIERA

サイト受付AI
    

STEP2

応答文を教えて、覚えさせる

前回は、簡単な応答をするプログラムを作りました。
今回は少し手を加えて辞書にない言葉を教えたら辞書を更新する改造を実装します。

前回のプログラムに辞書を更新する処理を追加します。

▼front_desk_ai.py

            '''
            サイト受付API STEP2 応答文を教えて、覚えさせる
            '''

            # 辞書クラスをインポートする
            from front_desk_ai_dict import frontDeskAiDict

            # 辞書クラスをインスタンス化する
            bot_dict_class = frontDeskAiDict()
            # 辞書情報を格納する
            bot_dict = bot_dict_class.readDict()
            # サイト受付入力メッセージを格納する
            input_message = bot_dict_class.front_desk_ai_def_req_message
            # サイト受付AIの名前を格納する
            ai_name = bot_dict_class.front_desk_ai_name
            # サイト受付共通メッセージリストを格納する
            common_message_list = bot_dict_class.front_desk_ai_def_res_message_list
            # サイト受付処理終了メッセージを格納する
            end_message = bot_dict_class.front_desk_ai_def_end_message

            # サイト受付処理終了メッセージが入力されたら処理を終了する
            while True:
                # 入力された情報を変数に格納する
                command = input(input_message)

                # 応答メッセージを初期化する
                responseMessage,responseMessage2 = "",""

                # 辞書クラスの辞書1にキーが含まれているかチェック
                for param_key in bot_dict:
                    # 入力された情報と辞書1のキーが一致した場合に辞書1から紐づく値を取得する
                    if param_key in command:
                        responseMessage = bot_dict[param_key]
                        break

                # 辞書に含まれていない文字の指定の場合は、問い返す
                if not responseMessage:
                    responseMessage = ai_name + command + common_message_list[0]
                    responseMessage2 = ai_name + common_message_list[1]
                # 辞書に含まれている文字の指定の場合は、紐づく応答メッセージを返却する
                else:
                    responseMessage = ai_name + responseMessage

                # 応答メッセージを表示する
                print(responseMessage)

                # 応答メッセージ2があれば表示する
                if responseMessage2 != "":
                    print(responseMessage2)

                    # 追加で入力を受け付ける
                    re_command = input(input_message)

                    # 追加入力を最初の入力内容の応答文として登録するメッセージを回答する
                    # 応答メッセージリストを初期化する
                    responseMessageRegi = []
                    # 共通メッセージリストから応答メッセージリストを生成する
                    responseMessageRegi.append(ai_name + command + common_message_list[2])
                    responseMessageRegi.append(ai_name + re_command + common_message_list[3])
                    responseMessageRegi.append(ai_name + common_message_list[4])
                    # 複数の応答メッセージをループで表示する
                    for resMesRegi in responseMessageRegi:
                        print(resMesRegi)

                    # 覚えた応答を辞書ファイルに登録する
                    bot_dict_class.registDict(command, re_command)
                    # 覚えた応答を辞書配列に登録する
                    bot_dict[command] = re_command

                # サイト受付処理終了メッセージを受け取った場合は、ループを抜ける
                if end_message in command:
                    break
          

辞書クラスを読み込んでインスタンス化します。
生成したオブジェクトから受付AIの情報を取得します。

▼front_desk_ai_dict.py

            '''
            辞書クラス
            '''
            
            class frontDeskAiDict(object):
                '''
                サイト受付の応答する辞書を管理するクラス
                '''
            
                def __init__(self):
            
                    # 辞書ファイルパスを設定する
                    self.dict_file_path = 'dict.dat'
            
                    # サイト受付AIに使う辞書以外のパラメータ
                    self.front_desk_ai_def_req_message = '発言を入力> '
                    self.front_desk_ai_name = 'リヨぐだ子> '
                    self.front_desk_ai_def_res_message_list = [
                        'とは何ですか?',
                        '返答する内容を教えて下さい。',
                        'と聞かれたら、',
                        'と返すのですね。',
                        '学習しました。'
                    ]
                    self.front_desk_ai_def_end_message = 'さようなら'
            
                    # 辞書配列を初期化する
                    self.front_desk_ai_dict_1 = {}
            
                def registDict(self, reqMessage, resMessage):
            
                    # ファイルに追記する内容を生成する
                    addTextLine = reqMessage + ':' + resMessage
            
                    # 辞書ファイルに教えられた言葉を追加する
                    with open(self.dict_file_path, 'a', encoding="utf-8_sig") as fileObj:
                        print(addTextLine, file=fileObj)
            
            
                def readDict(self):
            
                    # 辞書ファイルを読み込む
                    with open(self.dict_file_path, 'r', encoding="utf-8_sig") as fileObj:
                        all_dict_data = fileObj.read()
            
                    # 行ごとに格納した配列を作成
                    line_list = all_dict_data.splitlines()
                    # 配列情報を1行ずつ読み込んで、リクエストとレスポンスに分けて辞書情報に登録する
                    for line in line_list:
                        reqMessage,resMessage = line.split(':')
                        self.front_desk_ai_dict_1[reqMessage] = resMessage
                    # 加工した辞書情報を返却する
                    return self.front_desk_ai_dict_1
          

辞書クラスには。辞書ファイルを読み込むメソッドと書き込むメソッドを実装します。
辞書ファイルに読み書きすることで一度学習した質問に回答できるようにします。


            # 辞書に含まれていない文字の指定の場合は、問い返す
            if not responseMessage:
                responseMessage = ai_name + command + common_message_list[0]
                responseMessage2 = ai_name + common_message_list[1]
            # 辞書に含まれている文字の指定の場合は、紐づく応答メッセージを返却する
            else:
                responseMessage = ai_name + responseMessage
          

辞書に含まれていない文字が入力された場合は、応答メッセージを別変数に格納します。


            # 応答メッセージ2があれば表示する
            if responseMessage2 != "":
                print(responseMessage2)

                # 追加で入力を受け付ける
                re_command = input(input_message)

                # 追加入力を最初の入力内容の応答文として登録するメッセージを回答する
                # 応答メッセージリストを初期化する
                responseMessageRegi = []
                # 共通メッセージリストから応答メッセージリストを生成する
                responseMessageRegi.append(ai_name + command + common_message_list[2])
                responseMessageRegi.append(ai_name + re_command + common_message_list[3])
                responseMessageRegi.append(ai_name + common_message_list[4])
                # 複数の応答メッセージをループで表示する
                for resMesRegi in responseMessageRegi:
                    print(resMesRegi)

                # 覚えた応答を辞書ファイルに登録する
                bot_dict_class.registDict(command, re_command)
                # 覚えた応答を辞書配列に登録する
                bot_dict[command] = re_command
          

応答メッセージ2がある場合=辞書に含まれていない文字が入力されたと判断し、
追加の入力を受け付けるようにします。
応答メッセージは複数文のためリスト型で定義して、返答メッセージを格納していきます。
辞書クラスの辞書ファイル登録メソッドを呼び出して入力メッセージと応答メッセージの 組み合わせで登録します。


            def registDict(self, reqMessage, resMessage):
            
            # ファイルに追記する内容を生成する
            addTextLine = reqMessage + ':' + resMessage
    
            # 辞書ファイルに教えられた言葉を追加する
            with open(self.dict_file_path, 'a', encoding="utf-8_sig") as fileObj:
                print(addTextLine, file=fileObj)
          

辞書クラスの登録メソッドは、入力メッセージと応答メッセージは区切り文字「:」を間に追加して文字列として結合します。
結合した文字列を辞書ファイルに追記で登録します。


            def readDict(self):
        
                # 辞書ファイルを読み込む
                with open(self.dict_file_path, 'r', encoding="utf-8_sig") as fileObj:
                    all_dict_data = fileObj.read()
        
                # 行ごとに格納した配列を作成
                line_list = all_dict_data.splitlines()
                # 配列情報を1行ずつ読み込んで、リクエストとレスポンスに分けて辞書情報に登録する
                for line in line_list:
                    reqMessage,resMessage = line.split(':')
                    self.front_desk_ai_dict_1[reqMessage] = resMessage
                # 加工した辞書情報を返却する
                return self.front_desk_ai_dict_1
          

辞書クラスの辞書情報読み込みメソッドは辞書ファイルを読み込んだ後で、
区切り文字「:」で分割した結果をそれぞれの変数に格納します。 辞書クラスの辞書配列に格納して結果を返却します。

実際に上記のコードを実行すると以下の画像のように教えたワードを辞書に登録し、
次回の応答時には覚えたメッセージを返すようになります。

コンソール画面

辞書ファイルにも入力メッセージと応答メッセージの組み合わせが登録されています。

コンソール画面

辞書にない言葉でも教えれば次からは回答してくれるようになりました。少しAIっぽくなってきましたね。
昔、個人サイトで人工無能チャットとして見かけたものの仕組みは、大体これと同じものだと思います。
一人で言葉を教えるのは大変なので、次回はこのプログラムをWEB公開する仕組みを考えます。
次回も楽しみに待っていただければ、幸いです。