web-dev-qa-db-ja.com

マルコフチェーンチャットボットの仕組み

マルコフチェーンのようなものを使用してチャットボットを作成することを考えていましたが、それを機能させる方法が完全にはわかりません。私が理解していることから、あなたは与えられたWordとそれに続く単語でデータからテーブルを作成します。ボットのトレーニング中に、あらゆる種類の確率またはカウンターを付加することは可能ですか?それもいい考えですか?

問題の2番目の部分はキーワードに関するものです。ユーザー入力からキーワードを既に識別できると仮定すると、そのキーワードを使用する文を生成するにはどうすればよいですか?私はいつもキーワードで文を始めたいとは思わないので、どうすればマルコフ連鎖に種をdoくことができますか?

70
Jordan

IRC in Python数年前にPython $ ===でMarkovチェーンチャットボットを作成しました。意味はありますが、読むのは本当に楽しいです。ステップごとに分解しましょう。固定入力、テキストファイルがあると仮定します(チャットテキストまたは歌詞からの入力を使用するか、想像力を使用することができます)

テキストをループして、キーと値のコンテナーを意味する辞書を作成します。そして、すべての単語のペアをキーとして、次の単語を値として入力します。たとえば、「abcabk」というテキストがあり、キーとして「ab」、値として「c」で始まり、値として「bc」と「a」で始まる場合、値は0を保持するリストまたはコレクションである必要があります..多くの「アイテム」。指定された単語のペアに対して複数の値を持つことができます。上記の例では、 "a b"が2回続き、最初に "c"が続き、最後に "k"が続きます。したがって、最終的には次のような辞書/ハッシュが得られます:{'a b': ['c','k'], 'b c': ['a'], 'c a': ['b']}

これで、ファンキーなテキストを作成するために必要な構造ができました。ランダムなキーまたは固定された場所から開始することを選択できます!したがって、「ab」を保存することから始めて、値cまたはkから次のWordをランダムに取得することで開始できる構造を考えると、ループの最初の保存「abk」(「k」が選択されたランダム値の場合)次に、右に1ステップ移動します。この場合は「bk」で、そのペアのランダムな値を保存します(この場合はnoなので、ループを抜けます(または、他のようなものを決めることができます)最初からやり直す)。ループが完了すると、保存したテキスト文字列を印刷します。

入力が大きければ大きいほど、キー(単語のペア)の値が多くなり、「スマートボット」になりますので、テキストを追加することでボットを「トレーニング」できます(おそらくチャット入力?)。入力として本がある場合は、いくつかの素敵なランダムな文章を構築できます。値としてペアに続くWordを1つだけとる必要はなく、2または10をとることができることに注意してください。違いは、「長い」ビルディングブロックを使用すると、テキストがより正確に表示されることです。ペアをキーとして、次のワードを値として開始します。

つまり、基本的に2つのステップがあり、最初にランダムにキーを選択する構造を作成してから、そのキーを取得してそのキーのランダムな値を出力し、値または他の条件がなくなるまで続けます。必要に応じて、キーバリュー構造からのチャット入力から単語のペアを「シード」して開始することができます。それはあなたの想像力次第であなたのチェーンを始める方法です。

実際の単語を使用した例:

"hi my name is Al and i live in a box that i like very much and i can live in there as long as i want"

"hi my" -> ["name"]

"my name" -> ["is"]

"name is" -> ["Al"]

"is Al" -> ["and"]

........

"and i" -> ["live", "can"]

........

"i can" -> ["live"]

......

ループを作成します。

ランダムキーを選択し、「こんにちは」と言い、値をランダムに選択します。ここでは1つだけなので、「名前」(SAVING "こんにちは私の名前")です。
次に、「マイネーム」を次のキーとして右に1ステップ移動し、ランダムな値を選択します...「is」(SAVING "hi my name is")
移動して「名前は」...「Al」になります(SAVING "hi my name is AL")
今、「is Al」...「and」を取ります(SAVING "こんにちは、私の名前はAl and")

...

「and i」に来たら、ランダムに値を選択し、「can」と発声します。その後、「i can」という単語が作成されます。停止条件になったとき、または構築された値を出力しないとき私たちの場合の文字列:

「こんにちは、私の名前はAlで、私が望む限りそこに住むことができます」

さらに値がある場合は、任意のキーにジャンプできます。値が多いほど組み合わせが多くなり、テキストがよりランダムで楽しいものになります。

137
Nocker

ボットは、入力からランダムなWordを選択し、その保持されたWordの後継であると見なされた別のランダムなWordを選択して応答を生成します。その後、そのWordの後継者を順番に見つけて、十分に言われたと思うまで繰り返し実行することで、プロセスを繰り返します。トレーニングテキスト内の句読点の前にあるWordで停止することにより、その結論に達します。その後、再び入力モードに戻り、応答できるようになります。

あまり現実的ではありませんが、71行のコードでより良い結果を出すよう、誰にでも挑戦します!!これは、新進のパイオニストにとって大きな挑戦であり、このブログにアクセスする少数の訪問者よりも多くの聴衆に挑戦を広げられることを望みます。常に文法的であることが保証されているボットをコーディングするには、確実に数百行に近づける必要があります。コンピューターに言いたいことを突き刺すだけの簡単なルールを考えて、私は非常に単純化しました。

その反応は控えめに言ってもかなり印象派です!また、あなたが言うことを一重引用符で囲む必要があります。

私は「コーパス」に戦争と平和を使いました。これはトレーニングの実行に数時間かかりました。もしあなたがせっかちだったらもっと短いファイルを使ってください…

こちらがトレーナーです

#lukebot-trainer.py
import pickle
b=open('war&peace.txt')
text=[]
for line in b:
    for Word in line.split():
        text.append (Word)
b.close()
textset=list(set(text))
follow={}
for l in range(len(textset)):
    working=[]
    check=textset[l]
    for w in range(len(text)-1):
        if check==text[w] and text[w][-1] not in '(),.?!':
            working.append(str(text[w+1]))
    follow[check]=working
a=open('Lexicon-luke','wb')
pickle.dump(follow,a,2)
a.close()

ボットは次のとおりです。

#lukebot.py
import pickle,random
a=open('Lexicon-luke','rb')
successorlist=pickle.load(a)
a.close()
def nextword(a):
    if a in successorlist:
        return random.choice(successorlist[a])
    else:
        return 'the'
speech=''
while speech!='quit':
    speech=raw_input('>')
    s=random.choice(speech.split())
    response=''
    while True:
        neword=nextword(s)
        response+=' '+neword
        s=neword
        if neword[-1] in ',?!.':
            break
    print response

部分的に理にかなっているように見える何かを言うとき、あなたは不気味な感覚を得る傾向があります。

7
user3513316

次のようにできます:文字ではなく単語を使用して、注文1マルコフチェーンジェネレーターを作成します。誰かが何かを投稿するたびに、彼が投稿したものがボットデータベースに追加されます。また、ボットはチャットに行ったとき、および男が最初の投稿を投稿したとき(10秒の倍数)を節約し、この同じ男が再び投稿するのを待っていた時間(10秒の倍数)を節約します...この2番目の部分は、男性がいつ投稿するかを確認するために使用されるため、チャットに参加し、「チャットに参加してから10秒後に投稿した」と表に基づいてしばらくすると、続行します同じテーブルで投稿するには、「考えて書くのにX秒を使った投稿の後に投稿された投稿を書くのにどのくらいの時間を費やしたか」

0
guestrt