¿Cómo funcionan los Chatbots de Cadena Markov?


Estaba pensando en crear un chatbot usando algo como markov chains, pero no estoy del todo seguro de cómo hacerlo funcionar. Por lo que entiendo, se crea una tabla a partir de datos con una palabra dada y luego las palabras que siguen. ¿Es posible adjuntar cualquier tipo de probabilidad o contador mientras se entrena al bot? ¿Es una buena idea?

La segunda parte del problema es con las palabras clave. Suponiendo que ya puedo identificar palabras clave a partir de la entrada del usuario, ¿cómo puedo generar una oración que utiliza esa palabra clave? No siempre quiero comenzar la oración con la palabra clave, así que ¿cómo puedo sembrar la cadena de markov?

Author: matsjoyce, 2011-03-15

3 answers

Hice un chatbot Markov chain para IRC en Python hace unos años y puede arrojar algo de luz sobre cómo lo hice. El texto generado no necesariamente tiene sentido, pero puede ser muy divertido de leer. Vamos a dividirlo en pasos. Suponiendo que tiene una entrada fija, un archivo de texto, (puede usar la entrada del texto del chat o la letra o simplemente usar su imaginación)

Recorre el texto y crea un diccionario, que significa contenedor clave - valor. Y poner todos los pares de palabras como claves y la palabra siguiente como un valor. Por ejemplo: Si tienes un texto de "a b c a b k" se empieza con una "b", como clave y "c" como valor, entonces "b c" y "a" como valor... el valor debe ser una lista o cualquier colección que contenga 0..muchos 'artículos' como usted puede tener más de un valor para un par dado de palabras. En el ejemplo anterior tendrás" a b "dos veces seguido de puño por" c "y luego al final por "k". Así que al final tendrás un diccionario / hash como este: {'a b': ['c','k'], 'b c': ['a'], 'c a': ['b']}

Ahora tienes la estructura necesaria para construir tu funky texto. Usted puede elegir para comenzar con una clave aleatoria o un lugar fijo! Así que dada la estructura que tenemos podemos empezar por guardar "a b" y luego tomar al azar una palabra siguiente del valor, c o k, por lo que el primer guardar en el bucle, "a b k" (si "k" fue el valor aleatorio elegido), a continuación, continuar moviendo un paso a la derecha que en nuestro caso es "b k" y guardar un valor aleatorio para ese par si usted tiene, en nuestro caso no, por lo que romper el bucle (o usted puede decidir otras cosas como empezar de nuevo). Cuando para hacer el bucle, imprima la cadena de texto guardada.

Cuanto mayor sea la entrada, más valores tendrá para sus claves (par de palabras) y luego tendrá un "bot más inteligente" para que pueda "entrenar" a su bot agregando más texto (¿tal vez entrada de chat?). Si tienes un libro como entrada, puedes construir algunas frases al azar. Tenga en cuenta que no tiene que tomar solo una palabra que sigue a un par como valor, puede tomar 2 o 10. La diferencia es que su texto aparecerá más preciso si usted utilice bloques de construcción "más largos". Comience con un par como clave y la siguiente palabra como valor.

Así que usted ve que básicamente puede tener dos pasos, primero hacer una estructura en la que elegir al azar una clave para empezar a continuación, tomar esa clave e imprimir un valor aleatorio de esa clave y continuar hasta que no tenga un valor o alguna otra condición. Si lo desea, puede" sembrar " un par de palabras de una entrada de chat de su estructura clave-valor para tener un comienzo. Su hasta su imaginación cómo comenzar su cadena.

Ejemplo con palabras reales:

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

......

Ahora construye un bucle:

Elija una clave aleatoria, diga "hola mi" y elija al azar un valor, solo uno aquí por lo que su " nombre" (GUARDANDO "hola mi nombre").
Ahora mueva un paso a la derecha tomando "mi nombre" como la siguiente clave y elija un valor aleatorio... "ser" (GUARDANDO "hola mi nombre es").
Ahora muévete y toma "el nombre es"... "Al" (GUARDANDO "hola mi nombre es AL").
Ahora toma "is Al"... "y" (SALVANDO "hola mi su nombre es Al y") .

...

Cuando llegues a "y yo" elegirás al azar un valor, digamos "puedo", entonces se hace la palabra "puedo", etc... cuando llegue a su condición de parada o que no tenga valores, imprima la cadena construida en nuestro caso:

"hola mi nombre es Al y puedo vivir allí el tiempo que quiera"

Si tiene más valores, puede saltar a cualquier tecla. Cuantos más valores tenga, más combinaciones tendrá y más aleatorio y divertido será el texto lo será.

 132
Author: Nocker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-13 17:16:07

El bot elige una palabra aleatoria de tu entrada y genera una respuesta eligiendo otra palabra aleatoria que ha sido vista como sucesora de su palabra retenida. Luego repite el proceso encontrando un sucesor de esa palabra a su vez y continuando iterativamente hasta que piensa que ya se ha dicho lo suficiente. Llega a esa conclusión deteniéndose en una palabra que era anterior a un signo de puntuación en el texto de entrenamiento. A continuación, vuelve al modo de entrada de nuevo para que pueda responder, y así sucesivamente.

No Es muy realista, pero por la presente reto a cualquiera a hacerlo mejor en 71 líneas de código !! Este es un gran desafío para cualquier pitonista en ciernes, y me gustaría poder abrir el desafío a una audiencia más amplia que el pequeño número de visitantes que recibo en este blog. Para codificar un bot que siempre se garantiza que sea gramatical seguramente debe estar más cerca de varios cientos de líneas, simplifiqué enormemente simplemente tratando de pensar en la regla más simple para darle al ordenador una mera puñalada por tener algo que decir.

Es las respuestas son bastante impresionistas por decir lo menos ! También tienes que poner lo que dices entre comillas simples.

Usé Guerra y Paz para mi "corpus" que tomó un par de horas para el entrenamiento, use un archivo más corto si está impaciente {

Aquí está el entrenador

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

Aquí está el 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

Tiendes a tener una sensación extraña cuando dice algo que parece parcialmente tener sentido.

 7
Author: user3513316,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-28 01:19:04

Usted podría hacer así: Haga un pedido 1 generador de cadena markov, usando palabras y no letras. Cada vez que alguien publica algo, lo que publicó se agrega a la base de datos de bots. También bot ahorraría cuando se fue a chatear y cuando un chico publicó el primer post (en múltiplos de 10 segundos), entonces ahorraría la cantidad de tiempo que este mismo chico esperó para publicar de nuevo (en múltiplos de 10 segundos)... Esta segunda parte se utilizaría para ver cuando el chico va a publicar, por lo que unirse a la charla y después de una cierta cantidad de tiempo basado en una tabla con "después de cuántos 10 segundos publicó el tipo después de unirse al chat", luego continuaría publicando con la misma tabla pensando "¿cómo fue la cantidad de tiempo utilizado para escribir el post que se publicó después de un post que usó X segundos para pensar y escribir"

 0
Author: guestrt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-02 13:31:29