MeliGraph (MeliGraph v0.3.0)

Copy Markdown View Source

MeliGraph — Motor de Recomendação baseado em Grafos para Elixir.

Biblioteca para recomendações baseadas em teoria dos grafos, inspirada nos sistemas WTF (Who to Follow) e GraphJet do Twitter, e nos padrões de engenharia do Oban.

Uso

# Iniciar uma instância
MeliGraph.start_link(name: :my_graph, graph_type: :bipartite, testing: :sync)

# Inserir arestas
MeliGraph.insert_edge(:my_graph, "user:1", "post:a", :like)

# Obter recomendações
{:ok, recs} = MeliGraph.recommend(:my_graph, "user:1", :content)

Múltiplas instâncias

Cada instância tem seu próprio namespace via Registry, permitindo múltiplos grafos independentes no mesmo node:

MeliGraph.start_link(name: :follows, graph_type: :directed)
MeliGraph.start_link(name: :interactions, graph_type: :bipartite)

Summary

Functions

Retorna o número total de arestas no grafo.

Retorna true se há embeddings LightGCN carregados na instância.

Insere uma aresta no grafo, com peso opcional (default 1.0).

Carrega embeddings pré-treinados na instância (em ETS com TTL :infinity).

Retorna os vizinhos de um vértice no grafo.

Retorna o nó que hospeda o grafo: Node.self() em :local ou no nó dono; o nó dono em :horde a partir de outro nó; nil se indisponível.

Retorna true quando a instância terminou de reconstruir o grafo via a MFA on_ready (ou imediatamente, se on_ready for nil).

Retorna top-N recomendações para um vértice.

Inicia uma instância do MeliGraph com a configuração fornecida.

Treina embeddings LightGCN com base no estado atual do grafo.

Retorna o número total de vértices mapeados.

Functions

edge_count(name)

@spec edge_count(atom()) :: non_neg_integer()

Retorna o número total de arestas no grafo.

embeddings_ready?(name)

@spec embeddings_ready?(atom()) :: boolean()

Retorna true se há embeddings LightGCN carregados na instância.

Quando false, chamadas a recommend/4 com algorithm: :lightgcn fazem fallback transparente para SALSA.

insert_edge(name, source, target, edge_type, weight \\ 1.0)

@spec insert_edge(atom(), term(), term(), atom(), float()) :: :ok

Insere uma aresta no grafo, com peso opcional (default 1.0).

No modo :sync, a inserção é síncrona. No modo :disabled, a inserção é assíncrona (fire-and-forget).

O peso é usado pelo LightGCN como entrada na matriz de adjacência ponderada à = D^(-1/2) · W · D^(-1/2). Quando múltiplas arestas user↔item existem (ex.: like + comentário), os pesos são somados. Os demais algoritmos (PageRank, SALSA, etc.) ignoram o peso na v0.2.

load_embeddings(name, binary)

@spec load_embeddings(atom(), binary()) :: :ok | {:error, :invalid_binary}

Carrega embeddings pré-treinados na instância (em ETS com TTL :infinity).

Substitui qualquer embedding anterior. Retorna {:error, :invalid_binary} se o binário não for um payload válido produzido por train_embeddings/2.

neighbors(name, entity_id, direction, opts \\ [])

@spec neighbors(atom(), term(), :outgoing | :incoming, keyword()) :: [term()]

Retorna os vizinhos de um vértice no grafo.

Opções

  • :type - filtrar por tipo de aresta (opcional)

owner_node(name)

@spec owner_node(atom()) :: node() | nil

Retorna o nó que hospeda o grafo: Node.self() em :local ou no nó dono; o nó dono em :horde a partir de outro nó; nil se indisponível.

Em modo distribuído, use para escolher onde rodar operações longas como train_embeddings/2 (treine no dono).

ready?(name)

@spec ready?(atom()) :: boolean()

Retorna true quando a instância terminou de reconstruir o grafo via a MFA on_ready (ou imediatamente, se on_ready for nil).

Útil para gatear leituras durante o boot frio ou logo após um failover, quando o grafo no nó dono ainda está sendo repovoado da fonte da verdade.

recommend(name, entity_id, type, opts \\ [])

@spec recommend(atom(), term(), atom(), keyword()) ::
  {:ok, [{term(), float()}]} | {:error, term()}

Retorna top-N recomendações para um vértice.

Opções

  • :algorithm - :pagerank ou :salsa (padrão: :pagerank)
  • :top_k - número de resultados (padrão: depende do algoritmo)

Opções adicionais são passadas diretamente para o algoritmo.

start_link(opts)

@spec start_link(keyword()) :: Supervisor.on_start()

Inicia uma instância do MeliGraph com a configuração fornecida.

Opções

  • :name - nome da instância (obrigatório)
  • :graph_type - :directed ou :bipartite (obrigatório)
  • :testing - :disabled ou :sync (padrão: :disabled)
  • :segment_max_edges - máximo de arestas por segmento (padrão: 1_000_000)

Veja MeliGraph.Config para todas as opções.

train_embeddings(name, opts \\ [])

@spec train_embeddings(
  atom(),
  keyword()
) :: {:ok, binary()} | {:error, term()}

Treina embeddings LightGCN com base no estado atual do grafo.

Retorna um binário serializado com os embeddings treinados. A lib não persiste nada — o binário deve ser salvo pelo caller (Postgres, R2, S3...) e recarregado depois via load_embeddings/2.

Opções

  • :user_prefix - prefixo dos vértices do lado "usuário" (obrigatório)
  • :embedding_dim - dimensão dos embeddings (padrão: 64)
  • :layers - número de camadas LGC (padrão: 3)
  • :epochs - épocas de treinamento (padrão: 1000)
  • :batch_size - tamanho do mini-batch BPR (padrão: 1024)
  • :learning_rate - taxa de aprendizado Adam (padrão: 0.001)
  • :lambda - regularização L2 (padrão: 1.0e-4)

vertex_count(name)

@spec vertex_count(atom()) :: non_neg_integer()

Retorna o número total de vértices mapeados.