Entendendo Inteligência Artificial — Parte 1: linguagem.

Viviane Tolomeotti
devorando
Published in
8 min readMay 29, 2020

Há cerca de dois anos fui convidada para participar de uma mesa de discussão da semana de recepção dos calouros. Uma das perguntas clássicas desse tipo de evento é “Por que você escolheu esse curso?”. Quando entrei na graduação a resposta era, na maior parte das vezes, “porque eu quero ser desenvolvedor de jogos”. Para minha grande surpresa, nesse grupo a vasta maioria respondeu “porque eu quero trabalhar com IA” ou, os mais sonhadores, “Pra construir um Jarvis igual o Homem de Ferro”.

A Inteligência Artificial abrange uma gama enorme de áreas e é responsável, em algum nível, pela maior parte das automações que vemos no nosso dia-a-dia. Apesar de todas essas aplicações, o que pensamos ao ouvir essa expressão é: criar um robô indistinguível de um humano (tipo a criança daquele filme do Steven Spielberg).

A obsessão pelo assunto é tanta e tão antiga que o próprio Pai da Computação, Alan Turing, ainda em 1950 desenvolveu um teste para medir o nível de inteligência de uma máquina tentando simular o comportamento humano. Esse teste é o famoso “jogo da imitação”.

O jogo consiste, basicamente, de uma conversa entre três indivíduos: um interrogador e dois interrogados. Os interrogados não conversam entre si e nem ouvem as respostas um do outro. Um dos interrogados é uma máquina, os outros dois participantes são humanos. O interrogador faz perguntas aos dois outros participantes, e, ao final delas, deve decidir qual dos dois interrogados é um ser humano e qual é uma máquina. Se ele não for capaz de fazer isso, a máquina passou no teste. Você pode ler mais detalhes sobre o jogo da imitação e como ele influenciou e influencia o mundo em que vivemos no site oficial. Olhando para essa métrica, podemos ter uma noção do quão importante é a capacidade de comunicação para a definição de inteligência na qual acreditamos.

Caso ainda não tenha visto, “O jogo da imitação” também é um filme sobre Alan Turing e o primeiro computador moderno.

Para se comunicar, uma máquina precisa de conhecimento (para saber sobre o que falar), plasticidade cerebral (para saber conectar as ideias e criar ideias novas a partir delas) e linguagem natural (para construir frases e organizar as ideias). Todas essas coisas são importantes, mas nesse post vou me aprofundar um pouco mais em linguagem natural e o que a torna tão difícil de simular.

A primeira coisa que precisamos fazer para entender o que define uma linguagem natural é entender o que define uma linguagem. Nesse ponto a computação se mistura com a gramática, e temos que citar um grande linguista: Noam Chomsky. Chomsky nasceu em 1928 (ainda está vivo!!) e é considerado “o pai da linguística moderna”. O que o fez receber esse título foi a capacidade de definir matematicamente os tipos de linguagens existentes e classificá-los de acordo com uma hierarquia.

Chomsky e sua carinha de gênio.

Chomsky define uma linguagem a partir de algumas regras: um conjunto (finito ou infinito) de sentenças de tamanho finito e construídas a partir de um conjunto finito de elementos. Para uma linguagem natural, por exemplo, temos um número finito de fonemas (ou de letras) que formam frases de tamanho finito. Além disso, uma linguagem deve possuir uma gramática. Uma gramática é um dispositivo que pode ser usado para produzir sentenças corretas dentro da linguagem. Uma gramática, portanto, produz apenas sentenças gramaticalmente corretas. É importante notar, entretanto, que uma gramática não necessariamente produz sentenças com algum significado.

Essa definição separou o sintático (está correto de acordo com as regras gramaticais) do semântico (faz algum sentido para o interlocutor) e é usada em todas as áreas da ciência da computação. Até porque, se formos pensar a respeito, uma linguagem de programação é uma linguagem, e o dispositivo que testa sua gramática é o compilador.

Além disso, Chomsky também nos deu uma definição matemática de gramática. De acordo com ele uma gramática G é uma tupla composta por

G = (N, Σ, P, S)

sendo:

N — um conjunto de símbolos não-terminais. Um símbolo não-terminal é um símbolo que pode se transformar em um ou mais outro símbolo, de acordo com as regras da gramática que o define. Os símbolos não-terminais nunca fazem parte da sentença final.

Σ — um conjunto de símbolos terminais. Um símbolo terminal não pode ser substituído por outro símbolo. Portanto nenhum dos membros de Σ pode ser membro de N, e vice-versa. Os símbolos terminais são os únicos que aparecem na sentença final.

S — Um símbolo S que pertence ao conjunto N. Esse símbolo é especial pois é o símbolo inicial, que marca onde devemos iniciar o processamento da palavra.

P — um conjunto finito de regras, chamadas de regras de produção. Essas regras são responsáveis por transformar os símbolos não terminais em símbolos terminais e formar palavras. Para uma palavra ser aceita por uma gramática, deve existir um conjunto finito de passos que se pode seguir de forma a chegar nessa palavra e nenhum símbolo não-terminal.

Let’s math!

Dada uma gramática G, definida por:
G = (N = {A, B}, Σ={a, b, x}, {
S -> aA
A -> bA
A -> bB
B -> a
}, S)

Essa gramática nos retorna todas as palavras começadas e terminadas em A com apenas Bs no meio. Se testarmos a palavra “abba” (correta):
S -> aA — palavra atual: aA
A -> bA — palavra atual abA
A -> bB — palavra atual abbB
B -> a — palavra atua abba

Se testarmos a palavra “babba” (errada):
S -> aA — palavra atual: aA (não há regras capazes de substituírem esse a por um b)

E o que eu faço com isso?

Munido do conceito de gramática, Chomsky percebeu que elas podiam ser divididas de acordo com as regras extras que aplicavam para a criação de suas regras de produção e as linguagens que geravam. Ele classificou as linguagens em quatro grupos (de 0 a 3), sendo que o conjunto de menor número sempre contém os conjuntos de número maior (quase como uma boneca russa). Os grupos são:

Tipo 3 (mais simples) — chamadas gramáticas regulares, elas são capazes de definir linguagens regulares. As regras de produção delas são as mais estritas, sendo permitido apenas um não-terminal do lado esquerdo, sem terminais. Do lado direito deve haver apenas um terminal acompanhado de no máximo um não-terminal. Por exemplo:
A -> aA
A -> a
A -> Aa
Aa -> Aa
A -> A
Por ser altamente restrita, esse tipo de linguagem, em geral, é usada na definição de autômatos que realizam operações bem específicas, como procurar padrões em DNA e classificação de documentos.

Tipo 2 — chamadas gramáticas livres de contexto, elas definem linguagens do mesmo tipo. Sua única regra de produção é que do lado esquerdo deve existir apenas um não-terminal, sem terminais. Do lado direito podem existir quaisquer regras de combinação de terminais e não-terminais. Esse tipo de linguagem é mais largamente aplicado, sendo o padrão para a criação de quase todas as linguagens de programação modernas.
Por muitos anos existiu a dúvida se linguagens naturais também seriam livres de contexto. Isso porque o fato de não sermos capazes de criar uma gramática que defina o idioma não significa que isso não é possível. Em 1980, entretanto, provou-se que holandês era um idioma com complexidade acima de uma linguagem livre de contexto, e que, portanto, todas as outras linguagens naturais também são.

Tipo 1 — chamadas gramáticas sensíveis ao contexto, elas definem linguagens que também o são. Sua regra de produção consiste de pelo menos um terminal do lado esquerdo, acompanhado de qualquer combinação de terminais e não-terminais. O lado direito pode conter qualquer coisa. Esse tipo de gramática acabou provando-se complexa o suficiente para produzir uma linguagem natural, e é, atualmente, o utilizado pelos pesquisadores da área para simular idiomas.

Tipo 0 — as gramáticas irrestritas, ou gramáticas livres, são todas as outras gramáticas que não são restritas o suficiente para se encaixarem nos tipos anteriores. A única regra para elas é que sejam resolvíveis, ou seja, o conjunto de regras seja capaz de formar palavras e não acabe em loops. Esse tipo de gramática é capaz de representar qualquer linguagem. Entretanto é um modelo apenas teórico, já que sua aplicação requer a implementação de uma máquina de Turing (um autômato com poder de processamento e memória infinitos, leia mais sobre esses autômatos aqui).

RESUMO DA ÓPERA

Resumindo toda essa teoria: linguagens naturais podem sim ser processadas e simuladas computacionalmente. Seu nível de complexidade de acordo com a Hierarquia de Chomsky, entretanto, é um dos mais altos possível.

O que torna esse nível alto? Grande parte da resposta está na definição do grupo da linguagem: sensível ao contexto. A teoria matemática nos prova que é possível ensinar o computador a ser sensível ao contexto (e entender metáforas, ironias, ambiguidades e tudo o mais), entretanto definir as regras que o farão aprender corretamente ainda é um desafio enorme ao nosso intelecto.

Há muitos e muitos milhões de anos, uma espécie de seres pandimensionais hiperinteligentes ficaram tão de saco cheio dessas discussões a respeito do significado da vida, que decidiram resolver esse problema de uma vez por todas. Construíram um estupendo supercomputador tão extraordinariamente inteligente que, mesmo antes de seus bancos de dados serem ligados, ele já deduzira, a partir do princípio “penso, logo existo”, a existência do pudim de arroz e do Imposto de Renda […]
- Ó, Pensador Profundo, queremos que nos diga… a Resposta!
- A Resposta? Resposta a que pergunta?
- A Vida! O Universo! E tudo o mais!
- Há uma resposta. Mas vou ter que pensar nela.
(sete milhões e quinhentos mil anos depois)
- Tenho a resposta. Mas acho que vocês não vão gostar dela. É 42.
- 42?
- Eu verifiquei cuidadosamente, e não há duvida de que a resposta é essa. Para ser franco, acho que o problema é que vocês jamais souberam qual é a pergunta.

--

--