Gerando texto com Cadeias de Markov usando Python

Henrique Gomes
Bots Brasil
Published in
3 min readMar 28, 2019

Cadeias de Markov são sistemas matemáticos que pulam de um estado para outro. Por exemplo, se construimos um modelo de Cadeia de Markov do comportamento de um bebê podemos incluir os estados:

"Dormindo”, “Brincando”, “Comendo” e “Chorando”

Além disso, a Cadeia de Markov nos diz a probabilidade de ocorrer uma transição de um estado para outro. Por exemplo, a probabilidade do bebê dormir dado que atualmente está comendo.

Se pensarmos em um modelo com apenas dois estados (A e B), temos 4 possibilidades de transição, dado que um estado pode transitar para ele mesmo.

Fonte: A visual explanation by Victor Powell (editado)

Caso prefira uma explicação visual, clique aqui e aprecie o trabalho do Victor Powell.

Antes de continuarmos, esse artigo e o código usado foram baseados nesse artigo do Autor Ben Shaver, no qual ele explica o código em Python baseado numa coleção de textos do Donald Trump.

Palavras são como estados. E uma sequencia de estados forma uma sentença.

Para gerar texto com base em uma coleção de textos, primeiro contaremos todas as palavras que aparecem na coleção. Depois, para cada palavra armazenaremos as palavras que subsequentes dessa.
Exemplo:

"Esse é um exemplo de texto."Número de palavras: 6Armazenando (palavra, palavra subsequente):
[(Esse, é),(é, um),(um, exemplo),(exemplo, de),(de, texto.)]

Para testar o algoritmo, precisamos de uma coleção de texto. Quanto mais texto sobre o mesmo assunto, melhor. Além disso, o ideal é que os textos apresentem “similaridade” entre si. Nada melhor do que a prática para entendermos esses detalhes.

Similaridade está entre aspas por que não se trata de similaridade semantica e sim de temas semelhantes. Não adianta juntarmos textos sobre Impressoras e Jardins e esperar que geraremos algo que faça o mínimo de sentido (Teste, vale a pena).

No caso, assim como o autor utilizou citações de Donald Trump, usaremos citações e um discurso Bolsonaro. Vamos usar uma coleção de citações encontradas aqui e o discurso durante cerimônia de recebimento da faixa presidencial encontrado aqui.

Passo-a-Passo (código completo 👇)

Primeiro, importamos o NumPy e o arquivo .txt que contêm os textos do Bolsonaro.

import numpy as np
bolsonaro = open(r'bolsonaro.txt', encoding='utf8').read()

Depois, dividimos o arquivo de texto em palavras únicas. (Não estamos tirando a pontuação, portanto nosso texto gerado terá pontuação.)

corpus = bolsonaro.split()

Então, definimos uma função para nos dar todos os pares de palavras nos discursos.

def make_pairs(corpus):
for i in range(len(corpus)-1):
yield (corpus[i], corpus[i+1])

pairs = make_pairs(corpus)

Então, instanciámos um dicionário e preenchemos as palavras de nossos pares. Se a primeira palavra do par já é uma chave no dicionário, basta anexar a próxima palavra à lista de palavras que seguem essa palavra. Caso contrário, inicialize uma nova entrada no dicionário com a chave igual à primeira palavra e o valor uma lista de tamanho um:

word_dict = {}for word_1, word_2 in pairs:
if word_1 in word_dict.keys():
word_dict[word_1].append(word_2)
else:
word_dict[word_1] = [word_2]

Finalmente, escolhemos aleatoriamente uma palavra para começar a cadeia e escolhemos o número de palavras que queremos gerar (é interessante brincar com essa variável).

first_word = np.random.choice(corpus)chain = [first_word]n_words = 30

Após a primeira palavra, cada palavra da cadeia é escolhida aleatoriamente a partir da lista de palavras que seguiram essa palavra nas citações reais do Bolsonaro.

for i in range(n_words):
chain.append(np.random.choice(word_dict[chain[-1]]))

O comando join retorna a cadeia como uma string:

' '.join(chain)print(' '.join(chain))

Ao rodar o código, a primeira saída que recebo é:

Moro vai à corrupção. É melhor Jair se excedendo, achando que um futuro de tudo. Deus que eles fazem em prática o dos brasileiros em busca de todas as reformas necessárias.

O próprio Ben Shaver incentiva que façam melhorias no código, por exemplo exigir que a primeira palavra seja colocada em maiúscula, para que o texto não comece no meio da frase.

--

--