How do Markov Chain Chatbots work?

前端 未结 3 503
伪装坚强ぢ
伪装坚强ぢ 2021-01-29 17:44

I was thinking of creating a chatbot using something like markov chains, but I\'m not entirely sure how to get it to work. From what I understand, you create a table from data w

相关标签:
3条回答
  • 2021-01-29 18:07

    You could do like this: Make a order 1 markov chain generator, using words and not letters. Everytime someone post something, what he posted is added to bot database. Also bot would save when he gone to chat and when a guy posted the first post (in multiples of 10 seconds), then he would save the amount of time this same guy waited to post again (in multiples of 10 seconds)... This second part would be used to see when the guy will post, so he join the chat and after some amount of time based on a table with "after how many 10 seconds the a guy posted after joining the chat", then he would continue to post with the same table thinking "how was the amount of time used to write the the post that was posted after a post that he used X seconds to think about and write"

    0 讨论(0)
  • 2021-01-29 18:08

    The bot chooses a random word from your input and generates a response by choosing another random word that has been seen to be a successor to its held word. It then repeats the process by finding a successor to that word in turn and carrying on iteratively until it thinks it’s said enough. It reaches that conclusion by stopping at a word that was prior to a punctuation mark in the training text. It then returns to input mode again to let you respond, and so on.

    It isn’t very realistic but I hereby challenge anyone to do better in 71 lines of code !! This is a great challenge for any budding Pythonists, and I just wish I could open the challenge to a wider audience than the small number of visitors I get to this blog. To code a bot that is always guaranteed to be grammatical must surely be closer to several hundred lines, I simplified hugely by just trying to think of the simplest rule to give the computer a mere stab at having something to say.

    Its responses are rather impressionistic to say the least ! Also you have to put what you say in single quotes.

    I used War and Peace for my “corpus” which took a couple of hours for the training run, use a shorter file if you are impatient…

    here is the 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()
    

    Here is the 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
    

    You tend to get an uncanny feeling when it says something that seems partially to make sense.

    0 讨论(0)
  • 2021-01-29 18:17

    I made a Markov chain chatbot for IRC in Python a few years back and can shed some light how I did it. The text generated does not necessarily make any sense, but it can be really fun to read. Lets break it down in steps. Assuming you have a fixed input, a text file, (you can use input from chat text or lyrics or just use your imagination)

    Loop through the text and make a Dictionary, meaning key - value container. And put all pair of words as keys and the word following as a value. For example: If you have a text "a b c a b k" you start with "a b" as key and "c" as value, then "b c" and "a" as value... the value should be a list or any collection holding 0..many 'items' as you can have more than one value for a given pair of words. In the example above you will have "a b" two times followed fist by "c" then in the end by "k". So in the end you will have a dictionary/hash looking like this: {'a b': ['c','k'], 'b c': ['a'], 'c a': ['b']}

    Now you have the needed structure for building your funky text. You can choose to start with a random key or a fixed place! So given the structure we have we can start by saving "a b" then randomly taking a following word from the value, c or k, so the first save in the loop, "a b k" (if "k" was the random value chosen) then you continue by moving one step to the right which in our case is "b k" and save a random value for that pair if you have, in our case no, so you break out of the loop (or you can decide other stuff like start over again). When to loop is done you print your saved text string.

    The bigger the input, the more values you will have for you keys (pair of words) and will then have a "smarter bot" so you can "train" your bot by adding more text (perhaps chat input?). If you have a book as input, you can construct some nice random sentences. Please note that you don't have to take only one word that follows a pair as a value, you can take 2 or 10. The difference is that your text will appear more accurate if you use "longer" building blocks. Start with a pair as a key and the following word as a value.

    So you see that you basically can have two steps, first make a structure where you randomly choose a key to start with then take that key and print a random value of that key and continue till you do not have a value or some other condition. If you want you can "seed" a pair of words from a chat input from your key-value structure to have a start. Its up to your imagination how to start your chain.

    Example with real words:

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

    Now construct a loop:

    Pick a random key, say "hi my" and randomly choose a value, only one here so its "name" (SAVING "hi my name").
    Now move one step to the right taking "my name" as the next key and pick a random value... "is" (SAVING "hi my name is").
    Now move and take "name is" ... "Al" (SAVING "hi my name is AL").
    Now take "is Al" ... "and" (SAVING "hi my name is Al and").

    ...

    When you come to "and i" you will randomly choose a value, lets say "can", then the word "i can" is made etc... when you come to your stop condition or that you have no values print the constructed string in our case:

    "hi my name is Al and i can live in there as long as i want"

    If you have more values you can jump to any keys. The more values the more combinations you have and the more random and fun the text will be.

    0 讨论(0)
提交回复
热议问题