Wie funktionieren Markov Chain Chatbots?

73

Ich habe darüber nachgedacht, einen Chatbot mit Markov-Ketten zu erstellen, bin mir aber nicht ganz sicher, wie ich ihn zum Laufen bringen soll. Soweit ich weiß, erstellen Sie eine Tabelle aus Daten mit einem bestimmten Wort und den folgenden Wörtern. Ist es möglich, während des Trainings des Bots irgendeine Wahrscheinlichkeit oder einen Zähler anzuhängen? Ist das überhaupt eine gute Idee?

Der zweite Teil des Problems betrifft Schlüsselwörter. Angenommen, ich kann Schlüsselwörter bereits anhand von Benutzereingaben identifizieren. Wie generiere ich einen Satz, der dieses Schlüsselwort verwendet? Ich möchte den Satz nicht immer mit dem Schlüsselwort beginnen. Wie setze ich also die Markov-Kette?

Jordanien
quelle
1
Tabellarische 2D-Daten sind für Artifical Intelligence nicht wirklich nützlich, ein Diagramm wäre viel vorteilhafter. Um die folgenden Wörter zu erhalten, ist Bayesian Network die beste Lösung. Um Sätze zu bilden, ist Sprachverarbeitung erforderlich, und Sie können dies nicht mit grundlegender Logik (wie Markov-Ketten)
tun
2
Mit Markov-Ketten geht das nicht? Es gibt einige Bots, die Markov-Ketten verwenden, obwohl sie wirklich nur Sätze zusammensetzen, machen sie wohl nicht immer Sinn.
Jordanien
Sie können, aber keine Sprachverarbeitung. Ich finde nur den wahrscheinlichsten Satz heraus.
AbiusX
@AbiusX: Was meinst du mit "nur den wahrscheinlichsten Satz herausfinden"? Was würde mir so etwas wie ein Bayes'sches Netzwerk geben, was Markov-Ketten nicht würden? Was würde ich verarbeiten? Sind Markov-Ketten nicht wie Bayes'sche Netzwerke? Ich meine, Sie haben es immer noch mit Wahrscheinlichkeiten und so etwas wie einem gerichteten Graphen zu tun, es wird stattdessen nur in einer Tabelle gespeichert. Bei jedem Wort wählen Sie immer noch das nächste Wort aus, das mit einer bestimmten Wahrscheinlichkeit folgt, nicht wahr? Was ist der Unterschied? Und könnte ich mit Markov-Ketten beginnen und zusätzliche Logik hinzufügen? Irgendwelche Vorschläge? Vielen Dank!
Jordanien
1
@ Jordan: AI ist ein breites Thema. Ich habe einmal einen Chatbot mit Bayesian Nets, Semantic Webs und einigen kreativen Ideen gemacht, was sich gut anhörte. Wenn Sie nicht viel KI wissen, bleiben Sie bei kreativen Ideen. Ein Bayesianisches Netz würde Ihren Bot dazu bringen, Dinge wie "Bist du Peruel?" Zu sagen. Das ist kein korrekter Satz, aber Sie fühlen sich schlau! (Wenden Sie Bayes'sche Netze auf Buchstabenauswahl in Wörtern an, um neue Wörter zu erstellen.
Dies

Antworten:

139

Ich habe vor ein paar Jahren einen Markov-Ketten-Chatbot für IRC in Python erstellt und kann etwas Licht ins Dunkel bringen, wie ich es gemacht habe. Der generierte Text macht nicht unbedingt Sinn, aber es kann wirklich Spaß machen, ihn zu lesen. Lassen Sie es uns in Schritten zerlegen. Angenommen, Sie haben eine feste Eingabe, eine Textdatei (Sie können Eingaben aus Chat-Text oder Texten verwenden oder einfach Ihre Fantasie verwenden).

Durchlaufen Sie den Text und erstellen Sie ein Wörterbuch, dh einen Schlüsselwertcontainer. Und setzen Sie alle Wortpaare als Schlüssel und das folgende Wort als Wert. Zum Beispiel: Wenn Sie einen Text "abcab k" haben, beginnen Sie mit "ab" als Schlüssel und "c" als Wert, dann "bc" und "a" als Wert ... der Wert sollte eine Liste oder eine Sammlung sein 0..Viele 'Elemente', da Sie für ein bestimmtes Wortpaar mehr als einen Wert haben können. Im obigen Beispiel haben Sie zweimal "a b", gefolgt von "c" und am Ende von "k". Am Ende haben Sie also ein Wörterbuch / einen Hash, der wie folgt aussieht:{'a b': ['c','k'], 'b c': ['a'], 'c a': ['b']}

Jetzt haben Sie die erforderliche Struktur zum Erstellen Ihres funky Textes. Sie können wählen, ob Sie mit einem zufälligen Schlüssel oder einem festen Ort beginnen möchten! Wenn wir also die Struktur haben, die wir haben, können wir beginnen, indem wir "ab" speichern und dann zufällig ein folgendes Wort aus dem Wert c oder k nehmen, also das erste Speichern in der Schleife "ab k" (wenn "k" der gewählte zufällige Wert war ) Dann fahren Sie fort, indem Sie einen Schritt nach rechts bewegen, der in unserem Fall "bk" ist, und einen zufälligen Wert für dieses Paar speichern, wenn Sie in unserem Fall nein haben, damit Sie aus der Schleife ausbrechen (oder Sie können andere Dinge entscheiden wie von vorne anfangen). Wenn die Schleife fertig ist, drucken Sie Ihre gespeicherte Textzeichenfolge.

Je größer die Eingabe, desto mehr Werte haben Sie für Ihre Schlüssel (Wortpaar) und dann einen "intelligenteren Bot", damit Sie Ihren Bot "trainieren" können, indem Sie mehr Text hinzufügen (möglicherweise Chat-Eingabe?). Wenn Sie ein Buch als Eingabe haben, können Sie einige schöne zufällige Sätze konstruieren. Bitte beachten Sie, dass Sie nicht nur ein Wort, das einem Paar folgt, als Wert verwenden müssen, sondern 2 oder 10. Der Unterschied besteht darin, dass Ihr Text genauer erscheint, wenn Sie "längere" Bausteine ​​verwenden. Beginnen Sie mit einem Paar als Schlüssel und dem folgenden Wort als Wert.

Sie sehen also, dass Sie grundsätzlich zwei Schritte ausführen können: Erstellen Sie zunächst eine Struktur, in der Sie zunächst zufällig einen Schlüssel auswählen, nehmen Sie dann diesen Schlüssel, drucken Sie einen zufälligen Wert dieses Schlüssels und fahren Sie fort, bis Sie keinen Wert oder eine andere Bedingung mehr haben. Wenn Sie möchten, können Sie ein Wortpaar aus einer Chat-Eingabe aus Ihrer Schlüsselwertstruktur "säen", um einen Anfang zu haben. Es liegt in Ihrer Fantasie, wie Sie Ihre Kette starten.

Beispiel mit echten Worten:

"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"]

......

Erstellen Sie nun eine Schleife:

Wählen Sie einen zufälligen Schlüssel, sagen Sie "Hallo mein" und wählen Sie zufällig einen Wert, nur einen hier, also seinen "Namen" (SPEICHERN von "Hallo mein Name") . Gehen Sie
nun einen Schritt nach rechts und nehmen Sie "Mein Name" als nächsten Schlüssel und wählen Sie einen zufälligen Wert ... "ist" (SPEICHERN "Hallo, mein Name ist") .
Bewegen Sie sich jetzt und nehmen Sie "Name ist" ... "Al" (SPEICHERN "Hallo, mein Name ist AL") .
Nehmen Sie nun "ist Al" ... "und" (SPAREN SIE "Hallo, mein Name ist Al und") .

...

Wenn Sie zu "und i" kommen, wählen Sie zufällig einen Wert aus, sagen wir "können", dann wird das Wort "ich kann" gemacht usw. Wenn Sie zu Ihrem Stoppzustand kommen oder wenn Sie keine Werte haben, drucken Sie den konstruierten Wert Zeichenfolge in unserem Fall:

"Hallo, mein Name ist Al und ich kann dort leben, solange ich will."

Wenn Sie mehr Werte haben, können Sie zu beliebigen Tasten springen. Je mehr Werte Sie haben, desto mehr Kombinationen haben Sie und desto zufälliger und unterhaltsamer wird der Text.

Nocker
quelle
1
Wenn Sie Chat-Text als Eingabe verwenden, müssen Sie viel haben, um den Bot "intelligent" zu machen. Wenn eine Person den Bot-Namen erwähnt, wurde eine Antwort ausgelöst. Ich nahm die gesamte geschriebene Zeichenfolge und überprüfte zuerst, wer sie geschrieben hatte, und begann meine Antwort mit diesem Namen, wie "Jordan: bla bla". Dann wählte ich ein Wortpaar aus dieser Zeichenfolge und begann dort. Ich könnte auch zwei Sätze mit dem zweiten Anfang mit "und (zufälliges Wort)" bilden. Ich habe auch zufällig ausgewählt, wie lange meine Antwort war, vielleicht 5-50 Wörter. Ich hatte auch mehr als ein "Gehirn" mit mehr Strukturen, mit denen ich spielen konnte. Ein Gehirn ist im Grunde nur eine Textdatei.
Nocker
1
Ich habe vergessen zu sagen, dass es schwierig sein kann, wenn Sie Chat-Eingaben verwenden, da die Leute dazu neigen, viele Rechtschreibfehler und Verknüpfungen zu machen. Dann wird Ihr Bot so sein. Sie können sich auch mit der Verarbeitung natürlicher Sprache befassen, wenn Sie Zeit haben. Hier ist etwas in Python- Link
Nocker
Wenn Sie die Quelle noch irgendwo haben, werfen Sie sie auf Github.
user1943442
Ich habe so etwas gemacht, bei dem ich einen Programm-Scan über Oliver Twist durchgeführt habe und jede einzelne 4-Wort-Chunk-Kombination und deren Häufigkeit extrahiert habe. Es hat ewig gedauert, die Frequenzkarte zu generieren und nur Müllstrings mit nahezu bedeutungslosem Text auszugeben. Ich wünschte, ich wäre damals neu in dieser Methode!
Carcigenicate
1
Ich denke, hier fehlt ein Teil, da Markov-Ketten Entscheidungen auf der Grundlage von Wahrscheinlichkeiten treffen. Wenn es also um das "und i" geht, sollte das System in der Lage sein, die gesamte Zeichenfolge (nicht nur das letzte Schlüsselpaar) bis neu zu bewerten dort, um das nächste Wort zu bestimmen. Das System sollte Ihnen sagen, dass "live" das nächste sein sollte, aber nicht zufällig.
Juan Zamora
9

Der Bot wählt ein zufälliges Wort aus Ihrer Eingabe aus und generiert eine Antwort, indem er ein anderes zufälliges Wort auswählt, das als Nachfolger seines gehaltenen Wortes angesehen wurde. Es wiederholt dann den Vorgang, indem es nacheinander einen Nachfolger für dieses Wort findet und iterativ weitermacht, bis es denkt, dass es genug gesagt ist. Zu dieser Schlussfolgerung gelangt man zu einem Wort, das vor einem Satzzeichen im Trainingstext stand. Anschließend kehrt es wieder in den Eingabemodus zurück, damit Sie antworten können, und so weiter.

Es ist nicht sehr realistisch, aber ich fordere hiermit jeden auf, es in 71 Codezeilen besser zu machen !! Dies ist eine große Herausforderung für angehende Pythonisten, und ich wünschte nur, ich könnte die Herausforderung einem breiteren Publikum zugänglich machen als der geringen Anzahl von Besuchern, die ich in diesem Blog bekomme. Um einen Bot zu codieren, von dem immer garantiert wird, dass er grammatikalisch ist, muss er sicherlich näher an mehreren hundert Zeilen liegen. Ich habe es enorm vereinfacht, indem ich nur versucht habe, an die einfachste Regel zu denken, um dem Computer einen Stich zu geben, etwas zu sagen.

Die Antworten sind gelinde gesagt eher impressionistisch! Außerdem müssen Sie das, was Sie sagen, in einfache Anführungszeichen setzen.

Ich habe Krieg und Frieden für meinen „Korpus“ verwendet, der einige Stunden für den Trainingslauf gedauert hat. Verwenden Sie eine kürzere Datei, wenn Sie ungeduldig sind.

Hier ist der Trainer

#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()

Hier ist der Bot:

#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

Sie neigen dazu, ein unheimliches Gefühl zu bekommen, wenn es etwas sagt, das teilweise sinnvoll erscheint.

user3513316
quelle
Was ist der Code der Methode raw_input (...)?
user2994783
0

Sie könnten Folgendes tun: Erstellen Sie einen Markov-Kettengenerator für Bestellung 1, indem Sie Wörter und keine Buchstaben verwenden. Jedes Mal, wenn jemand etwas veröffentlicht, wird das, was er gepostet hat, zur Bot-Datenbank hinzugefügt. Außerdem würde Bot sparen, wenn er zum Chatten ging und wenn ein Typ den ersten Beitrag veröffentlichte (in Vielfachen von 10 Sekunden), dann würde er die Zeit sparen, die derselbe Typ darauf wartete, erneut zu posten (in Vielfachen von 10 Sekunden) ... Dieser zweite Teil wird verwendet, um zu sehen, wann der Typ etwas veröffentlicht, also nimmt er am Chat teil und nach einiger Zeit basierend auf einer Tabelle mit "Nach wie vielen 10 Sekunden hat der Typ nach dem Beitritt zum Chat gepostet", dann würde er fortfahren mit derselben Tabelle posten und darüber nachdenken, "wie viel Zeit wurde zum Schreiben des Posts verwendet, der nach einem Post gepostet wurde, über den er X Sekunden lang nachgedacht und geschrieben hat".

guestrt
quelle