Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

1
resposta

Faça como eu fiz: construindo um sistema especialista

class BaseDeConhecimento:
def init(self):
self.fatos = set()
self.regras = []

def adicionar_fato(self, fato):
    self.fatos.add(fato)

def adicionar_regra(self, condicoes, conclusao):
    # condicoes é uma lista de fatos necessários
    # conclusao é o diagnóstico ou novo fato inferido
    self.regras.append((condicoes, conclusao))

class SistemaEspecialista:
def init(self, base_conhecimento):
self.base = base_conhecimento
self.diagnosticos = []

def inferir(self):
    mudou = True
    while mudou:
        mudou = False
        for condicoes, conclusao in self.base.regras:
            if all(c in self.base.fatos for c in condicoes) and conclusao not in self.base.fatos:
                self.base.adicionar_fato(conclusao)
                self.diagnosticos.append((condicoes, conclusao))
                mudou = True

def mostrar_raciocinio(self):
    for condicoes, conclusao in self.diagnosticos:
        print(f"Se {', '.join(condicoes)}, então {conclusao}.")

base = BaseDeConhecimento()

base.adicionar_regra(["febre alta", "tosse"], "infecção respiratória")
base.adicionar_regra(["infecção respiratória", "dificuldade para respirar"], "pneumonia")

base.adicionar_fato("febre alta")
base.adicionar_fato("tosse")
base.adicionar_fato("dificuldade para respirar")

sistema = SistemaEspecialista(base)
sistema.inferir()

print("Diagnósticos inferidos:")
print(base.fatos)
print("\nRaciocínio seguido:")
sistema.mostrar_raciocinio()

1 resposta

Olá, Penha. Como vai?

Parabéns pelo desenvolvimento do seu sistema especialista! O seu código está muito limpo, bem estruturado e demonstra de forma bastante didática o funcionamento de um motor de inferência por Encadeamento para Frente (Forward Chaining).

Nesse modelo clássico de inteligência artificial baseada em conhecimento, partimos dos fatos conhecidos para deduzir novas conclusões de forma iterativa. O seu código ilustra muito bem esse encadeamento: o sistema usa os fatos iniciais "febre alta" e "tosse" para deduzir "infecção respiratória". Em seguida, no ciclo seguinte do laço, esse fato recém-descoberto é combinado com a "dificuldade para respirar" para finalmente deduzir o diagnóstico de "pneumonia".

Gostaria de destacar dois pontos técnicos muito positivos na sua solução:

  • O uso da função all(): A sua verificação condicional utilizando all(c in self.base.fatos for c in condicoes) é uma excelente prática em Python. Ela é altamente legível, elegante e eficiente para garantir que todas as premissas de uma regra sejam atendidas antes de disparar a conclusão.
  • Controle de loop com a variável mudou: A lógica de manter o laço while mudou garante que o motor de inferência continue rodando enquanto houver novas conclusões a serem feitas, interrompendo o processamento imediatamente quando a base de fatos se estabilizar.

Como contribuição para os seus estudos, gostaria de deixar duas sugestões práticas:

  • Atenção à nomenclatura dos construtores (__init__): Notei que, na formatação do código aqui no post do fórum, os métodos construtores das suas duas classes aparecem escritos como def init(self):. É muito provável que a formatação do editor do fórum tenha "engolido" os sublinhados (o que acontece bastante quando copiamos e colamos código diretamente, pois o Markdown pode interpretar dois sublinhados seguidos como uma instrução de formatação de texto em negrito). No entanto, caso o seu código original no Python esteja de fato com init, ele gerará um erro de atributo ao tentar instanciar o objeto. Lembre-se de que em Python os construtores devem ser escritos obrigatoriamente com dois sublinhados antes e depois: def __init__(self):.
  • Tratamento e Normalização de Strings: Sistemas baseados em regras que lidam com entrada de texto podem falhar por detalhes de digitação, como letras maiúsculas ou espaços em branco extras (por exemplo, se o usuário digitar "Febre alta" ou "tosse "). Para deixar o seu sistema especialista ainda mais robusto contra esses pequenos erros, você pode aplicar métodos de tratamento de strings, como .lower().strip(), tanto no momento de adicionar os fatos quanto na verificação das regras.

O seu projeto prático ficou muito bem estruturado e serve como uma ótima referência de estudos para outros alunos que estão aprendendo sobre os fundamentos de sistemas inteligentes!

Espero que possa ter lhe ajudado!