dgf.sampling
dgf.sampling.Sampler
Sampler for generating subgraphs from an in-memory graph.
multisubgraph
Extracts the subgraphs around the provided seed nodes.
This method returns the graphs containing all the nodes and edges at a
distance less than or equal to the configured number of hops from the
provided seed_node_idxs. Each seed-node leads to the creation of a
different sub-graph independently.
The seed nodes are always the first node of the extracted graph.
Functionally, multisubgraph returns the same results as sample with an
infinite width, but is massively more efficient. Both multisubgraph and
sample use a graph traversal algorithm. However, multisubgraph doesn't
re-visit nodes, which can make it more efficient.
Usage example:
graph, schema = dgf.io.read_graph(<path to graph>)
config = dgf.sampling.SimpleSamplingConfig(
seed_nodeset="client",
num_hops=4,
hop_width=1, # Not used with "subgraph".
reverse=True,
)
sampler = dgf.sampling.create_sampler(graph, config, schema)
subgraph = sampler.subgraph([0,1,2])
print(subgraph)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
seed_node_idxs
|
List[int]
|
The indexes of the nodes to start sampling from. |
required |
Returns:
| Type | Description |
|---|---|
List[InMemoryGraph]
|
A list of graphs. One for each "seed_node_idxs" value. |
sample
sample
sample
Samples one (or multiple) subgraphs.
Grows one or more graph samples starting from the provided seed nodes. Each graph sample is constructed by randomly traversing edges and aggregating all visited edges and nodes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
seed_node_idxs
|
Union[int, List[int], ndarray]
|
The index or indexes of the nodes to start sampling from. Sampling multiple nodes at the same time is more efficient that calling "sample" multiple times. |
required |
seed_timestamps
|
Optional[Union[int, List[int], ndarray]]
|
Optional timestamps for time-aware sampling. If specified, only sample edges with a timestamp anterior (non strict) to the provided seed_timestamp. Should have the same length as "seed_node_idxs". Requires for the sampler to be initialized with some timestamps. |
None
|
masked_edge_idxs
|
Optional[Union[int, List[int], ndarray]]
|
Optional edge indices to mask during sampling. If specified, masks the specified edge. Should have the same length as "seed_node_idxs". Requires for the sampler to be initialized with a masked edgeset. If a seed node idx is -1, not edge filtering is done. |
None
|
Returns:
| Type | Description |
|---|---|
Union[InMemoryGraph, List[InMemoryGraph]]
|
An |
Union[InMemoryGraph, List[InMemoryGraph]]
|
representing the sampled subgraph. |
set_return_options
Sets whether to return features and node indices in sampled graphs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
return_features
|
bool
|
Whether to include feature values in the returned graph. |
required |
return_node_idxs
|
bool
|
Whether to include node indexes in the returned graph as a "#idx" node feature. |
required |
subgraph
Extracts the subgraph around the provided seed nodes.
This method returns a graph containing all the nodes and edges at a
distance less than or equal to the configured number of hops from the
provided seed_node_idxs.
The seed nodes are always the first nodes of their respective node set in
the returned InMemoryGraph. For example, if seed_node_idxs contains 3
elements from a specific node set, these will correspond to the first 3
nodes of that same node set in the extracted graph.
Warning: Unlike "sample" that returns a different graph for each seed-node,
"subgraph" returns a single possibly connected graph. To compute independent
subgraphs, use multisubgraph instead.
Usage example:
graph, schema = dgf.io.read_graph(<path to graph>)
config = dgf.sampling.SimpleSamplingConfig(
seed_nodeset="client",
num_hops=4,
hop_width=1, # Not used with "subgraph".
reverse=True,
)
sampler = dgf.sampling.create_sampler(graph, config, schema)
subgraph = sampler.subgraph([0,1,2])
print(subgraph)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
seed_node_idxs
|
List[int]
|
The indexes of the nodes to start sampling from. |
required |
Returns:
| Type | Description |
|---|---|
InMemoryGraph
|
The resulting graph. |
dgf.sampling.SamplingPlan
Defines a complex sampling config.
Attributes:
| Name | Type | Description |
|---|---|---|
root |
PlanNode
|
The root node of the sampling plan, specifying the starting nodeset. |
with_replacement |
bool
|
Test if the sampling is done with replacement. See documentation for "with_replacement" attribute in SimpleSamplingConfig for the full explanation. |
temporal_sampling |
bool
|
If True, temporal sampling is enabled and causal timestamps are inferred from the schema. |
edgeset_timestamp_features |
Dict[str, str]
|
Mapping from edgeset name to its timestamp feature name for causal filtering. |
dgf.sampling.SimpleSamplingConfig
Configuration for simple neighborhood sampling.
This configuration defines a simple, breadth-first sampling strategy. Starting
from a specified seed_nodeset, it performs a fixed number of num_hops.
At each hop, for every edge type connected to the current nodeset, up to
hop_width neighbors are sampled.
Attributes:
| Name | Type | Description |
|---|---|---|
seed_nodeset |
str
|
The name of the nodeset from which to start the sampling. |
num_hops |
int
|
The maximum number of hops (steps) to perform outwards from the
|
hop_width |
int
|
The maximum number of neighbors to sample for each edge type at
every hop. If more than |
reverse |
bool
|
If True, edges can be traversed in both their defined direction and the reverse direction. If False, only the defined forward direction of edges is used. |
with_replacement |
bool
|
If false, the sampled graph is a sub-graph of the original graph with cycles (if the original graph has cycles). Nodes / edges that are visited multiple times do not lead to multiple nodes / edges in the sampled graph. If true, the sampled graph is a tree where nodes / edges in the original graph might lead to multiple nodes / edges in the sampled grpah. |
temporal_sampling |
bool
|
If True, temporal sampling is enabled and causal timestamps are inferred from the schema. |
dgf.sampling.SpannerGraphSampler
Sampler that executes queries on Spanner directly to fetch subgraphs.
sample
Samples subgraphs starting from the given seed nodes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
seed_ids
|
List[bytes]
|
The list of node IDs (as bytes) to use as seeds. |
required |
Returns:
| Type | Description |
|---|---|
List[InMemoryGraph]
|
A list of InMemoryGraph objects corresponding to the subgraphs sampled for |
List[InMemoryGraph]
|
each seed ID. |
dgf.sampling.create_graph_spanner_sampler
dgf.sampling.create_sampler
Creates an in-memory sampler.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
graph
|
InMemoryGraph
|
The in-memory heterogeneous graph to sample from. |
required |
plan
|
Union[SimpleSamplingConfig, SamplingPlan]
|
The sampling plan configuration. Can be a |
required |
schema
|
GraphSchema
|
Graph schema. Required if |
required |
batch_size
|
Optional[int]
|
Number of samples you will sample each time. Sampling more / less samples at the same time is possible but possibly less efficient.. |
None
|
return_features
|
bool
|
Whether to include feature values in the returned graph. |
True
|
return_node_idxs
|
bool
|
Whether to include node indexes in the returned graph in as a "#idx" node feature. |
False
|
debug_sampling
|
bool
|
If true, enables a deterministic debug mode. In this mode, sampling always selects the first available edges, making the process fully reproducible. |
False
|
num_threads
|
Optional[int]
|
Number of sampling threads. If None, select the number of threads automatically. Set num_threads=0 to disable multi-threading. |
None
|
seed
|
Optional[int]
|
A positive integer to use as random seed for the sampler. If not provided, the seed is randomly initialized. Note that variation in the compilation can lead to variation (e.g., recompiling the binary might lead to different results--though this should be rare). Note: For writing unit tests,using debug_sampling=True is better. |
None
|
edgeset_to_mask
|
Optional[str]
|
Optional edgeset name to mask during sampling. |
None
|
slice_timeseries_by_seed
|
Optional[bool]
|
Whether to causally slice |
None
|
max_timeseries_len
|
Optional[int]
|
Optional cap on the number of historical causal sequence steps retained for each timeseries feature. |
None
|
TODO(gbm): Should we remove the compilation variations (e.g., change in random number generator, change in hashmaps).
Returns:
| Type | Description |
|---|---|
Sampler
|
A |
dgf.sampling.extract_beam_nodes_ids
Extracts all the node ids of a given nodeset.
This method can be used to create the seed nodes argument for the sampler.
See "sample_with_beam_semi_distributed_sampler" for a usage example.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
graph
|
Graph
|
The distributed graph containing the node sets. |
required |
target_nodeset
|
str
|
The name of the node set from which to extract node IDs. |
required |
Returns:
| Type | Description |
|---|---|
PCollection[NodeId]
|
A |
PCollection[NodeId]
|
from the specified |
dgf.sampling.sample_with_beam_semi_distributed_sampler
Samples subgraphs from a distributed graph using a semi-distributed algo.
WARNING: This sampler is not operational. Use the "sample_with_beam_semi_distributed_sampler_v2".
This beam sampler generates samples by running the in-process sampler multiple times in parallel on different workers. Only the final feature gathering is distributed. This sampler is suited for graph where the topologie fits in memory. For reference, a graph with 1B edges and 100M nodes takes (1B + 100M) * 8 = ~9GB of RAM (assuming uint64 indexing, no compression).
Usage example:
# Read HGraph
graph = dgf.io.ReadFromHGraph("/cns/.../my_hgraph")
# Create the sampling config / plan
sampling_config = dgf.sampling.SimpleSamplingConfig(
seed_nodeset="paper", num_hops=2, hop_width=3)
sampling_plan = dgf.sampling.simple_sampling_config_to_sampling_plan(
sampling_config,
graph.schema,
)
# Get all the nodes as seeds
seeds = dgf.sampler.extract_beam_nodes_ids(graph, "paper")
# Generate samples
samples = dgf.sampler.sample_with_beam_semi_distributed_sampler(
graph, plan seeds)
# Save the samples to disk
dgf.io.write_to_tf_graph_sample(samples, "/cns/.../samples@*")
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
graph
|
Graph
|
The distributed graph to sample from.. |
required |
plan
|
SamplingPlan
|
The sampling plan.. |
required |
seeds
|
PCollection[NodeId]
|
PCollection of node IDs to use as seed. These IDs must belong to the
nodeset specified in |
required |
debug_sampling
|
bool
|
If true, enables debug mode in the sampler. Used for unit testing. |
False
|
Returns:
| Type | Description |
|---|---|
PCollection[PKeyedInMemoryGraph]
|
A |
PCollection[PKeyedInMemoryGraph]
|
instance represents a sampled subgraph. |
dgf.sampling.sample_with_beam_semi_distributed_sampler_v2
Samples subgraphs from a distributed graph using a semi-distributed algo.
This beam sampler generates samples by running the in-process sampler multiple times in parallel on different workers. Only the final feature gathering is distributed. This sampler is suited for graph where the topology fits in memory. For reference, a graph with 1B edges and 100M nodes takes (1B + 100M) * 8 = ~9GB of RAM (assuming uint64 indexing, no compression).
Usage example:
graph_path = ...
# Use all the nodes as seed nodes.
graph = dgf.beam.io.read_graph(root, graph_path)
seeds = dgf.sampler.extract_beam_nodes_ids(graph, "paper")
seeds = seeds | "Reshuffle seeds" >> beam.Reshuffle()
# Create the sampling config
sampling_config = dgf.sampling.SimpleSamplingConfig(
seed_nodeset="paper", num_hops=2, hop_width=3)
# Generate samples
samples = dgf.sampler.sample_with_beam_semi_distributed_sampler_v2(
graph_path, sampling_config, seeds)
# Save the samples to disk
dgf.io.write_to_tf_graph_sample(samples, "/cns/.../samples@*")
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
graph_path
|
str
|
Path to graph on disk. |
required |
plan
|
Union[SimpleSamplingConfig, SamplingPlan]
|
The sampling plan.. |
required |
seeds
|
PCollection[NodeId]
|
PCollection of node IDs to use as seed. These IDs must belong to the
nodeset specified in |
required |
debug_sampling
|
bool
|
If true, enables debug mode in the sampler. Used for unit testing. |
False
|
num_threads
|
int
|
The number of threads used by each worker. |
20
|
beam_feature_collection
|
bool
|
If False (default), the feature values are gathered by the in-memory sampler. This option is fast but requires more RAM. If false, the feature values are gathered by a Beam join after the sampling. |
False
|
beam_namespace
|
str
|
Prefix added to all the beam ptransforms. |
''
|
Returns:
| Type | Description |
|---|---|
PKeyedInMemoryGraph
|
A |
GraphSchema
|
instance represents a sampled subgraph. |
dgf.sampling.simple_sampling_config_to_sampling_plan
Converts a SimpleSamplingConfig to a more general SamplingPlan.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
src
|
SimpleSamplingConfig
|
The SimpleSamplingConfig to convert. |
required |
schema
|
GraphSchema
|
The graph schema, used to resolve edge connections. |
required |
Returns:
| Type | Description |
|---|---|
SamplingPlan
|
A SamplingPlan equivalent to the provided SimpleSamplingConfig. |