top of page

「はい・いいえ判断」を考えてみる

執筆者の写真: snackvirtualsnackvirtual

これからもっとも単純な「はい・いいえ判断」を考えてみる


入力文そのものを「はい・いいえ辞書」と比較する

これは一番単純なやり方だ


入力文を形態素解析したものを「はい・いいえ辞書」と比較する

形態素解析をすると基本形がわかるので、語尾が変化しても一致をとれる反面、

文が細切れになるので一致を取りづらい

よってこの2つの比較を用いることにする

形態素解析で一致が得られた場合、これを優先することにする


「はい・いいえ辞書」と一致したものが感動詞の場合、重みづけを軽くし、二重否定から除くことにする

感動詞は相槌程度の重要性である場合があり、これを二重否定の要素にするのは誤りになる

(例:「ううん、そうじゃないよ」だと、ううん=否定、そうじゃない=否定で二重否定と判断するのは誤り)

また「うん、違うよ」のように相槌程度の重要性の場合が多いため、感嘆詞の場合には思い付けを0.3とし、ほかの文の結果に加算することにする


「はい・いいえ辞書」は文字の長さを長い順にSortして、誤認識を排除する

「うん」は「ううん」に含まれてしまうため、「うん」を先に一致されると誤認識となる


「はい・いいえ辞書」



















yesno_judge.py

# はい・いいえ判別
# 
import mecab_sub
import csv

# CSVファイルのパスを指定
csv_path = './HIDEO_AI/YesNo.csv'

# 空の配列を作成
yesno_array = []

# CSVファイルを読み込む
with open(csv_path, 'r') as csvfile:
    reader = csv.reader(csvfile)
    for row in reader:
        yesno_array.append(row)

# 文字の長い順にソートすることで誤った短い単語で検出するのを防ぐ
yesno_array.sort(key=len, reverse=True)


# 配列に格納されたデータを表示
# for i in yesno_array:
#     print(i)



# はい・いいえ判別
# 検索して合致した単語は、その単語をアンダースコアーに変換し、次の検索に当たらないようにする
# 直接検索と形態素分解したものの検索の両方を実行し、形態素検索が検出できなければ、直接検索を採用する
# 形態素分析で、検索結果が感動詞の場合には、0.3の重みづけをして加算する
# (感動詞はそれ自体が会話の流れでYes/Noをどちらでもとれてしまうため、重要度を0.3程度に下げる)
# 形態素分析で、検索結果が感動詞ではない場合、乗算をする
# (感動詞ではないものが複数あった場合、二重否定と考えて乗算する)
# はい・いいえは 0より大きいか小さいかで判定。0はどちらでもないという判定とする
def yesno_detect(input_word):

    yesno1 = 0
    copied_word = input_word
    for i in range(1,len(yesno_array)):
        if yesno_array[i][1] in copied_word:
            if yesno1 == 0:
                yesno1 = float(yesno_array[i][2])
            else:
                yesno1 = yesno1 * float(yesno_array[i][2])

            copied_word.replace(yesno_array[i][1],"_")

    yesno2 = 0
    result = mecab_sub.mecab_matrix(input_word)

    for j in range(0,len(result)):
        for i in range(1,len(yesno_array)):
            if yesno_array[i][1] in result[j][7]:
                if "感動詞" in result[j][1]: 
                    yesno2 = yesno2 + float(yesno_array[i][2]) * 0.3
                elif yesno2 == 0:
                    yesno2 = float(yesno_array[i][2])
                elif yesno2 >= 1 or yesno2 <= -1:
                    yesno2 = yesno2 * float(yesno_array[i][2])  # 二重否定
                else:
                    yesno2 = yesno2 + float(yesno_array[i][2])

                break

    if yesno2 == 0:
        yesno = yesno1
    else:
        yesno = yesno2

    return yesno        


if __name__ == '__main__':
    while True:
        user_input = input("入力してください: ")  
        result = yesno_detect(user_input)
        print(f"{user_input}   yes/no = {result}")

Mecab_sub.py

import sys
import MeCab


# Mecabを用いて、形態素解析した結果を、二次元配列にして出力する
def mecab_matrix(text):

    text = text + "「」"    # 文中に制約がひとつもないとちゃんと動かないっぽいので、ダミーとして挿入
    text = text.replace("「","\n")
    text = text.replace("」","\t*\n")

    m = MeCab.Tagger('-Ochasen -p')

    node = m.parseToNode(text)
    node = node.next # 最初はいらないので、除去

    results = []
    while node:
        word = []
        word.append(node.surface)  # 表層を追記
        word.extend(node.feature.split(","))  # 素性もカンマでsplitして、追記
        results.append(word)
        node = node.next

    results.pop() # 最後はいらないので、除去

    return results

この「はい・いいえ判別」前後の意味などは考えていないため、完璧な判定はできないが

それなりに使えるレベルだと考えられる


判定は >0で肯定、<0で否定、0はその他


うん、そうだね   yes/no = 0.3
正しいよ   yes/no = 1.0
ダメ、違うよ   yes/no = 1.0
あってる   yes/no = 0
いいね   yes/no = 1.0
それで正解だよ   yes/no = 1.0
うん、それは違う   yes/no = -0.7
だめだあ   yes/no = -1.0

赤字の部分は誤認識である

二重否定はもう少し技が必要かもしれない



閲覧数:0回0件のコメント

最新記事

すべて表示

Comments


bottom of page