Solucionado (ver solução)

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!

Solucionado
(ver solução)
2
respostas

[Projeto] Faça como eu fiz: construindo um sistema especialista

# Sistema Especialista para Diagnóstico Médico
# Este código implementa um sistema especialista simples para diagnóstico médico usando regras de inferência.
# O sistema é baseado em uma base de conhecimento composta por fatos e regras, e pode inferir novos fatos a partir de um conjunto inicial de sintomas.
# O sistema é projetado para ser facilmente extensível, permitindo a adição de novos fatos e regras conforme necessário.
# O exemplo inclui regras para diagnosticar infecção respiratória, pneumonia e resfriado com base em sintomas como febre alta, tosse, falta de ar e coriza.

class Fato:
    def __init__(self, nome):
        self.nome = nome

class Regra:
    def __init__(self, antecedentes, consequente):
        self.antecedentes = antecedentes
        self.consequente = consequente

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

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

    def adicionar_regra(self, regra):
        self.regras.append(regra)


class SistemaEspecialista:

    def __init__(self, base_conhecimento):
        self.base = base_conhecimento

    def inferir(self, fatos_iniciais):

        fatos_conhecidos = {fato.nome for fato in fatos_iniciais  }
        houve_alteracao = True

        while houve_alteracao:
            houve_alteracao = False
            for regra in self.base.regras:
                if all( antecedente.nome in fatos_conhecidos for antecedente in regra.antecedentes):
                    if regra.consequente.nome not in fatos_conhecidos:
                        fatos_conhecidos.add( regra.consequente.nome)
                        houve_alteracao = True

        return fatos_conhecidos


#tabela de regras para diagnóstico médico
regra1 = Regra(
        [Fato("febre_alta"), Fato("tosse")],
        Fato("infeccao_respiratoria")
    )

regra2 = Regra(
        [Fato("febre_alta"),
         Fato("tosse"),
         Fato("falta_de_ar")],
        Fato("pneumonia")
    )

regra3 = Regra(
        [Fato("coriza"), Fato("tosse")],
        Fato("resfriado")
    )

regra4 = Regra(
        [Fato("coriza"), Fato("tosse")],
        Fato("resfriado")
    )

# Criando a base de conhecimento e adicionando as regras
base = BaseDeConhecimento()
base.adicionar_regra(regra1)
base.adicionar_regra(regra2)
base.adicionar_regra(regra3)
base.adicionar_regra(regra4)


# Fatos iniciais do paciente
fatos_paciente = [
    Fato("febre_alta"),
    Fato("tosse"),
    Fato("falta_de_ar")
]


# Criando o sistema especialista a partir da base de conhecimento
sistema = SistemaEspecialista(base)

# Inferir os diagnósticos com base nos fatos do paciente (sintomas)
resultado = sistema.inferir( fatos_paciente)

print("\nFATOS INFERIDOS:")

for fato in resultado:
    print("-", fato)
2 respostas
solução!

Olá, Marcelo! Como vai?

Parabéns pela realização das atividades!

Você conseguiu apresentar um sistema especialista bem estruturado, demonstrou clareza na definição das regras de inferência e ainda trouxe um exemplo prático de diagnóstico médico com sintomas relevantes. Além disso, mostrou como a base de conhecimento pode ser facilmente expandida, o que evidencia visão de escalabilidade e aplicabilidade em cenários reais. Isso reforça a importância de unir lógica de programação com inteligência artificial simbólica para criar soluções explicativas e confiáveis.

Se quiser aprofundar ainda mais, algumas boas práticas são:

  • Evitar redundâncias: revisar regras duplicadas para manter a base de conhecimento enxuta.
  • Adicionar explicações: incluir mensagens que mostrem ao usuário como cada diagnóstico foi inferido.
  • Expandir sintomas: enriquecer a base com novos fatos e regras para aumentar a precisão.

Ah uma pergunta: O que você considera mais interessante neste tipo de sistema, a possibilidade de explicar passo a passo como chegou ao diagnóstico ou a rapidez em gerar conclusões automáticas?

Fico à disposição! E se precisar, conte sempre com o apoio do fórum.

Abraço e bons estudos!

AluraConte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!

Obrigado Daniel, pelo retorno!

putz eu não tinha percebido que equeci de mudar a ultima regra, bem observado.
Na minha opinião é importante mostrar como o resultado foi inferido, qual caminho para o especialisa validar, então sim, aplique isso numa versão melhorada, muitas coisas poderiam melhorar, como colocar um loop ininito pra entrada de dados e poder inferir, novos pacientes, digitando ou selecionando códigos numéricos ou migrar isso pra algo visual ou ligar com um agente com entrada em linugagem natural + pydantic pra passar um estrutura para o sistema especialista.

# Sistema Especialista para Diagnóstico Médico V2
# Este código implementa um sistema especialista simples para diagnóstico médico usando regras de inferência.
# O sistema é baseado em uma base de conhecimento composta por fatos e regras, e pode inferir novos fatos a partir de um conjunto inicial de sintomas.
# O sistema é projetado para ser facilmente extensível, permitindo a adição de novos fatos e regras conforme necessário.
# O exemplo inclui regras para diagnosticar infecção respiratória, pneumonia e resfriado com base em sintomas como febre alta, tosse, falta de ar e coriza.


class Fato:
    def __init__(self, nome):
        self.nome = nome


class Regra:
    def __init__(self, antecedentes, consequente):
        self.antecedentes = antecedentes
        self.consequente = consequente


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

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

    def adicionar_regra(self, regra):
        self.regras.append(regra)


class SistemaEspecialista:

    def __init__(self, base_conhecimento):
        self.base = base_conhecimento
        self.explicacoes = []   #acrescentando uma lista para armazenar as explicações das inferências

    def inferir(self, fatos_iniciais):

        fatos_conhecidos = {fato.nome for fato in fatos_iniciais  }
        houve_alteracao = True

        while houve_alteracao:
            houve_alteracao = False
            for regra in self.base.regras:
                  if all( antecedente.nome in fatos_conhecidos for antecedente in regra.antecedentes):
                    if regra.consequente.nome not in fatos_conhecidos:
                        fatos_conhecidos.add( regra.consequente.nome )
                        houve_alteracao = True

                        sintomas = ", ".join( antecedente.nome for antecedente in regra.antecedentes ) #criando uma string com os sintomas que levaram à inferência do diagnóstico

                        #adicionando uma explicação para a inferência do diagnóstico, indicando quais sintomas foram encontrados para chegar a essa conclusão
                        self.explicacoes.append(
                            f"{regra.consequente.nome} "
                            f"foi inferido porque foram encontrados: "
                            f"{sintomas}"
                        )

        return fatos_conhecidos


#tabela de regras para diagnóstico médico

regra1 = Regra(
    [Fato("febre_alta"), Fato("tosse")],
    Fato("infeccao_respiratoria")
)

regra2 = Regra(
    [
        Fato("febre_alta"),
        Fato("tosse"),
        Fato("falta_de_ar")
    ],
    Fato("pneumonia")
)

regra3 = Regra(
    [Fato("coriza"), Fato("tosse")],
    Fato("resfriado")
)

#(Tudo apenas didático, não deve ser usado para diagnóstico real)
regra4 = Regra(
    [
        Fato("febre_alta"),
        Fato("dor_no_corpo"),
        Fato("tosse")
    ],
    Fato("gripe")
)

regra5 = Regra(
    [
        Fato("tosse"),
        Fato("chiado_no_peito")
    ],
    Fato("bronquite")
)

regra6 = Regra(
    [
        Fato("febre_alta"),
        Fato("tosse"),
        Fato("perda_olfato")
    ],
    Fato("covid")
)

regra7 = Regra(
    [
        Fato("falta_de_ar"),
        Fato("chiado_no_peito")
    ],
    Fato("asma")
)

# Criando a base de conhecimento e adicionando as regras
base = BaseDeConhecimento()

base.adicionar_regra(regra1)
base.adicionar_regra(regra2)
base.adicionar_regra(regra3)
base.adicionar_regra(regra4)
base.adicionar_regra(regra5)
base.adicionar_regra(regra6)
base.adicionar_regra(regra7)

# Fatos iniciais do paciente
fatos_paciente = [
    Fato("febre_alta"),
    Fato("tosse"),
    Fato("falta_de_ar")
]

# Criando o sistema especialista a partir da base de conhecimento
sistema = SistemaEspecialista(base)

# Inferir os diagnósticos com base nos fatos do paciente (sintomas)
resultado = sistema.inferir( fatos_paciente)

print("\nFATOS INFERIDOS:")
print("-" * 20)

for fato in resultado:
    print("-", fato)

print("\nEXPLICAÇÃO DAS INFERÊNCIAS:")
print("-" * 20)

for explicacao in sistema.explicacoes:
    print("-", explicacao)
print("\n")