graphforge_core/embedding_options.rs
1//! Closed typed options for the four embedding-v1 analysis algorithms.
2
3use crate::algorithms::AnalyzeAlgorithm;
4
5/// Maximum embedding width shared by Node2Vec, GraphSAGE, and FastRP.
6pub const MAX_EMBEDDING_DIMENSIONS: usize = 4_096;
7/// Maximum embedding width for HashGNN.
8pub const MAX_HASHGNN_DIMENSIONS: usize = 8_192;
9
10/// One embedding-v1 option family.
11#[derive(Debug, Clone, PartialEq)]
12pub enum EmbeddingOptions {
13 /// `analyze(by="node2vec")`.
14 Node2Vec(Node2VecOptions),
15 /// `analyze(by="graphsage")`.
16 GraphSage(GraphSageOptions),
17 /// `analyze(by="fast_random_projection")`.
18 FastRandomProjection(FastRpOptions),
19 /// `analyze(by="hashgnn")`.
20 HashGnn(HashGnnOptions),
21}
22
23/// Graph-native invocation boundary for an embedding analysis.
24#[derive(Debug, Clone, PartialEq)]
25pub struct EmbeddingAnalyzeOptions {
26 /// Embedding algorithm selected from the closed analysis catalog.
27 pub by: AnalyzeAlgorithm,
28 /// Optional relationship type filter.
29 pub via: Option<String>,
30 /// Whether to treat edges as directed.
31 pub directed: bool,
32 /// Optional edge-weight property.
33 pub weight: Option<String>,
34 /// Closed options for the selected embedding algorithm.
35 pub options: EmbeddingOptions,
36}
37
38/// Node2Vec v1 options.
39#[derive(Debug, Clone, PartialEq)]
40pub struct Node2VecOptions {
41 /// Output vector width.
42 pub dimensions: usize,
43 /// Transitions in each walk.
44 pub walk_length: usize,
45 /// Walks originating at each selected node.
46 pub walks_per_node: usize,
47 /// Return parameter `p`.
48 pub p: f64,
49 /// In/out parameter `q`.
50 pub q: f64,
51 /// Fixed context radius.
52 pub window_size: usize,
53 /// Negative samples per positive context.
54 pub negative_samples: usize,
55 /// Training passes over the fixed corpus.
56 pub epochs: usize,
57 /// Constant SGNS learning rate.
58 pub learning_rate: f64,
59 /// Caller seed; omission normalizes to zero.
60 pub seed: u64,
61}
62
63impl Default for Node2VecOptions {
64 fn default() -> Self {
65 Self {
66 dimensions: 128,
67 walk_length: 80,
68 walks_per_node: 10,
69 p: 1.0,
70 q: 1.0,
71 window_size: 10,
72 negative_samples: 5,
73 epochs: 1,
74 learning_rate: 0.025,
75 seed: 0,
76 }
77 }
78}
79
80/// GraphSAGE v1 aggregator. Version 1 intentionally supports only mean.
81#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
82pub enum GraphSageAggregator {
83 /// Arithmetic mean of the sampled neighborhood.
84 #[default]
85 Mean,
86}
87
88/// Unsupervised GraphSAGE v1 options.
89///
90/// `feature_properties` must be supplied explicitly: the empty default is not a
91/// runnable GraphSAGE configuration.
92#[derive(Debug, Clone, PartialEq)]
93pub struct GraphSageOptions {
94 /// Output vector width.
95 pub dimensions: usize,
96 /// Width of non-final layers.
97 pub hidden_dimensions: usize,
98 /// Number of aggregation layers.
99 pub layers: usize,
100 /// Ordered fanout for each layer.
101 pub sample_sizes: Vec<usize>,
102 /// Version-pinned neighborhood aggregator.
103 pub aggregator: GraphSageAggregator,
104 /// Training epochs.
105 pub epochs: usize,
106 /// Negative samples per positive pair.
107 pub negative_samples: usize,
108 /// Constant Adam learning rate.
109 pub learning_rate: f64,
110 /// Ordered graph-native numeric feature properties.
111 pub feature_properties: Vec<String>,
112 /// Caller seed; omission normalizes to zero.
113 pub seed: u64,
114}
115
116impl Default for GraphSageOptions {
117 fn default() -> Self {
118 Self {
119 dimensions: 256,
120 hidden_dimensions: 256,
121 layers: 2,
122 sample_sizes: vec![25, 10],
123 aggregator: GraphSageAggregator::Mean,
124 epochs: 1,
125 negative_samples: 20,
126 learning_rate: 0.000_002,
127 feature_properties: Vec::new(),
128 seed: 0,
129 }
130 }
131}
132
133/// Fast random projection v1 options.
134#[derive(Debug, Clone, PartialEq)]
135pub struct FastRpOptions {
136 /// Output vector width.
137 pub dimensions: usize,
138 /// Ordered coefficients for `H_0..H_t`.
139 pub iteration_weights: Vec<f64>,
140 /// Degree normalization exponent.
141 pub normalization_strength: f64,
142 /// Weight of the optional feature projection.
143 pub feature_weight: f64,
144 /// Ordered graph-native scalar feature properties.
145 pub feature_properties: Vec<String>,
146 /// Caller seed; omission normalizes to zero.
147 pub seed: u64,
148}
149
150impl Default for FastRpOptions {
151 fn default() -> Self {
152 Self {
153 dimensions: 128,
154 iteration_weights: vec![0.0, 1.0, 1.0],
155 normalization_strength: 0.0,
156 feature_weight: 0.0,
157 feature_properties: Vec::new(),
158 seed: 0,
159 }
160 }
161}
162
163/// HashGNN v1 options.
164#[derive(Debug, Clone, PartialEq)]
165pub struct HashGnnOptions {
166 /// Output vector width.
167 pub dimensions: usize,
168 /// Minhash propagation rounds.
169 pub iterations: usize,
170 /// Initial active-coordinate fraction.
171 pub embedding_density: f64,
172 /// Whether explicit heterogeneous type properties enter hashing.
173 pub heterogeneous: bool,
174 /// Explicit graph-native node type property.
175 pub node_type_property: Option<String>,
176 /// Explicit graph-native relationship type property.
177 pub relationship_type_property: Option<String>,
178 /// Caller seed; omission normalizes to zero.
179 pub seed: u64,
180}
181
182impl Default for HashGnnOptions {
183 fn default() -> Self {
184 Self {
185 dimensions: 256,
186 iterations: 2,
187 embedding_density: 0.25,
188 heterogeneous: false,
189 node_type_property: None,
190 relationship_type_property: None,
191 seed: 0,
192 }
193 }
194}