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!

2
respostas

[Projeto] Faça como eu fiz: construindo um sistema inteligente de recomendação

  1. Definindo os produtos:
class Produto:
    def __init__(self, nome, categoria, probabilidade_conversao):
        self.nome = nome
        self.categoria = categoria
        self.probabilidade_conversao = probabilidade_conversao

    def __repr__(self):
        return f"Produto(Nome='{self.nome}', Categoria='{self.categoria}', Conversão={self.probabilidade_conversao:.2f})"

    def __lt__(self, other):
        # Usado para comparação de prioridade em filas
        return self.probabilidade_conversao > other.probabilidade_conversao # maior conversão quer dizer 'menor' comportamento de topo de pilha
  1. Criando sistema de recomendação e Implementando a heurística
import heapq

class AStarRecommendation:
    def __init__(self, produtos):
        self.produtos = {p.nome: p for p in produtos}
        self.grafo = self._construir_grafo_simplificado(produtos)

    def _construir_grafo_simplificado(self, produtos):
        # Grafo completo onde cada produto se conecta a todos os outros
        grafo = {produto.nome: [] for produto in produtos}
        for i, p1 in enumerate(produtos):
            for j, p2 in enumerate(produtos):
                if p1.nome != p2.nome:
                    # Suponha que o "custo" para ir de um produto para outro seja 1
                    # No A*, o custo real (g) é a distância percorrida.
                    # Podemos ajustar este custo para refletir alguma similaridade ou dificuldade.
                    # Por simplicidade, faremos custo de transição como 1 para todos.
                    grafo[p1.nome].append((p2.nome, 1)) # (destino, custo)
        return grafo

    def _heuristica(self, produto_nome):
        # Heurística baseada na probabilidade de conversão
        # Queremos minimizar o "custo", então uma probabilidade de conversão alta deve resultar em um valor heurístico baixo.
        # Uma forma de fazer isso é 1 - probabilidade_conversao, ou simplesmente usar a probabilidade negativa.
        # Como o A* busca o menor custo total, e queremos maximizar a conversão, a heurística deve ser
        # um *custo estimado* para alcançar o objetivo. Vamos usar (1 - probabilidade_conversao) como um "custo" potencial.
        # Ou, para ser mais direto com o problema, vamos considerar que um produto com alta conversão é "mais próximo" do objetivo ideal.
        # Para um caminho de recomendação, o custo seria a "desvantagem" ou "distância" do produto ideal.
        # Portanto, quanto maior a probabilidade de conversão, menor o valor da heurística.
        return 1 - self.produtos[produto_nome].probabilidade_conversao

    def encontrar_melhor_caminho(self, inicio_nome, objetivo_nome):
        if inicio_nome not in self.produtos or objetivo_nome not in self.produtos:
            return None, "Produto de início ou objetivo não encontrado."

        # Fila de prioridade: (f_score, g_score, produto_atual_nome, caminho)
        # f_score = g_score + h_score
        # g_score = custo do início até o produto atual
        # h_score = estimativa heurística do produto atual até o objetivo
        fila_prioridade = [(0 + self._heuristica(inicio_nome), 0, inicio_nome, [inicio_nome])]

        # Manter o menor g_score encontrado para cada produto
        g_scores = {produto: float('inf') for produto in self.produtos}
        g_scores[inicio_nome] = 0

        # Para reconstruir o caminho
        caminhos = {inicio_nome: [inicio_nome]}

        while fila_prioridade:
            f_score_atual, g_score_atual, atual_nome, caminho_atual = heapq.heappop(fila_prioridade)

            if atual_nome == objetivo_nome:
                return caminho_atual, f"Custo total (aproximado): {f_score_atual:.2f}"

            # Se já encontramos um caminho melhor para este nó, ignoramos
            if g_score_atual > g_scores[atual_nome]:
                continue

            for vizinho_nome, custo_transicao in self.grafo[atual_nome]:
                tentative_g_score = g_score_atual + custo_transicao

                if tentative_g_score < g_scores[vizinho_nome]:
                    g_scores[vizinho_nome] = tentative_g_score
                    caminhos[vizinho_nome] = caminho_atual + [vizinho_nome]
                    h_score = self._heuristica(vizinho_nome)
                    f_score = tentative_g_score + h_score
                    heapq.heappush(fila_prioridade, (f_score, tentative_g_score, vizinho_nome, caminhos[vizinho_nome]))

        return None, "Caminho não encontrado."

Continua nos comentários

2 respostas

Continuando...
3. Testando o sistema

# Inserir exemplos de produtos
produtos_exemplo = [
    Produto("Smartphone X", "Eletrônicos", 0.85),
    Produto("Fone Bluetooth", "Eletrônicos", 0.70),
    Produto("Camiseta Algodão", "Vestuário", 0.60),
    Produto("Calça Jeans", "Vestuário", 0.75),
    Produto("Livro Fantasia", "Livros", 0.90),
    Produto("Câmera Digital", "Eletrônicos", 0.50),
    Produto("Relógio Inteligente", "Eletrônicos", 0.80)
]

# Criar o sistema de recomendação
sistema_recomendacao = AStarRecommendation(produtos_exemplo)

print("Produtos Disponíveis:")
for p in produtos_exemplo:
    print(f"- {p}")
print("\n")

# Testar o sistema para encontrar o melhor caminho entre dois produtos
inicio = "Smartphone X"
objetivo = "Livro Fantasia"

caminho_melhor, info = sistema_recomendacao.encontrar_melhor_caminho(inicio, objetivo)

if caminho_melhor:
    print(f"Melhor caminho de '{inicio}' para '{objetivo}':")
    for i, produto_nome in enumerate(caminho_melhor):
        print(f"  {i+1}. {sistema_recomendacao.produtos[produto_nome]}")
    print(info)
else:
    print(f"Não foi possível encontrar um caminho de '{inicio}' para '{objetivo}'. {info}")

print("\n")

inicio = "Camiseta Algodão"
objetivo = "Relógio Inteligente"

caminho_melhor, info = sistema_recomendacao.encontrar_melhor_caminho(inicio, objetivo)

if caminho_melhor:
    print(f"Melhor caminho de '{inicio}' para '{objetivo}':")
    for i, produto_nome in enumerate(caminho_melhor):
        print(f"  {i+1}. {sistema_recomendacao.produtos[produto_nome]}")
    print(info)
else:
    print(f"Não foi possível encontrar um caminho de '{inicio}' para '{objetivo}'. {info}")

Oi, Paulo! Como vai?

Agradeço por compartilhar seu código com a comunidade Alura.

Seu projeto de sistema inteligente de recomendação em Python ficou bem estruturado e demonstra uma boa aplicação dos conceitos estudados no curso Fundamentos de IA.

Você organizou bem a classe Produto, definiu atributos como nome, categoria e probabilidade_conversao, e usou esses dados para construir uma lógica de recomendação baseada em busca A*, heurística, grafo e fila de prioridade com heapq. Esse tipo de implementação ajuda bastante a visualizar como a Inteligência Artificial pode ser aplicada em sistemas de recomendação, simulando escolhas mais relevantes a partir de critérios definidos no código.

Uma dica interessante para o futuro é usar o método sorted() para listar os produtos com maior probabilidade de conversão antes de executar a busca. Veja este exemplo:


produtos_ordenados = sorted(produtos_exemplo, key=lambda produto: produto.probabilidade_conversao, reverse=True)

for produto in produtos_ordenados:
    print(produto.nome, produto.probabilidade_conversao)

Esse código ordena os produtos pela probabilidade_conversao, da maior para a menor, facilitando a análise das recomendações mais promissoras dentro do sistema.

Pensando em uma evolução do projeto, que outros critérios você adicionaria à heurística para deixar esse sistema de recomendação mais próximo de uma experiência real de usuário?

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