Pregunta

Estaba pensando en crear un chatbot usando algo como las cadenas de Markov, pero no estoy completamente seguro de cómo hacer que funcione. Por lo que entiendo, crea una tabla a partir de datos con una palabra dada y luego palabras que siguen. ¿Es posible adjuntar algún tipo de probabilidad o contador mientras capacita al bot? ¿Es esa una buena idea?

La segunda parte del problema es con palabras clave. Suponiendo que ya puedo identificar palabras clave de la entrada del usuario, ¿cómo genero una oración que usa esa palabra clave? No siempre quiero comenzar la oración con la palabra clave, entonces, ¿cómo sembro la cadena de Markov?

¿Fue útil?

Solución

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

Reunir el texto y hacer un diccionario, que significa contenedor de valor clave. Y ponga todas las palabras como teclas y la palabra siguiente como un valor. Por ejemplo: si tiene un texto "ABCABK", comienza con "AB" como clave y "C" como valor, luego "BC" y "A" como valor ... el valor debe ser una lista o cualquier colección que tenga 0 ... muchos 'elementos', ya que puedes tener más de un valor para un par de palabras dado. En el ejemplo anterior, habrá "ab" dos veces seguido al puño de "C" y luego al final de "K". Así que al final tendrás un diccionario/hash que se parece: {'a b': ['c','k'], 'b c': ['a'], 'c a': ['b']}

Ahora tiene la estructura necesaria para construir su texto funky. ¡Puede elegir comenzar con una llave aleatoria o un lugar fijo! Entonces, dada la estructura que tenemos, podemos comenzar guardando "AB" y luego tomando una palabra siguiente del valor, C o K, por lo que el primer ahorro en el bucle, "ABK" (si "K" fue el valor aleatorio elegido) Luego continúa moviendo un paso hacia la derecha, que en nuestro caso es "BK" y guarda un valor aleatorio para ese par si tiene, en nuestro caso, no, para salir del bucle (o puede decidir otras cosas como empezar de nuevo). Cuando se realiza el bucle, imprime su cadena de texto guardada.

Cuanto más grande sea la entrada, más valores tendrá para sus teclas (par de palabras) y luego tendrá un "bot más inteligente" para que pueda "entrenar" su bot agregando más texto (¿quizás la entrada de chat?). Si tiene un libro como entrada, puede construir algunas oraciones aleatorias agradables. Tenga en cuenta que no tiene que tomar solo una palabra que siga un par como valor, puede tomar 2 o 10. La diferencia es que su texto parecerá más preciso si usa bloques de construcción "más largos". Comience con un par como clave y la siguiente palabra como valor.

Entonces, verá que básicamente puede tener dos pasos, primero haga una estructura en la que elija al azar una clave para comenzar, luego tome esa clave e imprima un valor aleatorio de esa clave y continúe hasta que no tenga un valor o alguna otra condición. Si desea, puede "sembrar" un par de palabras de una entrada de chat de su estructura de valor clave para comenzar. Depende de tu imaginación cómo comenzar tu 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 construya un bucle:

Elija una llave aleatoria, diga "hola my" y elija al azar un valor, solo una aquí para que su "nombre"(Guardar "hola mi nombre").
Ahora mueva un paso hacia la derecha tomando "mi nombre" como la siguiente clave y elige un valor aleatorio ... "es"(Guardar "Hola, mi nombre es").
Ahora muévase y tome "el nombre es" ... "AL"(Guardar "Hola, mi nombre es Al").
Ahora toma "es Al" ... "y"(Guardar "Hola, mi nombre es Al y").

...

Cuando vengas a "y yo" elegirás aleatoriamente un valor, digamos "lata", entonces la palabra "puedo" se hace, etc. cuando llegas a tu condición de parada o que no tienes valores imprime la construcción de la construcción cadena en nuestro caso:

"Hola, mi nombre es Al y puedo vivir allí todo el tiempo que quiera"

Si tiene más valores, puede saltar a cualquier tecla. Cuantos más valores, más combinaciones tengas y más aleatorio serán el texto.

Otros consejos

El bot elige una palabra aleatoria de su aporte y genera una respuesta al elegir otra palabra aleatoria que se ha visto como un sucesor de su palabra sostenida. Luego repite el proceso encontrando un sucesor de esa palabra a su vez y continuando iterativamente hasta que piense que se dice lo suficiente. Llega a esa conclusión deteniéndose en una palabra que era antes de un signo de puntuación en el texto de entrenamiento. Luego vuelve al modo de entrada nuevamente para permitirle responder, y así sucesivamente.

¡No es muy realista, pero por la presente desafío a cualquiera a hacerlo mejor en 71 líneas de código! Este es un gran desafío para cualquier pitonista en ciernes, y solo desearía poder abrir el desafío a un público más amplio que el pequeño número de visitantes que recibo a 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, me simplifiqué enormemente solo tratando de pensar en la regla más simple para darle a la computadora una mera puñalada para tener algo que decir.

¡Sus respuestas son bastante impresionistas por decir lo menos! También tienes que poner lo que dices en citas individuales.

Usé la guerra y la paz para mi "corpus" que tomó un par de horas para la carrera de 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.

Puede hacer esto: haga un generador de cadena de Markov Order 1, usando palabras y no letras. Cada vez que alguien publica algo, lo que publicó se agrega a la base de datos BOT. También Bot ahorraría cuando fuera a chatear y cuando un chico publicó la primera publicación (en múltiplos de 10 segundos), entonces ahorraría la cantidad de tiempo que este mismo tipo esperó para publicar nuevamente (en múltiplos de 10 segundos) ... Esta segunda parte se usaría para ver cuándo publicará el tipo, por lo que se unió al chat y después de un tiempo basado en una mesa con "Después de cuántos 10 segundos, el chico publicó después de unirse al chat", luego continuaría Publicar con la misma tabla pensando "¿Cómo se utilizó la cantidad de tiempo para escribir la publicación que se publicó después de una publicación que usó X segundos para pensar y escribir"

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top