【会話入門】会話・学習するアプリが質問にも答えられるように進化した♪

このアプリは進化中で、以下のようなこともできるようになりました♪
以下のように会話と（現在；天気と自転車）質問が連続的にできるようになりました。
今回はこのコードの説明をします。

```
>python auto_QAconversation_.py -d C:\PROGRA~1\mecab\dic\ipadic conversation_.csv  -s stop_words.txt
質問は、天気ですか、ブルべですか、それとも雑談ですか？
> ブルべ
ブルべについての質問は何ですか？
> ブルべって何ですか
(0.59): 知ら ず 知ら ず の うち に とんでも ない 距離 や 山岳 を 走破 し て しまう こと です 。
> ブルべは楽しいですか
(0.95): 楽しい です
>
質問は、天気ですか、ブルべですか、それとも雑談ですか？
> 天気
天気についての質問は何ですか？
> 晴れかどうかはどうしてわかるのですか
(0.42): 全 天 を 覆う 雲 の 量 （ 雲量 ） が ９ 割 以上 の 場合 は 曇り 、 雲量 が ２ 割 から ８ 割 まで の 場合 は 晴れ 、 雲量 が １ 割 以下 の 場合 は 快晴 です 。
>
質問は、天気ですか、ブルべですか、それとも雑談ですか？
> 雑談
雑談しましょう(⋈◍＞◡＜◍)。✧♡
> そうだね、今日は暇だよ
(0.63): そう だ よ ,
> 明日は君とどこか行きたいな
(0.56): どこ 行き たい
> 海行きたいな
(0.59): 行き たい の ,
>
質問は、天気ですか、ブルべですか、それとも雑談ですか？
> 天気
お天気についての質問は何ですか？
> 明日の天気は晴れるかな
(0.47): メール で は 、 天気 予報 の 内容 の 問合せ に対する 回答 は 行っ て おり ませ ん 。 気象庁 ホームページ に 最新 の 予報 を 掲載 し て い ます ので ご 利用 ください 。
>
質問は、天気ですか、ブルべですか、それとも雑談ですか？
```
###やったこと
・csvファイルの読込
・コード説明
###・csvファイルの読込
【参考】
・[PythonでCSVの読み書き](https://qiita.com/okadate/items/c36f4eb9506b358fb608)
Q\tA\n形式でCSVファイルに保存したQAをどうやって読み込もうと考えていたが、今回は、参考の「with文を使わなくても，以下のように読み込める．」という方のコードを利用して以下のように記載した。
※どっちでも良いわけですが

```py
def train_questions(mecab,line):
    questions = []
    answers = []
    if line=="天気":
        f = open('conversation_w.csv', 'r')
    elif line=="ブルべ":
        f = open('conversation_j.csv', 'r')
    reader = csv.reader(f)
    for row in reader:
        questions.append(mecab.parse(row[0]).strip())
        answers.append(mecab.parse(row[1]).strip())
    f.close()    
    return questions, answers
```
###・コード説明
コード全体は以下に置きました
・[something2speak/auto_QAconversation_.py](https://github.com/MuAuan/something2speak/blob/master/auto_QAconversation_.py)
ほぼ、解説の必要ないですね。
これのいいところは、QA型のQAは以下のようにquestions_w,answers_w,vecs_wだけ変えて、
`conversation_QA(questions_w,answers_w,vecs_w,mecab,line)`
で呼び出しているところです。

```py
vectorizer = TfidfVectorizer(token_pattern="(?u)\\b\\w+\\b", stop_words=stop_words)
while True:
    print("質問は、天気ですか、ブルべですか、それとも雑談ですか？")
    line = input("> ")
    if line=="天気":
        questions_w, answers_w = train_questions(mecab,line)
        vecs_w = vectorizer.fit_transform(questions_w)
        conversation_QA(questions_w,answers_w,vecs_w,mecab,line)
    elif line=="ブルべ":
        questions_j, answers_j = train_questions(mecab,line)
        vecs_j = vectorizer.fit_transform(questions_j)
        conversation_QA(questions_j,answers_j,vecs_j,mecab,line)
    elif line=="雑談":
        questions = train_conv(mecab)
        vecs = vectorizer.fit_transform(questions)
        conversation(questions,vecs,mecab,line)
```
呼び出される側は以下のような構造になっています。
QA型の場合は、質問に近いQに対してAを出力しています。
質問が続く限りこの関数内で処理しますが、質問を入力せずにエンターを押すと、先ほどの呼び出し側へ戻ります。

```py
def conversation_QA(questions,answers,vecs,mecab,line):
    print(line+"についての質問は何ですか？")
    line = input("> ")
    with open('conversation_.csv', 'a', newline='') as f: #a+ #w
        writer = csv.writer(f)
        while True:
            writer.writerow({line})
            sims = cosine_similarity(vectorizer.transform([mecab.parse(line)]), vecs)
            index = np.argsort(sims[0])
            index_= index[-1]
            line = answers[index_]
            save_questions(line)
            print("({:.2f}): {}".format(sims[0][index_],answers[index_]))
            text2speak(answers[index_])
            time.sleep(2)
            line = input("> ")
            save_questions(line)
            if not line:
                break
```
※何を保存するかはちょっと整理しないとですね
###結果
上記のとおりであるが、気象庁の回答が長いが、ストレスなく回答やQAと雑談間を行き来出来ている。
入力はテキスト入力だが、一応、音声でも回答できている。
###まとめ
・雑談しながら、複数のQA形式の質問に回答できるようにした
・テキストベースのQAがあれば、自由に追加できる

・やはり、質問を音声にしたいと思う