これからもっとも単純な「はい・いいえ判断」を考えてみる
入力文そのものを「はい・いいえ辞書」と比較する
これは一番単純なやり方だ
入力文を形態素解析したものを「はい・いいえ辞書」と比較する
形態素解析をすると基本形がわかるので、語尾が変化しても一致をとれる反面、
文が細切れになるので一致を取りづらい
よってこの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
赤字の部分は誤認識である
二重否定はもう少し技が必要かもしれない
Comments