<!-- CANARY: REQ=REQ-DOCS-001; FEATURE="Docs"; ASPECT=Documentation; STATUS=TESTED; OWNER=docs; UPDATED=2026-01-15 -->
<h2 id="machine-learning-integration-with-geode" class="position-relative d-flex align-items-center group">
<span>Machine Learning Integration with Geode</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="machine-learning-integration-with-geode"
aria-haspopup="dialog"
aria-label="Share link: Machine Learning Integration with Geode">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h2><div id="headingShareModal" class="heading-share-modal" role="dialog" aria-modal="true" aria-labelledby="headingShareTitle" hidden>
<div class="hsm-dialog" role="document">
<div class="hsm-header">
<h2 id="headingShareTitle" class="h6 mb-0 fw-bold">Share this section</h2>
<button type="button" class="hsm-close" aria-label="Close">
<i class="fa-solid fa-xmark"></i>
</button>
</div>
<div class="hsm-body">
<label for="headingShareInput" class="form-label small text-muted mb-1 text-uppercase fw-bold" style="font-size: 0.7rem; letter-spacing: 0.5px;">Permalink</label>
<div class="input-group mb-4 hsm-url-group">
<input id="headingShareInput" type="text" class="form-control font-monospace" readonly aria-readonly="true" style="font-size: 0.85rem;" />
<button class="btn btn-primary hsm-copy" type="button" aria-label="Copy" title="Copy">
<i class="fa-duotone fa-clipboard" aria-hidden="true"></i>
</button>
</div>
<div class="small fw-bold mb-2 text-muted text-uppercase" style="font-size: 0.7rem; letter-spacing: 0.5px;">Share via</div>
<div class="hsm-share-grid">
<a id="share-twitter" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-twitter me-2"></i>Twitter
</a>
<a id="share-linkedin" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-linkedin me-2"></i>LinkedIn
</a>
<a id="share-facebook" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-facebook me-2"></i>Facebook
</a>
</div>
</div>
</div>
</div>
<style>
.heading-share-modal {
position: fixed;
inset: 0;
display: flex;
justify-content: center;
align-items: center;
background: rgba(0, 0, 0, 0.6);
z-index: 1050;
padding: 1rem;
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
}
.heading-share-modal[hidden] { display: none !important; }
.hsm-dialog {
max-width: 420px;
width: 100%;
background: var(--bs-body-bg, #fff);
color: var(--bs-body-color, #212529);
border: 1px solid var(--bs-border-color, rgba(0,0,0,0.1));
border-radius: 1rem;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
overflow: hidden;
animation: hsm-fade-in 0.2s ease-out;
}
@keyframes hsm-fade-in {
from { opacity: 0; transform: scale(0.95); }
to { opacity: 1; transform: scale(1); }
}
[data-bs-theme="dark"] .hsm-dialog {
background: #1e293b;
border-color: rgba(255,255,255,0.1);
color: #f8f9fa;
}
.hsm-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 1.5rem;
border-bottom: 1px solid var(--bs-border-color, rgba(0,0,0,0.1));
background: rgba(0,0,0,0.02);
}
[data-bs-theme="dark"] .hsm-header {
background: rgba(255,255,255,0.02);
border-color: rgba(255,255,255,0.1);
}
.hsm-close {
background: transparent;
border: none;
color: inherit;
opacity: 0.5;
padding: 0.25rem 0.5rem;
border-radius: 0.25rem;
font-size: 1.2rem;
line-height: 1;
transition: opacity 0.2s;
}
.hsm-close:hover {
opacity: 1;
}
.hsm-body {
padding: 1.5rem;
}
.hsm-url-group {
display: flex !important;
align-items: stretch;
}
.hsm-url-group .form-control {
flex: 1;
min-width: 0;
margin: 0;
background: var(--bs-secondary-bg, #f8f9fa);
border-color: var(--bs-border-color, #dee2e6);
border-top-right-radius: 0;
border-bottom-right-radius: 0;
height: 42px;
}
.hsm-url-group .btn {
flex: 0 0 auto;
margin: 0;
margin-left: -1px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
height: 42px;
display: flex;
align-items: center;
justify-content: center;
padding: 0 1.25rem;
z-index: 2;
}
[data-bs-theme="dark"] .hsm-url-group .form-control {
background: #0f172a;
border-color: #334155;
color: #e2e8f0;
}
.hsm-share-grid {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.hsm-share-grid .btn {
display: flex;
align-items: center;
justify-content: center;
font-size: 0.9rem;
padding: 0.6rem;
border-color: var(--bs-border-color);
width: 100%;
}
[data-bs-theme="dark"] .hsm-share-grid .btn {
color: #e2e8f0;
border-color: #475569;
}
[data-bs-theme="dark"] .hsm-share-grid .btn:hover {
background: #334155;
border-color: #cbd5e1;
}
</style>
<script>
(function(){
const modal = document.getElementById('headingShareModal');
if(!modal) return;
const input = modal.querySelector('#headingShareInput');
const copyBtn = modal.querySelector('.hsm-copy');
const twitter = modal.querySelector('#share-twitter');
const linkedin = modal.querySelector('#share-linkedin');
const facebook = modal.querySelector('#share-facebook');
const closeBtn = modal.querySelector('.hsm-close');
let lastFocus=null;
let trapBound=false;
function buildUrl(id){ return window.location.origin + window.location.pathname + '#' + id; }
function isOpen(){ return !modal.hasAttribute('hidden'); }
function hydrate(id){
const url=buildUrl(id);
input.value=url;
const enc=encodeURIComponent(url);
const text=encodeURIComponent(document.title);
if(twitter) twitter.href=`https://twitter.com/intent/tweet?url=${enc}&text=${text}`;
if(linkedin) linkedin.href=`https://www.linkedin.com/sharing/share-offsite/?url=${enc}`;
if(facebook) facebook.href=`https://www.facebook.com/sharer/sharer.php?u=${enc}`;
}
function openModal(id){
lastFocus=document.activeElement;
hydrate(id);
if(!isOpen()){
modal.removeAttribute('hidden');
}
requestAnimationFrame(()=>{ input.focus(); });
trapFocus();
}
function closeModal(){
if(!isOpen()) return;
modal.setAttribute('hidden','');
if(lastFocus && typeof lastFocus.focus==='function') lastFocus.focus();
}
function copyCurrent(){
try{ navigator.clipboard.writeText(input.value).then(()=>feedback(true),()=>fallback()); }
catch(e){ fallback(); }
}
function fallback(){ input.select(); try{ document.execCommand('copy'); feedback(true);}catch(e){ feedback(false);} }
function feedback(ok){ if(!copyBtn) return; const icon=copyBtn.querySelector('i'); if(!icon) return; const prev=copyBtn.getAttribute('data-prev')||icon.className; if(!copyBtn.getAttribute('data-prev')) copyBtn.setAttribute('data-prev',prev); icon.className= ok ? 'fa-duotone fa-clipboard-check':'fa-duotone fa-circle-exclamation'; setTimeout(()=>{ icon.className=prev; },1800); }
function handleShareClick(e){ e.preventDefault(); const btn=e.currentTarget; const id=btn.getAttribute('data-share-target'); if(id) openModal(id); }
function bindShareButtons(){
document.querySelectorAll('.h-share').forEach(btn=>{
if(!btn.dataset.hShareBound){ btn.addEventListener('click', handleShareClick); btn.dataset.hShareBound='1'; }
});
}
bindShareButtons();
if(document.readyState==='loading'){
document.addEventListener('DOMContentLoaded', bindShareButtons);
} else {
requestAnimationFrame(bindShareButtons);
}
document.addEventListener('click', function(e){
const shareBtn=e.target.closest && e.target.closest('.h-share');
if(shareBtn && !shareBtn.dataset.hShareBound){ handleShareClick.call(shareBtn, e); }
}, true);
document.addEventListener('click', e=>{
if(e.target===modal) closeModal();
if(e.target.closest && e.target.closest('.hsm-close')){ e.preventDefault(); closeModal(); }
if(copyBtn && (e.target===copyBtn || (e.target.closest && e.target.closest('.hsm-copy')))) { e.preventDefault(); copyCurrent(); }
});
document.addEventListener('keydown', e=>{ if(e.key==='Escape' && isOpen()) closeModal(); });
function trapFocus(){
if(trapBound) return;
trapBound=true;
modal.addEventListener('keydown', f=>{ if(f.key==='Tab' && isOpen()){ const focusable=[...modal.querySelectorAll('a[href],button,input,textarea,select,[tabindex]:not([tabindex="-1"])')].filter(el=>!el.hasAttribute('disabled')); if(!focusable.length) return; const first=focusable[0]; const last=focusable[focusable.length-1]; if(f.shiftKey && document.activeElement===first){ f.preventDefault(); last.focus(); } else if(!f.shiftKey && document.activeElement===last){ f.preventDefault(); first.focus(); } } });
}
if(closeBtn) closeBtn.addEventListener('click', e=>{ e.preventDefault(); closeModal(); });
})();
</script><p>Geode serves as a powerful foundation for machine learning workflows, providing graph-based feature engineering, embedding storage, and deployment infrastructure for graph neural networks (GNNs) and ML models that leverage network structure.</p>
<h3 id="graph-data-for-machine-learning" class="position-relative d-flex align-items-center group">
<span>Graph Data for Machine Learning</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="graph-data-for-machine-learning"
aria-haspopup="dialog"
aria-label="Share link: Graph Data for Machine Learning">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><p>Graphs naturally encode relational information that traditional machine learning struggles to capture from flat tables. Geode enables extraction of topological features, generation of graph embeddings, and serving of ML predictions at scale.</p>
<h4 id="why-graphs-for-ml" class="position-relative d-flex align-items-center group">
<span>Why Graphs for ML</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="why-graphs-for-ml"
aria-haspopup="dialog"
aria-label="Share link: Why Graphs for ML">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Rich Feature Space</strong>: Graph topology provides features like degree centrality, clustering coefficients, and PageRank that capture network position.</p>
<p><strong>Relational Learning</strong>: Graph neural networks learn representations that incorporate both node attributes and network structure.</p>
<p><strong>Feature Engineering</strong>: Extract complex patterns (motifs, communities, paths) as features for traditional ML models.</p>
<p><strong>Model Deployment</strong>: Store trained models and serve predictions using graph context for real-time inference.</p>
<h3 id="graph-feature-extraction" class="position-relative d-flex align-items-center group">
<span>Graph Feature Extraction</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="graph-feature-extraction"
aria-haspopup="dialog"
aria-label="Share link: Graph Feature Extraction">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="topological-features" class="position-relative d-flex align-items-center group">
<span>Topological Features</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="topological-features"
aria-haspopup="dialog"
aria-label="Share link: Topological Features">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Extract</span><span class="w"> </span><span class="py">node</span><span class="err">-</span><span class="py">level</span><span class="w"> </span><span class="py">features</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">ML</span><span class="w"> </span><span class="py">training</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">n</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">n</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COUNT</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">(</span><span class="py">n</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-></span><span class="p">()</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">out_degree</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COUNT</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">(</span><span class="py">n</span><span class="p">)</span><span class="err"><-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-</span><span class="p">()</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">in_degree</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COUNT</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">(</span><span class="py">n</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-></span><span class="p">()</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">n</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">reciprocal_connections</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">n</span><span class="p">,</span><span class="w"> </span><span class="py">out_degree</span><span class="p">,</span><span class="w"> </span><span class="py">in_degree</span><span class="p">,</span><span class="w"> </span><span class="py">reciprocal_connections</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">CASE</span><span class="w"> </span><span class="py">WHEN</span><span class="w"> </span><span class="py">out_degree</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">THEN</span><span class="w"> </span><span class="py">reciprocal_connections</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">1</span><span class="mf">.0</span><span class="w"> </span><span class="err">/</span><span class="w"> </span><span class="py">out_degree</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">ELSE</span><span class="w"> </span><span class="py">0</span><span class="w"> </span><span class="py">END</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">reciprocity_rate</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">n</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">friend</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">fof</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">EXISTS</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">(</span><span class="py">n</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">fof</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="py">n</span><span class="w"> </span><span class="err"><></span><span class="w"> </span><span class="py">fof</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">n</span><span class="p">,</span><span class="w"> </span><span class="py">out_degree</span><span class="p">,</span><span class="w"> </span><span class="py">in_degree</span><span class="p">,</span><span class="w"> </span><span class="py">reciprocity_rate</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COUNT</span><span class="p">(</span><span class="py">DISTINCT</span><span class="w"> </span><span class="py">fof</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">potential_connections</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">n</span><span class="err">.</span><span class="py">id</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">user_id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">out_degree</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">in_degree</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">reciprocity_rate</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">potential_connections</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">out_degree</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">1</span><span class="mf">.0</span><span class="w"> </span><span class="err">/</span><span class="w"> </span><span class="p">(</span><span class="py">in_degree</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">1</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">influence_ratio</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">n</span><span class="err">.</span><span class="py">id</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="community-based-features" class="position-relative d-flex align-items-center group">
<span>Community-Based Features</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="community-based-features"
aria-haspopup="dialog"
aria-label="Share link: Community-Based Features">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Extract</span><span class="w"> </span><span class="py">community</span><span class="w"> </span><span class="py">membership</span><span class="w"> </span><span class="py">as</span><span class="w"> </span><span class="py">features</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">n</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">n</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">n</span><span class="err">.</span><span class="py">community_id</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">community</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">n</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">neighbor</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">n</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">community</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COUNT</span><span class="p">(</span><span class="py">CASE</span><span class="w"> </span><span class="py">WHEN</span><span class="w"> </span><span class="py">neighbor</span><span class="err">.</span><span class="py">community_id</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">community</span><span class="w"> </span><span class="py">THEN</span><span class="w"> </span><span class="py">1</span><span class="w"> </span><span class="py">END</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">internal_connections</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COUNT</span><span class="p">(</span><span class="py">CASE</span><span class="w"> </span><span class="py">WHEN</span><span class="w"> </span><span class="py">neighbor</span><span class="err">.</span><span class="py">community_id</span><span class="w"> </span><span class="err"><></span><span class="w"> </span><span class="py">community</span><span class="w"> </span><span class="py">THEN</span><span class="w"> </span><span class="py">1</span><span class="w"> </span><span class="py">END</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">external_connections</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">n</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">community</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">internal_connections</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">external_connections</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">internal_connections</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">1</span><span class="mf">.0</span><span class="w"> </span><span class="err">/</span><span class="w"> </span><span class="p">(</span><span class="py">internal_connections</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">external_connections</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">1</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">homophily_score</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="temporal-features" class="position-relative d-flex align-items-center group">
<span>Temporal Features</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="temporal-features"
aria-haspopup="dialog"
aria-label="Share link: Temporal Features">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Extract</span><span class="w"> </span><span class="py">temporal</span><span class="w"> </span><span class="py">interaction</span><span class="w"> </span><span class="py">patterns</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">user</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="err">-</span><span class="p">[</span><span class="py">action</span><span class="p">:</span><span class="nc">PURCHASED</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">product</span><span class="p">:</span><span class="nc">Product</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">action</span><span class="err">.</span><span class="py">timestamp</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">CURRENT_TIMESTAMP</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="py">INTERVAL</span><span class="w"> </span><span class="err">'</span><span class="py">90</span><span class="err">'</span><span class="w"> </span><span class="py">DAY</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">user</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COUNT</span><span class="p">(</span><span class="py">action</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">total_purchases</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SUM</span><span class="p">(</span><span class="py">action</span><span class="err">.</span><span class="py">amount</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">total_spent</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AVG</span><span class="p">(</span><span class="py">action</span><span class="err">.</span><span class="py">amount</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">avg_purchase</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">STDDEV</span><span class="p">(</span><span class="py">action</span><span class="err">.</span><span class="py">amount</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">purchase_variance</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COUNT</span><span class="p">(</span><span class="py">DISTINCT</span><span class="w"> </span><span class="py">DATE</span><span class="p">(</span><span class="py">action</span><span class="err">.</span><span class="py">timestamp</span><span class="p">))</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">active_days</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">user</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">total_purchases</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">total_spent</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">avg_purchase</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">purchase_variance</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">active_days</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">total_purchases</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">1</span><span class="mf">.0</span><span class="w"> </span><span class="err">/</span><span class="w"> </span><span class="py">active_days</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">purchase_frequency</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="storing-and-managing-embeddings" class="position-relative d-flex align-items-center group">
<span>Storing and Managing Embeddings</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="storing-and-managing-embeddings"
aria-haspopup="dialog"
aria-label="Share link: Storing and Managing Embeddings">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="embedding-storage" class="position-relative d-flex align-items-center group">
<span>Embedding Storage</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="embedding-storage"
aria-haspopup="dialog"
aria-label="Share link: Embedding Storage">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Store</span><span class="w"> </span><span class="py">pre</span><span class="err">-</span><span class="py">computed</span><span class="w"> </span><span class="py">node</span><span class="w"> </span><span class="py">embeddings</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">user</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$user_id</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">SET</span><span class="w"> </span><span class="py">user</span><span class="err">.</span><span class="py">embedding</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nv">$embedding_vector</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">user</span><span class="err">.</span><span class="py">embedding_model</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">'</span><span class="py">node2vec</span><span class="err">-</span><span class="py">v1</span><span class="err">'</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">user</span><span class="err">.</span><span class="py">embedding_timestamp</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">CURRENT_TIMESTAMP</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Store</span><span class="w"> </span><span class="py">edge</span><span class="w"> </span><span class="py">embeddings</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">:</span><span class="nc">Node</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$node_a</span><span class="p">})</span><span class="err">-</span><span class="p">[</span><span class="nc">r</span><span class="p">:</span><span class="nc">RELATED</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">b</span><span class="p">:</span><span class="nc">Node</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$node_b</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">SET</span><span class="w"> </span><span class="py">r</span><span class="err">.</span><span class="py">embedding</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nv">$edge_embedding</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">r</span><span class="err">.</span><span class="py">embedding_dim</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">128</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="batch-embedding-updates" class="position-relative d-flex align-items-center group">
<span>Batch Embedding Updates</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="batch-embedding-updates"
aria-haspopup="dialog"
aria-label="Share link: Batch Embedding Updates">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Update</span><span class="w"> </span><span class="py">embeddings</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">multiple</span><span class="w"> </span><span class="py">nodes</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">UNWIND</span><span class="w"> </span><span class="nv">$embeddings</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">emb</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">n</span><span class="p">:</span><span class="nc">Node</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nc">emb</span><span class="err">.</span><span class="py">node_id</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SET</span><span class="w"> </span><span class="py">n</span><span class="err">.</span><span class="py">embedding</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">emb</span><span class="err">.</span><span class="py">vector</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">n</span><span class="err">.</span><span class="py">updated</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">CURRENT_TIMESTAMP</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CALL</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WITH</span><span class="w"> </span><span class="py">n</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="py">Optionally</span><span class="w"> </span><span class="py">update</span><span class="w"> </span><span class="py">downstream</span><span class="w"> </span><span class="py">computations</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="py">TRANSACTIONS</span><span class="w"> </span><span class="py">OF</span><span class="w"> </span><span class="py">1000</span><span class="w"> </span><span class="py">ROWS</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="embedding-based-similarity" class="position-relative d-flex align-items-center group">
<span>Embedding-Based Similarity</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="embedding-based-similarity"
aria-haspopup="dialog"
aria-label="Share link: Embedding-Based Similarity">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Find</span><span class="w"> </span><span class="py">similar</span><span class="w"> </span><span class="py">nodes</span><span class="w"> </span><span class="py">using</span><span class="w"> </span><span class="py">embedding</span><span class="w"> </span><span class="py">similarity</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">target</span><span class="p">:</span><span class="nc">Product</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$product_id</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">candidate</span><span class="p">:</span><span class="nc">Product</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">candidate</span><span class="w"> </span><span class="err"><></span><span class="w"> </span><span class="py">target</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="py">candidate</span><span class="err">.</span><span class="py">embedding</span><span class="w"> </span><span class="py">IS</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">NULL</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">candidate</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COSINE_SIMILARITY</span><span class="p">(</span><span class="py">target</span><span class="err">.</span><span class="py">embedding</span><span class="p">,</span><span class="w"> </span><span class="py">candidate</span><span class="err">.</span><span class="py">embedding</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">similarity</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">similarity</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">0</span><span class="mf">.75</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">candidate</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">candidate</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">similarity</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">similarity</span><span class="w"> </span><span class="py">DESC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LIMIT</span><span class="w"> </span><span class="py">20</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="graph-neural-network-support" class="position-relative d-flex align-items-center group">
<span>Graph Neural Network Support</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="graph-neural-network-support"
aria-haspopup="dialog"
aria-label="Share link: Graph Neural Network Support">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="neighborhood-aggregation" class="position-relative d-flex align-items-center group">
<span>Neighborhood Aggregation</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="neighborhood-aggregation"
aria-haspopup="dialog"
aria-label="Share link: Neighborhood Aggregation">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Aggregate</span><span class="w"> </span><span class="py">neighbor</span><span class="w"> </span><span class="py">features</span><span class="w"> </span><span class="p">(</span><span class="py">GNN</span><span class="err">-</span><span class="py">style</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">node</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$user_id</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">node</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">neighbor</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">node</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COLLECT</span><span class="p">(</span><span class="py">neighbor</span><span class="err">.</span><span class="py">feature_vector</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">neighbor_features</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">node</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">node</span><span class="err">.</span><span class="py">feature_vector</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">node_features</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AVG</span><span class="p">([</span><span class="py">f</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="py">neighbor_features</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">f</span><span class="p">])</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">aggregated_neighbor_features</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">MAX</span><span class="p">([</span><span class="py">f</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="py">neighbor_features</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">f</span><span class="p">])</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">max_neighbor_features</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="multi-hop-aggregation" class="position-relative d-flex align-items-center group">
<span>Multi-Hop Aggregation</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="multi-hop-aggregation"
aria-haspopup="dialog"
aria-label="Share link: Multi-Hop Aggregation">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">2</span><span class="err">-</span><span class="py">hop</span><span class="w"> </span><span class="py">neighborhood</span><span class="w"> </span><span class="py">aggregation</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">node</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$user_id</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">node</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="err">*</span><span class="py">1</span><span class="err">.</span><span class="mf">.2</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">neighbor</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">node</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">neighbor</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">LENGTH</span><span class="p">((</span><span class="py">node</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="err">*</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">neighbor</span><span class="p">))</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">distance</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">node</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">distance</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COLLECT</span><span class="p">(</span><span class="py">neighbor</span><span class="err">.</span><span class="py">embedding</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">embeddings_at_distance</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">node</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AVG</span><span class="p">([</span><span class="py">e</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="py">embeddings_at_distance</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">distance</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">1</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">e</span><span class="p">])</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">first_hop_agg</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AVG</span><span class="p">([</span><span class="py">e</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="py">embeddings_at_distance</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">distance</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">2</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">e</span><span class="p">])</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">second_hop_agg</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="attention-mechanisms" class="position-relative d-flex align-items-center group">
<span>Attention Mechanisms</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="attention-mechanisms"
aria-haspopup="dialog"
aria-label="Share link: Attention Mechanisms">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Weighted</span><span class="w"> </span><span class="py">neighbor</span><span class="w"> </span><span class="py">aggregation</span><span class="w"> </span><span class="p">(</span><span class="py">attention</span><span class="err">-</span><span class="py">like</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">node</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$user_id</span><span class="p">})</span><span class="err">-</span><span class="p">[</span><span class="nc">r</span><span class="p">:</span><span class="nc">INTERACTS_WITH</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">neighbor</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">node</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">neighbor</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">r</span><span class="err">.</span><span class="py">weight</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">attention_weight</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">neighbor</span><span class="err">.</span><span class="py">features</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">neighbor_features</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">node</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SUM</span><span class="p">(</span><span class="py">attention_weight</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">neighbor_features</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">weighted_aggregation</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SUM</span><span class="p">(</span><span class="py">attention_weight</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">total_weight</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">node</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">weighted_aggregation</span><span class="w"> </span><span class="err">/</span><span class="w"> </span><span class="py">total_weight</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">attended_features</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="model-deployment-and-inference" class="position-relative d-flex align-items-center group">
<span>Model Deployment and Inference</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="model-deployment-and-inference"
aria-haspopup="dialog"
aria-label="Share link: Model Deployment and Inference">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="storing-trained-models" class="position-relative d-flex align-items-center group">
<span>Storing Trained Models</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="storing-trained-models"
aria-haspopup="dialog"
aria-label="Share link: Storing Trained Models">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Store</span><span class="w"> </span><span class="py">model</span><span class="w"> </span><span class="py">metadata</span><span class="w"> </span><span class="py">and</span><span class="w"> </span><span class="py">parameters</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="p">(</span><span class="py">model</span><span class="p">:</span><span class="nc">MLModel</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">user_churn_v2</span><span class="err">'</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">type</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">XGBoost</span><span class="err">'</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nc">version</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">2</span><span class="mf">.0</span><span class="err">'</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">features</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="err">'</span><span class="nc">degree</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">activity_rate</span><span class="err">'</span><span class="p">,</span><span class="w"> </span><span class="err">'</span><span class="py">avg_session_time</span><span class="err">'</span><span class="p">],</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">accuracy</span><span class="p">:</span><span class="w"> </span><span class="nc">0</span><span class="mf">.89</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">trained_date</span><span class="p">:</span><span class="w"> </span><span class="nc">CURRENT_TIMESTAMP</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">model_path</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">s3</span><span class="p">:</span><span class="err">//</span><span class="nc">models</span><span class="err">/</span><span class="py">user_churn_v2</span><span class="err">.</span><span class="py">pkl</span><span class="err">'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">})</span><span class="err">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Link</span><span class="w"> </span><span class="py">model</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="py">feature</span><span class="w"> </span><span class="py">definitions</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">model</span><span class="p">:</span><span class="nc">MLModel</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">user_churn_v2</span><span class="err">'</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="p">(</span><span class="py">model</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">USES_FEATURE</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">feature</span><span class="p">:</span><span class="nc">Feature</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">name</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">user_degree</span><span class="err">'</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">query</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">MATCH</span><span class="w"> </span><span class="p">(</span><span class="nc">u</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">COUNT</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">(</span><span class="py">u</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-></span><span class="p">()</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">degree</span><span class="err">'</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">type</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">integer</span><span class="err">'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">})</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="real-time-prediction-serving" class="position-relative d-flex align-items-center group">
<span>Real-Time Prediction Serving</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="real-time-prediction-serving"
aria-haspopup="dialog"
aria-label="Share link: Real-Time Prediction Serving">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Extract</span><span class="w"> </span><span class="py">features</span><span class="w"> </span><span class="py">and</span><span class="w"> </span><span class="py">serve</span><span class="w"> </span><span class="py">prediction</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">user</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$user_id</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">WITH</span><span class="w"> </span><span class="py">user</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COUNT</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">(</span><span class="py">user</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-></span><span class="p">()</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">degree</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COUNT</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">(</span><span class="py">user</span><span class="p">)</span><span class="err">-</span><span class="p">[</span><span class="py">action</span><span class="p">:</span><span class="nc">ACTION</span><span class="p">]</span><span class="err">-></span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">action</span><span class="err">.</span><span class="py">timestamp</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">CURRENT_TIMESTAMP</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="py">INTERVAL</span><span class="w"> </span><span class="err">'</span><span class="py">30</span><span class="err">'</span><span class="w"> </span><span class="py">DAY</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">recent_activity</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AVG</span><span class="p">([</span><span class="py">s</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="p">[(</span><span class="py">user</span><span class="p">)</span><span class="err">-</span><span class="p">[</span><span class="py">session</span><span class="p">:</span><span class="nc">SESSION</span><span class="p">]</span><span class="err">-></span><span class="p">()</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">session</span><span class="err">.</span><span class="py">duration</span><span class="p">]])</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">avg_session_time</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">//</span><span class="w"> </span><span class="py">Features</span><span class="w"> </span><span class="py">extracted</span><span class="p">,</span><span class="w"> </span><span class="py">would</span><span class="w"> </span><span class="py">call</span><span class="w"> </span><span class="py">external</span><span class="w"> </span><span class="py">model</span><span class="w"> </span><span class="py">in</span><span class="w"> </span><span class="py">application</span><span class="w"> </span><span class="py">layer</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">user</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">degree</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">recent_activity</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">avg_session_time</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="batch-prediction-storage" class="position-relative d-flex align-items-center group">
<span>Batch Prediction Storage</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="batch-prediction-storage"
aria-haspopup="dialog"
aria-label="Share link: Batch Prediction Storage">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Store</span><span class="w"> </span><span class="py">prediction</span><span class="w"> </span><span class="py">results</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">UNWIND</span><span class="w"> </span><span class="nv">$predictions</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">pred</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">user</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nc">pred</span><span class="err">.</span><span class="py">user_id</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SET</span><span class="w"> </span><span class="py">user</span><span class="err">.</span><span class="py">churn_probability</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">pred</span><span class="err">.</span><span class="py">probability</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">user</span><span class="err">.</span><span class="py">churn_predicted_at</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">CURRENT_TIMESTAMP</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">user</span><span class="err">.</span><span class="py">churn_model_version</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">'</span><span class="py">v2</span><span class="mf">.0</span><span class="err">'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CALL</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WITH</span><span class="w"> </span><span class="py">user</span><span class="p">,</span><span class="w"> </span><span class="py">pred</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="py">Optionally</span><span class="w"> </span><span class="py">trigger</span><span class="w"> </span><span class="py">actions</span><span class="w"> </span><span class="py">based</span><span class="w"> </span><span class="kd">on</span><span class="w"> </span><span class="py">prediction</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WITH</span><span class="w"> </span><span class="py">user</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">pred</span><span class="err">.</span><span class="py">probability</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">0</span><span class="mf">.7</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">CREATE</span><span class="w"> </span><span class="p">(</span><span class="py">alert</span><span class="p">:</span><span class="nc">Alert</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">type</span><span class="p">:</span><span class="w"> </span><span class="err">'</span><span class="nc">HIGH_CHURN_RISK</span><span class="err">'</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nc">user_id</span><span class="p">:</span><span class="w"> </span><span class="nc">user</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">probability</span><span class="p">:</span><span class="w"> </span><span class="nc">pred</span><span class="err">.</span><span class="py">probability</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">created</span><span class="p">:</span><span class="w"> </span><span class="nc">CURRENT_TIMESTAMP</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="py">TRANSACTIONS</span><span class="w"> </span><span class="py">OF</span><span class="w"> </span><span class="py">1000</span><span class="w"> </span><span class="py">ROWS</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="graph-sampling-for-training" class="position-relative d-flex align-items-center group">
<span>Graph Sampling for Training</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="graph-sampling-for-training"
aria-haspopup="dialog"
aria-label="Share link: Graph Sampling for Training">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="random-walk-sampling" class="position-relative d-flex align-items-center group">
<span>Random Walk Sampling</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="random-walk-sampling"
aria-haspopup="dialog"
aria-label="Share link: Random Walk Sampling">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Generate</span><span class="w"> </span><span class="py">random</span><span class="w"> </span><span class="py">walk</span><span class="w"> </span><span class="py">samples</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">training</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="py">path</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">(</span><span class="py">start</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$start_user</span><span class="p">})</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="err">*</span><span class="nc">5</span><span class="p">]</span><span class="err">-</span><span class="p">(</span><span class="py">end</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">ALL</span><span class="p">(</span><span class="py">step</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="py">RELATIONSHIPS</span><span class="p">(</span><span class="py">path</span><span class="p">)</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">RAND</span><span class="p">()</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">0</span><span class="mf">.5</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">NODES</span><span class="p">(</span><span class="py">path</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">walk_nodes</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="p">[</span><span class="py">n</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="py">walk_nodes</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">n</span><span class="err">.</span><span class="py">id</span><span class="p">]</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">random_walk</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="subgraph-sampling" class="position-relative d-flex align-items-center group">
<span>Subgraph Sampling</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="subgraph-sampling"
aria-haspopup="dialog"
aria-label="Share link: Subgraph Sampling">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Sample</span><span class="w"> </span><span class="py">subgraph</span><span class="w"> </span><span class="py">around</span><span class="w"> </span><span class="py">seed</span><span class="w"> </span><span class="py">nodes</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">seed</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">seed</span><span class="err">.</span><span class="py">id</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="nv">$seed_ids</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">seed</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="err">*</span><span class="py">1</span><span class="err">.</span><span class="mf">.2</span><span class="p">]</span><span class="err">-</span><span class="p">(</span><span class="py">neighbor</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">COLLECT</span><span class="p">(</span><span class="py">DISTINCT</span><span class="w"> </span><span class="py">seed</span><span class="p">)</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">COLLECT</span><span class="p">(</span><span class="py">DISTINCT</span><span class="w"> </span><span class="py">neighbor</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">sampled_nodes</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">UNWIND</span><span class="w"> </span><span class="py">sampled_nodes</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">node</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">node</span><span class="p">)</span><span class="err">-</span><span class="p">[</span><span class="py">r</span><span class="p">:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-</span><span class="p">(</span><span class="py">other</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">other</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="py">sampled_nodes</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">node</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">other</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">TYPE</span><span class="p">(</span><span class="py">r</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">relationship_type</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">node</span><span class="err">.</span><span class="py">features</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">node_features</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="stratified-sampling" class="position-relative d-flex align-items-center group">
<span>Stratified Sampling</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="stratified-sampling"
aria-haspopup="dialog"
aria-label="Share link: Stratified Sampling">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Sample</span><span class="w"> </span><span class="py">balanced</span><span class="w"> </span><span class="py">training</span><span class="w"> </span><span class="py">set</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">positive</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">churned</span><span class="p">:</span><span class="w"> </span><span class="nc">true</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">COLLECT</span><span class="p">(</span><span class="py">positive</span><span class="p">)[</span><span class="err">.</span><span class="mf">.1000</span><span class="p">]</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">positive_samples</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">negative</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">churned</span><span class="p">:</span><span class="w"> </span><span class="nc">false</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">positive_samples</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COLLECT</span><span class="p">(</span><span class="py">negative</span><span class="p">)[</span><span class="err">.</span><span class="mf">.1000</span><span class="p">]</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">negative_samples</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">UNWIND</span><span class="w"> </span><span class="p">(</span><span class="py">positive_samples</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">negative_samples</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">sample</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">sample</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">sample</span><span class="err">.</span><span class="py">churned</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">label</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">sample</span><span class="err">.</span><span class="py">features</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">features</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="feature-engineering-patterns" class="position-relative d-flex align-items-center group">
<span>Feature Engineering Patterns</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="feature-engineering-patterns"
aria-haspopup="dialog"
aria-label="Share link: Feature Engineering Patterns">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="graph-motif-counting" class="position-relative d-flex align-items-center group">
<span>Graph Motif Counting</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="graph-motif-counting"
aria-haspopup="dialog"
aria-label="Share link: Graph Motif Counting">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Count</span><span class="w"> </span><span class="py">triangle</span><span class="w"> </span><span class="py">participation</span><span class="w"> </span><span class="p">(</span><span class="py">motif</span><span class="w"> </span><span class="py">feature</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">user</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$user_id</span><span class="p">})</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="nc">friend1</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">friend2</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">EXISTS</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">(</span><span class="py">user</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">friend2</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">user</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COUNT</span><span class="p">(</span><span class="py">DISTINCT</span><span class="w"> </span><span class="py">friend1</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">triangle_count</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="path-based-features" class="position-relative d-flex align-items-center group">
<span>Path-Based Features</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="path-based-features"
aria-haspopup="dialog"
aria-label="Share link: Path-Based Features">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Extract</span><span class="w"> </span><span class="py">path</span><span class="w"> </span><span class="py">length</span><span class="w"> </span><span class="py">distributions</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">user1</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$user_id</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">MATCH</span><span class="w"> </span><span class="py">path</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">SHORTEST_PATH</span><span class="p">((</span><span class="py">user1</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="err">*</span><span class="p">]</span><span class="err">-</span><span class="p">(</span><span class="py">user2</span><span class="p">:</span><span class="nc">User</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">user2</span><span class="err">.</span><span class="py">category</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">'</span><span class="py">influencer</span><span class="err">'</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">user1</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">[</span><span class="py">len</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="p">[</span><span class="py">LENGTH</span><span class="p">(</span><span class="py">path</span><span class="p">)]</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">len</span><span class="p">]</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">path_lengths</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">user1</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">MIN</span><span class="p">(</span><span class="py">path_lengths</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">min_distance_to_influencer</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AVG</span><span class="p">(</span><span class="py">path_lengths</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">avg_distance_to_influencer</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COUNT</span><span class="p">(</span><span class="py">path_lengths</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">influencer_connections</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="temporal-graph-features" class="position-relative d-flex align-items-center group">
<span>Temporal Graph Features</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="temporal-graph-features"
aria-haspopup="dialog"
aria-label="Share link: Temporal Graph Features">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Extract</span><span class="w"> </span><span class="py">temporal</span><span class="w"> </span><span class="py">evolution</span><span class="w"> </span><span class="py">features</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">user</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$user_id</span><span class="p">})</span><span class="err">-</span><span class="p">[</span><span class="nc">action</span><span class="p">:</span><span class="nc">ACTION</span><span class="p">]</span><span class="err">-></span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">user</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">[</span><span class="py">a</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="py">COLLECT</span><span class="p">(</span><span class="py">action</span><span class="p">)</span><span class="w"> </span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">timestamp</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">timestamp</span><span class="p">]</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">timestamps</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">user</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">[</span><span class="py">i</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="py">RANGE</span><span class="p">(</span><span class="py">1</span><span class="p">,</span><span class="w"> </span><span class="py">SIZE</span><span class="p">(</span><span class="py">timestamps</span><span class="p">)</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="py">1</span><span class="p">)</span><span class="w"> </span><span class="p">|</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">DURATION</span><span class="err">.</span><span class="py">BETWEEN</span><span class="p">(</span><span class="py">timestamps</span><span class="p">[</span><span class="py">i</span><span class="err">-</span><span class="py">1</span><span class="p">],</span><span class="w"> </span><span class="py">timestamps</span><span class="p">[</span><span class="py">i</span><span class="p">])</span><span class="err">.</span><span class="py">days</span><span class="p">]</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">inter_event_times</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">user</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AVG</span><span class="p">(</span><span class="py">inter_event_times</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">avg_inter_event_days</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">STDDEV</span><span class="p">(</span><span class="py">inter_event_times</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">inter_event_variance</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SIZE</span><span class="p">(</span><span class="py">timestamps</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">total_events</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="best-practices" class="position-relative d-flex align-items-center group">
<span>Best Practices</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="best-practices"
aria-haspopup="dialog"
aria-label="Share link: Best Practices">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="feature-engineering" class="position-relative d-flex align-items-center group">
<span>Feature Engineering</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="feature-engineering"
aria-haspopup="dialog"
aria-label="Share link: Feature Engineering">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Domain Knowledge</strong>: Combine graph topology with domain-specific features for best results.</p>
<p><strong>Feature Scaling</strong>: Normalize degree-based features as graphs grow to maintain consistent model behavior.</p>
<p><strong>Temporal Consistency</strong>: Use time windows that match your prediction horizon (30-day features for 30-day churn prediction).</p>
<p><strong>Feature Updates</strong>: Refresh features periodically; cache frequently-used features for performance.</p>
<h4 id="embedding-management" class="position-relative d-flex align-items-center group">
<span>Embedding Management</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="embedding-management"
aria-haspopup="dialog"
aria-label="Share link: Embedding Management">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Version Control</strong>: Track embedding model versions and retrain schedules to ensure reproducibility.</p>
<p><strong>Dimension Consistency</strong>: Maintain consistent embedding dimensions across all nodes for downstream tasks.</p>
<p><strong>Null Handling</strong>: Define behavior for nodes without embeddings (use default vectors or exclude from calculations).</p>
<p><strong>Storage Optimization</strong>: Consider storing embeddings in external vector databases for large-scale deployments.</p>
<h4 id="model-integration" class="position-relative d-flex align-items-center group">
<span>Model Integration</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="model-integration"
aria-haspopup="dialog"
aria-label="Share link: Model Integration">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p><strong>Feature Extraction Performance</strong>: Pre-compute and cache expensive graph features rather than computing on every prediction.</p>
<p><strong>Batch Predictions</strong>: Process predictions in batches during off-peak hours for efficiency.</p>
<p><strong>Model Monitoring</strong>: Track prediction distributions and feature drift over time.</p>
<p><strong>A/B Testing</strong>: Store multiple model versions to enable controlled rollout and comparison.</p>
<h3 id="integration-examples" class="position-relative d-flex align-items-center group">
<span>Integration Examples</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="integration-examples"
aria-haspopup="dialog"
aria-label="Share link: Integration Examples">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="python-client---feature-extraction" class="position-relative d-flex align-items-center group">
<span>Python Client - Feature Extraction</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="python-client---feature-extraction"
aria-haspopup="dialog"
aria-label="Share link: Python Client - Feature Extraction">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">geode_client</span> <span class="kn">import</span> <span class="n">Client</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">extract_ml_features</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">user_ids</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> UNWIND $user_ids AS uid
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (u:User {id: uid})
</span></span></span><span class="line"><span class="cl"><span class="s2"> WITH u,
</span></span></span><span class="line"><span class="cl"><span class="s2"> COUNT { (u)-[:FOLLOWS]->() } AS out_degree,
</span></span></span><span class="line"><span class="cl"><span class="s2"> COUNT { (u)<-[:FOLLOWS]-() } AS in_degree,
</span></span></span><span class="line"><span class="cl"><span class="s2"> COUNT {
</span></span></span><span class="line"><span class="cl"><span class="s2"> (u)-[action:ACTION]->()
</span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE action.timestamp > CURRENT_TIMESTAMP - INTERVAL '30' DAY
</span></span></span><span class="line"><span class="cl"><span class="s2"> } AS recent_activity
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (u)-[:FOLLOWS]->(friend:User)-[:FOLLOWS]->(fof:User)
</span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE NOT EXISTS { (u)-[:FOLLOWS]->(fof) } AND u <> fof
</span></span></span><span class="line"><span class="cl"><span class="s2"> WITH u, out_degree, in_degree, recent_activity,
</span></span></span><span class="line"><span class="cl"><span class="s2"> COUNT(DISTINCT fof) AS potential_connections
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN u.id,
</span></span></span><span class="line"><span class="cl"><span class="s2"> out_degree,
</span></span></span><span class="line"><span class="cl"><span class="s2"> in_degree,
</span></span></span><span class="line"><span class="cl"><span class="s2"> recent_activity,
</span></span></span><span class="line"><span class="cl"><span class="s2"> potential_connections,
</span></span></span><span class="line"><span class="cl"><span class="s2"> out_degree * 1.0 / (in_degree + 1) AS influence_ratio
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span><span class="s1">'user_ids'</span><span class="p">:</span> <span class="n">user_ids</span><span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="n">features</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">features</span><span class="o">.</span><span class="n">append</span><span class="p">({</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'user_id'</span><span class="p">:</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'out_degree'</span><span class="p">:</span> <span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'in_degree'</span><span class="p">:</span> <span class="n">row</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'recent_activity'</span><span class="p">:</span> <span class="n">row</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'potential_connections'</span><span class="p">:</span> <span class="n">row</span><span class="p">[</span><span class="mi">4</span><span class="p">],</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'influence_ratio'</span><span class="p">:</span> <span class="n">row</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"> <span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">features</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">store_embeddings</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">embeddings_dict</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> UNWIND $embeddings AS emb
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (u:User {id: emb.user_id})
</span></span></span><span class="line"><span class="cl"><span class="s2"> SET u.embedding = emb.vector,
</span></span></span><span class="line"><span class="cl"><span class="s2"> u.embedding_updated = CURRENT_TIMESTAMP
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'embeddings'</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="s1">'user_id'</span><span class="p">:</span> <span class="n">uid</span><span class="p">,</span> <span class="s1">'vector'</span><span class="p">:</span> <span class="n">vec</span><span class="o">.</span><span class="n">tolist</span><span class="p">()}</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">uid</span><span class="p">,</span> <span class="n">vec</span> <span class="ow">in</span> <span class="n">embeddings_dict</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="p">]</span>
</span></span><span class="line"><span class="cl"> <span class="p">})</span>
</span></span></code></pre></div>
<h4 id="rust-client---prediction-serving" class="position-relative d-flex align-items-center group">
<span>Rust Client - Prediction Serving</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="rust-client---prediction-serving"
aria-haspopup="dialog"
aria-label="Share link: Rust Client - Prediction Serving">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">use</span><span class="w"> </span><span class="n">geode_client</span>::<span class="n">Client</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">async</span><span class="w"> </span><span class="k">fn</span> <span class="nf">serve_predictions</span><span class="p">(</span><span class="n">client</span>: <span class="kp">&</span><span class="nc">Client</span><span class="p">,</span><span class="w"> </span><span class="n">predictions</span>: <span class="nb">Vec</span><span class="o"><</span><span class="n">Prediction</span><span class="o">></span><span class="p">)</span><span class="w"> </span>-> <span class="nb">Result</span><span class="o"><</span><span class="p">()</span><span class="o">></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">pred_data</span>: <span class="nb">Vec</span><span class="o"><</span><span class="n">_</span><span class="o">></span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">predictions</span><span class="p">.</span><span class="n">iter</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.</span><span class="n">map</span><span class="p">(</span><span class="o">|</span><span class="n">p</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">json!</span><span class="p">({</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="s">"user_id"</span>: <span class="nc">p</span><span class="p">.</span><span class="n">user_id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="s">"probability"</span>: <span class="nc">p</span><span class="p">.</span><span class="n">churn_probability</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="s">"model_version"</span>: <span class="s">"v2.0"</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.</span><span class="n">collect</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="s">"UNWIND $predictions AS pred </span><span class="se">\</span><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s"> MATCH (u:User {id: pred.user_id}) </span><span class="se">\</span><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s"> SET u.churn_probability = pred.probability, </span><span class="se">\</span><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s"> u.churn_predicted_at = CURRENT_TIMESTAMP, </span><span class="se">\</span><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s"> u.churn_model_version = pred.model_version"</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">&</span><span class="p">[(</span><span class="s">"predictions"</span><span class="p">,</span><span class="w"> </span><span class="n">pred_data</span><span class="p">.</span><span class="n">into</span><span class="p">())]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">).</span><span class="k">await</span><span class="o">?</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Ok</span><span class="p">(())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">async</span><span class="w"> </span><span class="k">fn</span> <span class="nf">get_inference_features</span><span class="p">(</span><span class="n">client</span>: <span class="kp">&</span><span class="nc">Client</span><span class="p">,</span><span class="w"> </span><span class="n">user_id</span>: <span class="kp">&</span><span class="kt">str</span><span class="p">)</span><span class="w"> </span>-> <span class="nb">Result</span><span class="o"><</span><span class="n">Features</span><span class="o">></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="s">"MATCH (u:User {id: $user_id}) </span><span class="se">\</span><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s"> WITH u, </span><span class="se">\</span><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s"> COUNT { (u)-[:FOLLOWS]->() } AS degree, </span><span class="se">\</span><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s"> COUNT { (u)-[a:ACTION]->() WHERE a.timestamp > CURRENT_TIMESTAMP - INTERVAL '30' DAY } AS activity </span><span class="se">\</span><span class="s">
</span></span></span><span class="line"><span class="cl"><span class="s"> RETURN degree, activity, u.embedding"</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">&</span><span class="p">[(</span><span class="s">"user_id"</span><span class="p">,</span><span class="w"> </span><span class="n">user_id</span><span class="p">.</span><span class="n">into</span><span class="p">())]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">).</span><span class="k">await</span><span class="o">?</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="n">Features</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">degree</span>: <span class="nc">result</span><span class="p">.</span><span class="n">get_int</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="o">?</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">recent_activity</span>: <span class="nc">result</span><span class="p">.</span><span class="n">get_int</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="o">?</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">embedding</span>: <span class="nc">result</span><span class="p">.</span><span class="n">get_float_list</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span><span class="o">?</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
<h3 id="advanced-ml-patterns" class="position-relative d-flex align-items-center group">
<span>Advanced ML Patterns</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="advanced-ml-patterns"
aria-haspopup="dialog"
aria-label="Share link: Advanced ML Patterns">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="link-prediction" class="position-relative d-flex align-items-center group">
<span>Link Prediction</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="link-prediction"
aria-haspopup="dialog"
aria-label="Share link: Link Prediction">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Predict future relationships using graph features:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Extract</span><span class="w"> </span><span class="py">features</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">link</span><span class="w"> </span><span class="py">prediction</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$user_a</span><span class="p">}),</span><span class="w"> </span><span class="p">(</span><span class="nc">b</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$user_b</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">WITH</span><span class="w"> </span><span class="py">a</span><span class="p">,</span><span class="w"> </span><span class="py">b</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SIZE</span><span class="p">([(</span><span class="py">a</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-></span><span class="p">()</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">1</span><span class="p">])</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">a_out_degree</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SIZE</span><span class="p">([()</span><span class="err"><-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-</span><span class="p">(</span><span class="py">a</span><span class="p">)</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">1</span><span class="p">])</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">a_in_degree</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SIZE</span><span class="p">([(</span><span class="py">b</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-></span><span class="p">()</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">1</span><span class="p">])</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">b_out_degree</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SIZE</span><span class="p">([()</span><span class="err"><-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-</span><span class="p">(</span><span class="py">b</span><span class="p">)</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">1</span><span class="p">])</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">b_in_degree</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">//</span><span class="w"> </span><span class="py">Common</span><span class="w"> </span><span class="py">neighbors</span><span class="w"> </span><span class="p">(</span><span class="py">Jaccard</span><span class="w"> </span><span class="py">similarity</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">common</span><span class="p">)</span><span class="err"><-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-</span><span class="p">(</span><span class="py">b</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">a</span><span class="p">,</span><span class="w"> </span><span class="py">b</span><span class="p">,</span><span class="w"> </span><span class="py">a_out_degree</span><span class="p">,</span><span class="w"> </span><span class="py">a_in_degree</span><span class="p">,</span><span class="w"> </span><span class="py">b_out_degree</span><span class="p">,</span><span class="w"> </span><span class="py">b_in_degree</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COUNT</span><span class="p">(</span><span class="py">DISTINCT</span><span class="w"> </span><span class="py">common</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">common_neighbors</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">//</span><span class="w"> </span><span class="py">Adamic</span><span class="err">-</span><span class="py">Adar</span><span class="w"> </span><span class="py">index</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">a</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">common</span><span class="p">)</span><span class="err"><-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-</span><span class="p">(</span><span class="py">b</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">a</span><span class="p">,</span><span class="w"> </span><span class="py">b</span><span class="p">,</span><span class="w"> </span><span class="py">common_neighbors</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SUM</span><span class="p">(</span><span class="py">1</span><span class="mf">.0</span><span class="w"> </span><span class="err">/</span><span class="w"> </span><span class="py">log</span><span class="p">(</span><span class="py">SIZE</span><span class="p">([(</span><span class="py">common</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-></span><span class="p">()</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">1</span><span class="p">])))</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">adamic_adar</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">//</span><span class="w"> </span><span class="py">Preferential</span><span class="w"> </span><span class="py">attachment</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">a</span><span class="p">,</span><span class="w"> </span><span class="py">b</span><span class="p">,</span><span class="w"> </span><span class="py">common_neighbors</span><span class="p">,</span><span class="w"> </span><span class="py">adamic_adar</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">a_out_degree</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">b_out_degree</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">preferential_attachment</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w"> </span><span class="py">b</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">common_neighbors</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">adamic_adar</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">preferential_attachment</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">a_out_degree</span><span class="p">,</span><span class="w"> </span><span class="py">a_in_degree</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">b_out_degree</span><span class="p">,</span><span class="w"> </span><span class="py">b_in_degree</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="node-classification" class="position-relative d-flex align-items-center group">
<span>Node Classification</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="node-classification"
aria-haspopup="dialog"
aria-label="Share link: Node Classification">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Extract features for node classification tasks:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Features</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">user</span><span class="w"> </span><span class="py">classification</span><span class="w"> </span><span class="p">(</span><span class="py">churn</span><span class="w"> </span><span class="py">prediction</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">user</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nv">$user_id</span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">//</span><span class="w"> </span><span class="nc">Activity</span><span class="w"> </span><span class="py">features</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">user</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SIZE</span><span class="p">([(</span><span class="py">user</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">ACTION</span><span class="p">]</span><span class="err">-></span><span class="p">()</span><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">1</span><span class="p">])</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">total_actions</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SIZE</span><span class="p">([</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">(</span><span class="py">user</span><span class="p">)</span><span class="err">-</span><span class="p">[</span><span class="py">a</span><span class="p">:</span><span class="nc">ACTION</span><span class="p">]</span><span class="err">-></span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">a</span><span class="err">.</span><span class="py">timestamp</span><span class="w"> </span><span class="err">></span><span class="w"> </span><span class="py">CURRENT_TIMESTAMP</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="py">INTERVAL</span><span class="w"> </span><span class="err">'</span><span class="py">30</span><span class="err">'</span><span class="w"> </span><span class="py">DAY</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">|</span><span class="w"> </span><span class="py">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">])</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">recent_actions</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">//</span><span class="w"> </span><span class="py">Social</span><span class="w"> </span><span class="py">features</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">user</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">FOLLOWS</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">friend</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">user</span><span class="p">,</span><span class="w"> </span><span class="py">total_actions</span><span class="p">,</span><span class="w"> </span><span class="py">recent_actions</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COUNT</span><span class="p">(</span><span class="py">friend</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">friend_count</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AVG</span><span class="p">(</span><span class="py">friend</span><span class="err">.</span><span class="py">activity_score</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">avg_friend_activity</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">//</span><span class="w"> </span><span class="py">Content</span><span class="w"> </span><span class="py">features</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">user</span><span class="p">)</span><span class="err">-</span><span class="p">[:</span><span class="nc">POSTED</span><span class="p">]</span><span class="err">-></span><span class="p">(</span><span class="py">post</span><span class="p">:</span><span class="nc">Post</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">user</span><span class="p">,</span><span class="w"> </span><span class="py">total_actions</span><span class="p">,</span><span class="w"> </span><span class="py">recent_actions</span><span class="p">,</span><span class="w"> </span><span class="py">friend_count</span><span class="p">,</span><span class="w"> </span><span class="py">avg_friend_activity</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AVG</span><span class="p">(</span><span class="py">post</span><span class="err">.</span><span class="py">like_count</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">avg_post_likes</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AVG</span><span class="p">(</span><span class="py">LENGTH</span><span class="p">(</span><span class="py">post</span><span class="err">.</span><span class="py">content</span><span class="p">))</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">avg_post_length</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">//</span><span class="w"> </span><span class="py">Temporal</span><span class="w"> </span><span class="py">features</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">user</span><span class="p">)</span><span class="err">-</span><span class="p">[</span><span class="py">action</span><span class="p">:</span><span class="nc">ACTION</span><span class="p">]</span><span class="err">-></span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">user</span><span class="p">,</span><span class="w"> </span><span class="py">total_actions</span><span class="p">,</span><span class="w"> </span><span class="py">recent_actions</span><span class="p">,</span><span class="w"> </span><span class="py">friend_count</span><span class="p">,</span><span class="w"> </span><span class="py">avg_friend_activity</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">avg_post_likes</span><span class="p">,</span><span class="w"> </span><span class="py">avg_post_length</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">MAX</span><span class="p">(</span><span class="py">action</span><span class="err">.</span><span class="py">timestamp</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">last_action_time</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WITH</span><span class="w"> </span><span class="py">user</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">total_actions</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">recent_actions</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">recent_actions</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">1</span><span class="mf">.0</span><span class="w"> </span><span class="err">/</span><span class="w"> </span><span class="py">NULLIF</span><span class="p">(</span><span class="py">total_actions</span><span class="p">,</span><span class="w"> </span><span class="py">0</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">activity_trend</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">friend_count</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">avg_friend_activity</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">avg_post_likes</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">avg_post_length</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">DURATION</span><span class="err">.</span><span class="py">BETWEEN</span><span class="p">(</span><span class="py">last_action_time</span><span class="p">,</span><span class="w"> </span><span class="py">CURRENT_TIMESTAMP</span><span class="p">)</span><span class="err">.</span><span class="py">days</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">days_since_last_action</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURN</span><span class="w"> </span><span class="py">user</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">total_actions</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">recent_actions</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">activity_trend</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">friend_count</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">avg_friend_activity</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">avg_post_likes</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">avg_post_length</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">days_since_last_action</span><span class="err">;</span><span class="w">
</span></span></span></code></pre></div>
<h4 id="graph-convolutional-networks-gcn-support" class="position-relative d-flex align-items-center group">
<span>Graph Convolutional Networks (GCN) Support</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="graph-convolutional-networks-gcn-support"
aria-haspopup="dialog"
aria-label="Share link: Graph Convolutional Networks (GCN) Support">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Implement GCN layer operations in Geode:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">geode_client</span> <span class="kn">import</span> <span class="n">Client</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">GraphConvolutionalLayer</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""Simple GCN layer implementation using Geode"""</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">client</span><span class="p">,</span> <span class="n">input_dim</span><span class="p">,</span> <span class="n">output_dim</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">client</span> <span class="o">=</span> <span class="n">client</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">input_dim</span> <span class="o">=</span> <span class="n">input_dim</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">output_dim</span> <span class="o">=</span> <span class="n">output_dim</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">weights</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">random</span><span class="o">.</span><span class="n">randn</span><span class="p">(</span><span class="n">input_dim</span><span class="p">,</span> <span class="n">output_dim</span><span class="p">)</span> <span class="o">*</span> <span class="mf">0.01</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">forward</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">node_ids</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> Perform one GCN layer forward pass:
</span></span></span><span class="line"><span class="cl"><span class="s2"> H' = σ(D^(-1/2) A D^(-1/2) H W)
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span>
</span></span><span class="line"><span class="cl"> <span class="c1"># Fetch node features and neighbor information</span>
</span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> UNWIND $node_ids AS node_id
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (n:Node {id: node_id})
</span></span></span><span class="line"><span class="cl"><span class="s2"> OPTIONAL MATCH (n)-[:EDGE]-(neighbor:Node)
</span></span></span><span class="line"><span class="cl"><span class="s2"> WITH n,
</span></span></span><span class="line"><span class="cl"><span class="s2"> n.features AS features,
</span></span></span><span class="line"><span class="cl"><span class="s2"> COLLECT(DISTINCT neighbor.id) AS neighbors,
</span></span></span><span class="line"><span class="cl"><span class="s2"> COUNT(DISTINCT neighbor) + 1 AS degree
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN n.id, features, neighbors, degree
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span><span class="s2">"node_ids"</span><span class="p">:</span> <span class="n">node_ids</span><span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Aggregate neighbor features (message passing)</span>
</span></span><span class="line"><span class="cl"> <span class="n">aggregated_features</span> <span class="o">=</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">node_id</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s1">'n.id'</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"> <span class="n">features</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="s1">'features'</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"> <span class="n">neighbors</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s1">'neighbors'</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"> <span class="n">degree</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s1">'degree'</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Self-loop</span>
</span></span><span class="line"><span class="cl"> <span class="n">aggregated</span> <span class="o">=</span> <span class="n">features</span> <span class="o">/</span> <span class="n">np</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">degree</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Add neighbor contributions</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">neighbors</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">neighbor_result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> UNWIND $neighbor_ids AS nid
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (n:Node {id: nid})
</span></span></span><span class="line"><span class="cl"><span class="s2"> OPTIONAL MATCH (n)-[:EDGE]-()
</span></span></span><span class="line"><span class="cl"><span class="s2"> WITH n, COUNT(*) + 1 AS neighbor_degree
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN n.id, n.features, neighbor_degree
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span><span class="s2">"neighbor_ids"</span><span class="p">:</span> <span class="n">neighbors</span><span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">neighbor_row</span> <span class="ow">in</span> <span class="n">neighbor_result</span><span class="o">.</span><span class="n">rows</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">neighbor_features</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">neighbor_row</span><span class="p">[</span><span class="s1">'n.features'</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"> <span class="n">neighbor_degree</span> <span class="o">=</span> <span class="n">neighbor_row</span><span class="p">[</span><span class="s1">'neighbor_degree'</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Normalized aggregation</span>
</span></span><span class="line"><span class="cl"> <span class="n">aggregated</span> <span class="o">+=</span> <span class="n">neighbor_features</span> <span class="o">/</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">np</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">degree</span><span class="p">)</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="n">neighbor_degree</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Apply learned weights</span>
</span></span><span class="line"><span class="cl"> <span class="n">aggregated_features</span><span class="p">[</span><span class="n">node_id</span><span class="p">]</span> <span class="o">=</span> <span class="n">aggregated</span> <span class="o">@</span> <span class="bp">self</span><span class="o">.</span><span class="n">weights</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Apply activation function (ReLU)</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">node_id</span> <span class="ow">in</span> <span class="n">aggregated_features</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">aggregated_features</span><span class="p">[</span><span class="n">node_id</span><span class="p">]</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">maximum</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">aggregated_features</span><span class="p">[</span><span class="n">node_id</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">aggregated_features</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">update_node_embeddings</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">aggregated_features</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""Store computed embeddings back to Geode"""</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> UNWIND $updates AS update
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (n:Node {id: update.node_id})
</span></span></span><span class="line"><span class="cl"><span class="s2"> SET n.embedding = update.embedding,
</span></span></span><span class="line"><span class="cl"><span class="s2"> n.embedding_updated = CURRENT_TIMESTAMP
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"updates"</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="s2">"node_id"</span><span class="p">:</span> <span class="n">nid</span><span class="p">,</span> <span class="s2">"embedding"</span><span class="p">:</span> <span class="n">features</span><span class="o">.</span><span class="n">tolist</span><span class="p">()}</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">nid</span><span class="p">,</span> <span class="n">features</span> <span class="ow">in</span> <span class="n">aggregated_features</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="p">]</span>
</span></span><span class="line"><span class="cl"> <span class="p">})</span>
</span></span></code></pre></div>
<h4 id="training-data-sampling" class="position-relative d-flex align-items-center group">
<span>Training Data Sampling</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="training-data-sampling"
aria-haspopup="dialog"
aria-label="Share link: Training Data Sampling">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Efficiently sample training data from graph:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">sample_training_data</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">batch_size</span><span class="o">=</span><span class="mi">1000</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> Sample balanced training batches for node classification
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span>
</span></span><span class="line"><span class="cl"> <span class="c1"># Get class distribution</span>
</span></span><span class="line"><span class="cl"> <span class="n">class_counts</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (n:Node)
</span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE n.label IS NOT NULL
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN n.label, COUNT(*) AS count
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Calculate sampling probabilities for balanced batches</span>
</span></span><span class="line"><span class="cl"> <span class="n">total</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="s1">'count'</span><span class="p">]</span> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">class_counts</span><span class="o">.</span><span class="n">rows</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="n">class_weights</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="n">row</span><span class="p">[</span><span class="s1">'n.label'</span><span class="p">]:</span> <span class="n">total</span> <span class="o">/</span> <span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">class_counts</span><span class="o">.</span><span class="n">rows</span><span class="p">)</span> <span class="o">*</span> <span class="n">row</span><span class="p">[</span><span class="s1">'count'</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">class_counts</span><span class="o">.</span><span class="n">rows</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Sample with stratification</span>
</span></span><span class="line"><span class="cl"> <span class="n">samples_per_class</span> <span class="o">=</span> <span class="n">batch_size</span> <span class="o">//</span> <span class="nb">len</span><span class="p">(</span><span class="n">class_weights</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="n">training_nodes</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">label</span><span class="p">,</span> <span class="n">weight</span> <span class="ow">in</span> <span class="n">class_weights</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
</span></span><span class="line"><span class="cl"> <span class="n">samples</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (n:Node {label: $label})
</span></span></span><span class="line"><span class="cl"><span class="s2"> WITH n, RAND() AS random
</span></span></span><span class="line"><span class="cl"><span class="s2"> ORDER BY random
</span></span></span><span class="line"><span class="cl"><span class="s2"> LIMIT $limit
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN n.id, n.features, n.label
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span><span class="s2">"label"</span><span class="p">:</span> <span class="n">label</span><span class="p">,</span> <span class="s2">"limit"</span><span class="p">:</span> <span class="n">samples_per_class</span><span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="n">training_nodes</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">samples</span><span class="o">.</span><span class="n">rows</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">training_nodes</span>
</span></span></code></pre></div>
<h4 id="graph-attention-networks-gat-implementation" class="position-relative d-flex align-items-center group">
<span>Graph Attention Networks (GAT) Implementation</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="graph-attention-networks-gat-implementation"
aria-haspopup="dialog"
aria-label="Share link: Graph Attention Networks (GAT) Implementation">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Implement attention mechanisms for graph learning:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">compute_attention_weights</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">node_id</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> Compute attention weights for neighbors using learned attention mechanism
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span>
</span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (center:Node {id: $node_id})
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (center)-[e:EDGE]-(neighbor:Node)
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN center.embedding AS center_emb,
</span></span></span><span class="line"><span class="cl"><span class="s2"> neighbor.id AS neighbor_id,
</span></span></span><span class="line"><span class="cl"><span class="s2"> neighbor.embedding AS neighbor_emb,
</span></span></span><span class="line"><span class="cl"><span class="s2"> e.features AS edge_features
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span><span class="s2">"node_id"</span><span class="p">:</span> <span class="n">node_id</span><span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="n">center_embedding</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="s1">'center_emb'</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="n">attention_weights</span> <span class="o">=</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">neighbor_id</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="s1">'neighbor_id'</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"> <span class="n">neighbor_emb</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="s1">'neighbor_emb'</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"> <span class="n">edge_features</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="s1">'edge_features'</span><span class="p">])</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="s1">'edge_features'</span><span class="p">]</span> <span class="k">else</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">(</span><span class="mi">8</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Concatenate embeddings and edge features</span>
</span></span><span class="line"><span class="cl"> <span class="n">concat</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">concatenate</span><span class="p">([</span><span class="n">center_embedding</span><span class="p">,</span> <span class="n">neighbor_emb</span><span class="p">,</span> <span class="n">edge_features</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Compute attention score (learned attention parameters)</span>
</span></span><span class="line"><span class="cl"> <span class="n">attention_score</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">dot</span><span class="p">(</span><span class="n">concat</span><span class="p">,</span> <span class="n">attention_params</span><span class="p">)</span> <span class="c1"># attention_params learned during training</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="n">attention_weights</span><span class="p">[</span><span class="n">neighbor_id</span><span class="p">]</span> <span class="o">=</span> <span class="n">attention_score</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Softmax normalization</span>
</span></span><span class="line"><span class="cl"> <span class="n">exp_scores</span> <span class="o">=</span> <span class="p">{</span><span class="n">nid</span><span class="p">:</span> <span class="n">np</span><span class="o">.</span><span class="n">exp</span><span class="p">(</span><span class="n">score</span><span class="p">)</span> <span class="k">for</span> <span class="n">nid</span><span class="p">,</span> <span class="n">score</span> <span class="ow">in</span> <span class="n">attention_weights</span><span class="o">.</span><span class="n">items</span><span class="p">()}</span>
</span></span><span class="line"><span class="cl"> <span class="n">sum_exp</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">exp_scores</span><span class="o">.</span><span class="n">values</span><span class="p">())</span>
</span></span><span class="line"><span class="cl"> <span class="n">normalized_weights</span> <span class="o">=</span> <span class="p">{</span><span class="n">nid</span><span class="p">:</span> <span class="n">score</span> <span class="o">/</span> <span class="n">sum_exp</span> <span class="k">for</span> <span class="n">nid</span><span class="p">,</span> <span class="n">score</span> <span class="ow">in</span> <span class="n">exp_scores</span><span class="o">.</span><span class="n">items</span><span class="p">()}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Store attention weights for visualization/analysis</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> UNWIND $weights AS w
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (center:Node {id: $center_id})-[e:EDGE]-(neighbor:Node {id: w.neighbor_id})
</span></span></span><span class="line"><span class="cl"><span class="s2"> SET e.attention_weight = w.weight
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"center_id"</span><span class="p">:</span> <span class="n">node_id</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"weights"</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="s2">"neighbor_id"</span><span class="p">:</span> <span class="n">nid</span><span class="p">,</span> <span class="s2">"weight"</span><span class="p">:</span> <span class="n">weight</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">nid</span><span class="p">,</span> <span class="n">weight</span> <span class="ow">in</span> <span class="n">normalized_weights</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="p">]</span>
</span></span><span class="line"><span class="cl"> <span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">normalized_weights</span>
</span></span></code></pre></div>
<h4 id="online-learning-and-model-updates" class="position-relative d-flex align-items-center group">
<span>Online Learning and Model Updates</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="online-learning-and-model-updates"
aria-haspopup="dialog"
aria-label="Share link: Online Learning and Model Updates">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Incrementally update models with new data:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">IncrementalGraphModel</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""Online learning model that updates with new graph data"""</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">partial_fit</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">client</span><span class="p">,</span> <span class="n">new_nodes</span><span class="p">,</span> <span class="n">new_edges</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""Update model with new nodes and edges"""</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Extract features for new nodes</span>
</span></span><span class="line"><span class="cl"> <span class="n">new_features</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">extract_features</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">new_nodes</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Update embedding for new nodes</span>
</span></span><span class="line"><span class="cl"> <span class="n">new_embeddings</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">model</span><span class="o">.</span><span class="n">transform</span><span class="p">(</span><span class="n">new_features</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Store embeddings</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> UNWIND $embeddings AS emb
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (n:Node {id: emb.node_id})
</span></span></span><span class="line"><span class="cl"><span class="s2"> SET n.embedding = emb.vector,
</span></span></span><span class="line"><span class="cl"><span class="s2"> n.embedding_model_version = $version
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"embeddings"</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="s2">"node_id"</span><span class="p">:</span> <span class="n">nid</span><span class="p">,</span> <span class="s2">"vector"</span><span class="p">:</span> <span class="n">emb</span><span class="o">.</span><span class="n">tolist</span><span class="p">()}</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">nid</span><span class="p">,</span> <span class="n">emb</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">new_nodes</span><span class="p">,</span> <span class="n">new_embeddings</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">],</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"version"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">model_version</span>
</span></span><span class="line"><span class="cl"> <span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Incrementally update neighbor embeddings (for propagation models)</span>
</span></span><span class="line"><span class="cl"> <span class="n">affected_neighbors</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> UNWIND $new_nodes AS node_id
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (new:Node {id: node_id})-[:EDGE]-(neighbor:Node)
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN DISTINCT neighbor.id
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span><span class="s2">"new_nodes"</span><span class="p">:</span> <span class="n">new_nodes</span><span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="n">neighbor_ids</span> <span class="o">=</span> <span class="p">[</span><span class="n">row</span><span class="p">[</span><span class="s1">'neighbor.id'</span><span class="p">]</span> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">affected_neighbors</span><span class="o">.</span><span class="n">rows</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Re-compute embeddings for affected neighbors</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">recompute_embeddings</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">neighbor_ids</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">recompute_embeddings</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">client</span><span class="p">,</span> <span class="n">node_ids</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""Re-compute embeddings for nodes affected by graph changes"""</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">node_id</span> <span class="ow">in</span> <span class="n">node_ids</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">features</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">extract_node_features</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">node_id</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="n">embedding</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">model</span><span class="o">.</span><span class="n">transform</span><span class="p">([</span><span class="n">features</span><span class="p">])[</span><span class="mi">0</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (n:Node {id: $node_id})
</span></span></span><span class="line"><span class="cl"><span class="s2"> SET n.embedding = $embedding,
</span></span></span><span class="line"><span class="cl"><span class="s2"> n.embedding_updated = CURRENT_TIMESTAMP
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span><span class="s2">"node_id"</span><span class="p">:</span> <span class="n">node_id</span><span class="p">,</span> <span class="s2">"embedding"</span><span class="p">:</span> <span class="n">embedding</span><span class="o">.</span><span class="n">tolist</span><span class="p">()})</span>
</span></span></code></pre></div>
<h4 id="model-monitoring-and-drift-detection" class="position-relative d-flex align-items-center group">
<span>Model Monitoring and Drift Detection</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="model-monitoring-and-drift-detection"
aria-haspopup="dialog"
aria-label="Share link: Model Monitoring and Drift Detection">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Track model performance over time:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">monitor_model_drift</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">model_id</span><span class="p">,</span> <span class="n">prediction_window_days</span><span class="o">=</span><span class="mi">30</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> Detect model drift by comparing prediction distribution
</span></span></span><span class="line"><span class="cl"><span class="s2"> over time
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span>
</span></span><span class="line"><span class="cl"> <span class="c1"># Get recent predictions</span>
</span></span><span class="line"><span class="cl"> <span class="n">recent_predictions</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (n:Node)-[p:PREDICTION]->()
</span></span></span><span class="line"><span class="cl"><span class="s2"> WHERE p.model_id = $model_id
</span></span></span><span class="line"><span class="cl"><span class="s2"> AND p.timestamp > CURRENT_TIMESTAMP - INTERVAL '$days' DAY
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN p.predicted_class,
</span></span></span><span class="line"><span class="cl"><span class="s2"> p.confidence,
</span></span></span><span class="line"><span class="cl"><span class="s2"> p.timestamp
</span></span></span><span class="line"><span class="cl"><span class="s2"> ORDER BY p.timestamp
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span><span class="s2">"model_id"</span><span class="p">:</span> <span class="n">model_id</span><span class="p">,</span> <span class="s2">"days"</span><span class="p">:</span> <span class="n">prediction_window_days</span><span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Split into time windows</span>
</span></span><span class="line"><span class="cl"> <span class="n">window_size</span> <span class="o">=</span> <span class="n">prediction_window_days</span> <span class="o">//</span> <span class="mi">7</span> <span class="c1"># Weekly windows</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="n">distributions</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">week</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">7</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="n">start</span> <span class="o">=</span> <span class="n">week</span> <span class="o">*</span> <span class="n">window_size</span>
</span></span><span class="line"><span class="cl"> <span class="n">end</span> <span class="o">=</span> <span class="p">(</span><span class="n">week</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="n">window_size</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="n">week_preds</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl"> <span class="n">row</span> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">recent_predictions</span><span class="o">.</span><span class="n">rows</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">start</span> <span class="o"><=</span> <span class="p">(</span><span class="n">CURRENT_TIMESTAMP</span> <span class="o">-</span> <span class="n">row</span><span class="p">[</span><span class="s1">'p.timestamp'</span><span class="p">])</span><span class="o">.</span><span class="n">days</span> <span class="o"><</span> <span class="n">end</span>
</span></span><span class="line"><span class="cl"> <span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Calculate distribution</span>
</span></span><span class="line"><span class="cl"> <span class="n">class_dist</span> <span class="o">=</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">pred</span> <span class="ow">in</span> <span class="n">week_preds</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="bp">cls</span> <span class="o">=</span> <span class="n">pred</span><span class="p">[</span><span class="s1">'p.predicted_class'</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"> <span class="n">class_dist</span><span class="p">[</span><span class="bp">cls</span><span class="p">]</span> <span class="o">=</span> <span class="n">class_dist</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="n">distributions</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">class_dist</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Detect drift using KL divergence</span>
</span></span><span class="line"><span class="cl"> <span class="n">drift_score</span> <span class="o">=</span> <span class="n">calculate_kl_divergence</span><span class="p">(</span><span class="n">distributions</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">distributions</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">drift_score</span> <span class="o">></span> <span class="mf">0.1</span><span class="p">:</span> <span class="c1"># Threshold</span>
</span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"WARNING: Model drift detected for </span><span class="si">{</span><span class="n">model_id</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"KL divergence: </span><span class="si">{</span><span class="n">drift_score</span><span class="si">:</span><span class="s2">.4f</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">True</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">False</span>
</span></span></code></pre></div>
<h4 id="feature-store-integration" class="position-relative d-flex align-items-center group">
<span>Feature Store Integration</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="feature-store-integration"
aria-haspopup="dialog"
aria-label="Share link: Feature Store Integration">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Use Geode as a feature store for ML pipelines:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">GeodeFeatureStore</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""Feature store backed by Geode graph database"""</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">client</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">client</span> <span class="o">=</span> <span class="n">client</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">register_feature</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">feature_name</span><span class="p">,</span> <span class="n">feature_query</span><span class="p">,</span> <span class="n">entity_type</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""Register a feature definition"""</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE (f:Feature {
</span></span></span><span class="line"><span class="cl"><span class="s2"> name: $name,
</span></span></span><span class="line"><span class="cl"><span class="s2"> query: $query,
</span></span></span><span class="line"><span class="cl"><span class="s2"> entity_type: $entity_type,
</span></span></span><span class="line"><span class="cl"><span class="s2"> registered_at: CURRENT_TIMESTAMP
</span></span></span><span class="line"><span class="cl"><span class="s2"> })
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"name"</span><span class="p">:</span> <span class="n">feature_name</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"query"</span><span class="p">:</span> <span class="n">feature_query</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"entity_type"</span><span class="p">:</span> <span class="n">entity_type</span>
</span></span><span class="line"><span class="cl"> <span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">compute_features</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">feature_names</span><span class="p">,</span> <span class="n">entity_ids</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""Compute features for given entities"""</span>
</span></span><span class="line"><span class="cl"> <span class="n">features</span> <span class="o">=</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">feature_name</span> <span class="ow">in</span> <span class="n">feature_names</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="c1"># Get feature definition</span>
</span></span><span class="line"><span class="cl"> <span class="n">definition</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (f:Feature {name: $name})
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN f.query, f.entity_type
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span><span class="s2">"name"</span><span class="p">:</span> <span class="n">feature_name</span><span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="n">query_template</span> <span class="o">=</span> <span class="n">definition</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="s1">'f.query'</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Execute feature query for each entity</span>
</span></span><span class="line"><span class="cl"> <span class="n">results</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">query_template</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="s2">"entity_ids"</span><span class="p">:</span> <span class="n">entity_ids</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="n">features</span><span class="p">[</span><span class="n">feature_name</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="n">row</span><span class="p">[</span><span class="s1">'entity_id'</span><span class="p">]:</span> <span class="n">row</span><span class="p">[</span><span class="s1">'feature_value'</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">results</span><span class="o">.</span><span class="n">rows</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Transpose to entity-centric format</span>
</span></span><span class="line"><span class="cl"> <span class="n">entity_features</span> <span class="o">=</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">entity_id</span> <span class="ow">in</span> <span class="n">entity_ids</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">entity_features</span><span class="p">[</span><span class="n">entity_id</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="n">fname</span><span class="p">:</span> <span class="n">features</span><span class="p">[</span><span class="n">fname</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">entity_id</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">fname</span> <span class="ow">in</span> <span class="n">feature_names</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">entity_features</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">materialize_features</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">feature_names</span><span class="p">,</span> <span class="n">entity_type</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""Pre-compute and cache features"""</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">feature_name</span> <span class="ow">in</span> <span class="n">feature_names</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="bp">self</span><span class="o">.</span><span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (f:Feature {name: $name})
</span></span></span><span class="line"><span class="cl"><span class="s2"> WITH f
</span></span></span><span class="line"><span class="cl"><span class="s2"> CALL apoc.cypher.run(f.query, </span><span class="si">{}</span><span class="s2">) YIELD value
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (entity) WHERE entity.type = $entity_type
</span></span></span><span class="line"><span class="cl"><span class="s2"> SET entity[$feature_name] = value.feature_value
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"name"</span><span class="p">:</span> <span class="n">feature_name</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"entity_type"</span><span class="p">:</span> <span class="n">entity_type</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"feature_name"</span><span class="p">:</span> <span class="n">feature_name</span>
</span></span><span class="line"><span class="cl"> <span class="p">})</span>
</span></span></code></pre></div>
<h3 id="production-ml-workflows" class="position-relative d-flex align-items-center group">
<span>Production ML Workflows</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="production-ml-workflows"
aria-haspopup="dialog"
aria-label="Share link: Production ML Workflows">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="complete-training-pipeline" class="position-relative d-flex align-items-center group">
<span>Complete Training Pipeline</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="complete-training-pipeline"
aria-haspopup="dialog"
aria-label="Share link: Complete Training Pipeline">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">train_graph_model</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">model_config</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""End-to-end graph ML training pipeline"""</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># 1. Feature extraction</span>
</span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="s2">"Extracting features..."</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="n">features</span> <span class="o">=</span> <span class="k">await</span> <span class="n">extract_graph_features</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">client</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">node_label</span><span class="o">=</span><span class="s2">"User"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">feature_config</span><span class="o">=</span><span class="n">model_config</span><span class="p">[</span><span class="s1">'features'</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"> <span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># 2. Train/test split</span>
</span></span><span class="line"><span class="cl"> <span class="kn">from</span> <span class="nn">sklearn.model_selection</span> <span class="kn">import</span> <span class="n">train_test_split</span>
</span></span><span class="line"><span class="cl"> <span class="n">X</span> <span class="o">=</span> <span class="p">[</span><span class="n">f</span><span class="p">[</span><span class="s1">'features'</span><span class="p">]</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">features</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"> <span class="n">y</span> <span class="o">=</span> <span class="p">[</span><span class="n">f</span><span class="p">[</span><span class="s1">'label'</span><span class="p">]</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">features</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"> <span class="n">X_train</span><span class="p">,</span> <span class="n">X_test</span><span class="p">,</span> <span class="n">y_train</span><span class="p">,</span> <span class="n">y_test</span> <span class="o">=</span> <span class="n">train_test_split</span><span class="p">(</span><span class="n">X</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">test_size</span><span class="o">=</span><span class="mf">0.2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># 3. Train model</span>
</span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="s2">"Training model..."</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="n">model</span> <span class="o">=</span> <span class="n">train_xgboost</span><span class="p">(</span><span class="n">X_train</span><span class="p">,</span> <span class="n">y_train</span><span class="p">,</span> <span class="n">model_config</span><span class="p">[</span><span class="s1">'params'</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># 4. Evaluate</span>
</span></span><span class="line"><span class="cl"> <span class="n">predictions</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">predict</span><span class="p">(</span><span class="n">X_test</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="n">accuracy</span> <span class="o">=</span> <span class="n">accuracy_score</span><span class="p">(</span><span class="n">y_test</span><span class="p">,</span> <span class="n">predictions</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Test accuracy: </span><span class="si">{</span><span class="n">accuracy</span><span class="si">:</span><span class="s2">.4f</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># 5. Store model and predictions</span>
</span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="s2">"Storing model..."</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">store_model</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">model</span><span class="p">,</span> <span class="n">model_config</span><span class="p">,</span> <span class="n">accuracy</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># 6. Generate predictions for all nodes</span>
</span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="s2">"Generating predictions..."</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="n">all_predictions</span> <span class="o">=</span> <span class="n">model</span><span class="o">.</span><span class="n">predict</span><span class="p">(</span><span class="n">X</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">store_predictions</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">features</span><span class="p">,</span> <span class="n">all_predictions</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">model</span><span class="p">,</span> <span class="n">accuracy</span>
</span></span></code></pre></div>
<h4 id="ab-testing-ml-models" class="position-relative d-flex align-items-center group">
<span>A/B Testing ML Models</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="ab-testing-ml-models"
aria-haspopup="dialog"
aria-label="Share link: A/B Testing ML Models">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">ab_test_models</span><span class="p">(</span><span class="n">client</span><span class="p">,</span> <span class="n">model_a_id</span><span class="p">,</span> <span class="n">model_b_id</span><span class="p">,</span> <span class="n">traffic_split</span><span class="o">=</span><span class="mf">0.5</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""A/B test two different models"""</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">serve_prediction</span><span class="p">(</span><span class="n">user_id</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="c1"># Assign user to variant</span>
</span></span><span class="line"><span class="cl"> <span class="n">user_hash</span> <span class="o">=</span> <span class="nb">hash</span><span class="p">(</span><span class="n">user_id</span><span class="p">)</span> <span class="o">%</span> <span class="mi">100</span>
</span></span><span class="line"><span class="cl"> <span class="n">model_id</span> <span class="o">=</span> <span class="n">model_a_id</span> <span class="k">if</span> <span class="n">user_hash</span> <span class="o"><</span> <span class="n">traffic_split</span> <span class="o">*</span> <span class="mi">100</span> <span class="k">else</span> <span class="n">model_b_id</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Get prediction from assigned model</span>
</span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (user:User {id: $user_id})
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (model:MLModel {id: $model_id})
</span></span></span><span class="line"><span class="cl"><span class="s2"> // Get features and apply model
</span></span></span><span class="line"><span class="cl"><span class="s2"> WITH user, model,
</span></span></span><span class="line"><span class="cl"><span class="s2"> extract_features(user) AS features
</span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN model.predict(features) AS prediction
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span><span class="s2">"user_id"</span><span class="p">:</span> <span class="n">user_id</span><span class="p">,</span> <span class="s2">"model_id"</span><span class="p">:</span> <span class="n">model_id</span><span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="n">prediction</span> <span class="o">=</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="s1">'prediction'</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Log for analysis</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE (e:ExperimentEvent {
</span></span></span><span class="line"><span class="cl"><span class="s2"> user_id: $user_id,
</span></span></span><span class="line"><span class="cl"><span class="s2"> model_id: $model_id,
</span></span></span><span class="line"><span class="cl"><span class="s2"> prediction: $prediction,
</span></span></span><span class="line"><span class="cl"><span class="s2"> timestamp: CURRENT_TIMESTAMP
</span></span></span><span class="line"><span class="cl"><span class="s2"> })
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"user_id"</span><span class="p">:</span> <span class="n">user_id</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"model_id"</span><span class="p">:</span> <span class="n">model_id</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"prediction"</span><span class="p">:</span> <span class="n">prediction</span>
</span></span><span class="line"><span class="cl"> <span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">prediction</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">serve_prediction</span>
</span></span></code></pre></div>
<h3 id="related-topics" class="position-relative d-flex align-items-center group">
<span>Related Topics</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="related-topics"
aria-haspopup="dialog"
aria-label="Share link: Related Topics">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><ul>
<li><strong><a
href="/tags/embeddings/"
>Embeddings</a>
</strong>: Vector storage and similarity search</li>
<li><strong><a
href="/tags/vector-search/"
>Vector Search</a>
</strong>: HNSW-based embedding retrieval</li>
<li><strong><a
href="/tags/analytics/"
>Analytics</a>
</strong>: Feature engineering patterns</li>
<li><strong><a
href="/tags/graph-algorithms/"
>Graph Algorithms</a>
</strong>: Graph algorithm implementations</li>
<li><strong><a
href="/tags/python/"
>Python Client</a>
</strong>: Python integration patterns</li>
<li><strong><a
href="/tags/real-time-analytics/"
>Real-Time Analytics</a>
</strong>: Real-time data processing</li>
</ul>
<h3 id="further-reading" class="position-relative d-flex align-items-center group">
<span>Further Reading</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="further-reading"
aria-haspopup="dialog"
aria-label="Share link: Further Reading">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><ul>
<li><strong>Graph Algorithms</strong>: <code>/docs/analytics/graph-algorithms/</code></li>
<li><strong>Real-Time Analytics</strong>: <code>/docs/analytics/real-time-analytics/</code></li>
<li><strong>Python Client</strong>: <code>/docs/client-libraries/python-client/</code></li>
<li><strong>Vector Search Tutorial</strong>: <code>/docs/tutorials/vector-search-tutorial/</code></li>
</ul>
Tag
2 articles
Machine Learning Integration
Integrate machine learning with Geode graph database. Use graph features for ML training, store embeddings, implement GNNs, and deploy graph-powered ML models with GQL.