DO NOT MERGE: Add dataset builder docs - #1857
Conversation
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
documentation | 96d0049 | Commit Preview URL Branch Preview URL |
Aug 04 2026, 09:17 AM |
Documentation style reviewOverall this is a well-structured, cleanly written page — good frontmatter, sentence-case headings, 4 H2 sections (within the 3–5 limit), correct terminology, and all internal links ( 1. Bold used for non-UI text (CLAUDE.md)CLAUDE.md: "Use bold only for UI elements (buttons, page titles)." The stage names in the "How it works" list are bolded but aren't UI elements:
Suggest removing the bold (the names are already emphasized by their list position), e.g. 2. Underscore name not in backticks (style guide)Style guide: "If the name has underscores, use code formatting."
Should be 3. Spaced hyphens used as dashes (minor)Several sentences use a spaced hyphen
Prefer an em dash or restructure with a colon/commas, e.g. "You specify a goal (the criteria that define a positive outcome) and a time window to scan." This applies in a few other places (the "How it works" list items, "Session anchors" intro). Minor noteThe |
jborlase-snowplow
left a comment
There was a problem hiding this comment.
Added some comments.
I think we need a tutorial to alongside the release of this to make it clear on how we expect this to be used.
|
|
||
| The dataset builder produces a training dataset in three stages: | ||
|
|
||
| 1. **Anchors** - identify moments in historical sessions where a user either achieved a goal (positive label) or did not (negative label) |
There was a problem hiding this comment.
I think this section could use a diagram to make it clear how anchors and attributes work
|
|
||
| Use the Signals Python SDK to build labeled training datasets from your [attribute groups](/docs/signals/attributes/attribute-groups/index.md). The dataset builder generates SQL that computes attribute values over historical data and joins them with labeled anchor events, producing a dataset ready for model training. | ||
|
|
||
| Start by [connecting to Signals](/docs/signals/connection/index.md) to create a `Signals` client object. |
There was a problem hiding this comment.
We should have a more high-level why / how it works section showing how this is meant to be used to enable you to train ML models using same definitions as your attribute groups that you can use to serve the attributes to your ML models
There was a problem hiding this comment.
and there we can highlight why PIT correctness is important
There was a problem hiding this comment.
We should also highlight the overall process we expect users to take - not just the flow on how the dataset builder works.
| schema="ml", | ||
| table="my_anchor_events", | ||
| ), | ||
| has_label=True, |
There was a problem hiding this comment.
What does label need to look like?
| from snowplow_signals import UserSuppliedAnchors, WarehouseTable | ||
|
|
||
| anchors = UserSuppliedAnchors( | ||
| source=WarehouseTable( |
There was a problem hiding this comment.
Can we show an example input table and requirements?
| start_time=datetime(2024, 1, 1, tzinfo=timezone.utc), | ||
| end_time=datetime(2024, 4, 1, tzinfo=timezone.utc), | ||
| ), | ||
| ) |
There was a problem hiding this comment.
Can we show example output of what this creates?
|
|
||
| ## Execute against your warehouse | ||
|
|
||
| Execute the generated SQL directly against your warehouse to produce the training dataset. |
There was a problem hiding this comment.
We should explain a bit about how - for example - using your existing Signals warehouse connection...
| account=os.environ["SNOWFLAKE_ACCOUNT"], | ||
| user=os.environ["SNOWFLAKE_USER"], | ||
| warehouse=os.environ["SNOWFLAKE_WAREHOUSE"], | ||
| private_key=private_key_der, |
There was a problem hiding this comment.
What is the private key? Do we just auth via this? Is that the Snowflake term?
| | `source` | Table containing your pre-built anchor events | `WarehouseTable` | ✅ | | ||
| | `has_label` | Whether the source table contains a label column | `bool` | Default: `True` | | ||
|
|
||
| ## Build the dataset |
There was a problem hiding this comment.
This header shouldn't be build the dataset - its more related to building the SQL rather than the actual dataset
| print(df.head()) | ||
| ``` | ||
|
|
||
| You can also inspect the execution stages: |
There was a problem hiding this comment.
What are the execution stages?
There was a problem hiding this comment.
If it is for monitoring execution - this doesn't feel like it should be in this section
| After execution, convert the result to a pandas DataFrame for analysis or model training. | ||
|
|
||
| ```python | ||
| df = result.to_pandas() |
There was a problem hiding this comment.
We should show example of what is the output
4e22634 to
787b1f8
Compare
| After execution, access the `dataframe` attribute to get the training dataset as a pandas DataFrame, ready for model training. | ||
|
|
||
| ```python | ||
| df = result.dataframe |
There was a problem hiding this comment.
Just a note to update this to reflect the changes in the SDK.
jborlase-snowplow
left a comment
There was a problem hiding this comment.
Few more suggestions to the structure
| 4. Execute the SQL against your warehouse to produce the training dataset | ||
| 5. Train your model on the resulting DataFrame | ||
| 6. Deploy your model, serving it the same attributes in real time via [Retrieve attributes](/docs/signals/applications/retrieve-attributes/index.md) | ||
| 2. Submit a dataset run by calling the appropriate method - `submit_dataset_run_with_session_anchors()` for auto-generated anchors, or `submit_dataset_run_with_custom_anchors()` for a pre-existing anchor table |
There was a problem hiding this comment.
We should abstract these steps - as both methods now exists.
- Prepare the dataset SQL...
- Generate your SQL by running the queries against your warehouse - you can do this by X or Y.
| ### Session anchors | ||
|
|
||
| Use `build_dataset_with_session_anchors()` to automatically generate anchors from your event data. You specify a goal (the criteria that define a positive outcome) and a time window to scan. Signals scans all sessions in the training window and labels each based on whether the goal was achieved. For positive sessions, anchors are placed at the goal event itself. For negative sessions (where the goal was never achieved), anchors are placed at randomly selected events within the session. Negative anchors are then downsampled according to `max_negative_ratio` to avoid class imbalance. | ||
| Use `submit_dataset_run_with_session_anchors()` to automatically generate anchors from your event data and build the training dataset server-side. You specify a goal (the criteria that define a positive outcome) and a time window to scan. Signals scans all sessions in the training window and labels each based on whether the goal was achieved. For positive sessions, anchors are placed at the goal event itself. For negative sessions (where the goal was never achieved), anchors are placed at randomly selected events within the session. Negative anchors are then downsampled according to `max_negative_ratio` to avoid class imbalance. |
There was a problem hiding this comment.
Did we completely remove the other option? Shouldn't there be both in here now?
| | `max_lookback_days` | How far back from each anchor timestamp to look for events when computing attributes. By default, this is derived from the longest period defined across your attributes. | `int` | Default: derived from attribute periods | | ||
|
|
||
| ## Inspect and save the SQL bundle | ||
| ## Poll for completion and retrieve results |
There was a problem hiding this comment.
Same here, this should be additional and probably under a heading where customers can decide to run it themselves or let us manage it.
| ### Get results as a DataFrame | ||
|
|
||
| After execution, call `to_pandas()` to pull the training dataset into a pandas DataFrame, ready for model training. By default, it fetches up to 10,000 rows. | ||
| Once the run status is `success`, call `get_dataset_run_preview()` to fetch a preview of the completed dataset. By default, it returns up to 100 rows. You can set `limit` up to 10,000. |
There was a problem hiding this comment.
Why just a preview?
There was a problem hiding this comment.
This could be millions of rows - its probably best not to load it into python
There was a problem hiding this comment.
Why not let customers decide how to configure it?
You'd expect to need millions of rows and might have a powerful environment to do just that?
There was a problem hiding this comment.
Sorry probably wasn't clear - this is returned via the signals API, so if we loaded too much data into the json response it could crash our server. I think its ok to expect the customer to fetch the full dataset directly from Snowflake
| | 1 | def-456 | 2024-01-15 10:01:00 | 0 | 3 | 0 | | ||
| | 2 | ghi-789 | 2024-01-16 14:22:00 | 1 | 8 | 4 | | ||
|
|
||
| The full dataset is also written to your warehouse at the table location shown in `run.dataset`. You can query this table directly for the complete result set. |
There was a problem hiding this comment.
If we require them to query table directly - then we should provide example on how to do that
| sp_signals.cancel_dataset_run(run.id) | ||
| ``` | ||
|
|
||
| ## Inspect the generated SQL |
There was a problem hiding this comment.
Oh I see its down here - I would arrange this page into the higher level abstractions as headings I mentioned above, and then within that give the customers the option to choose which way they do it.
What changed?
Docs for as yet unreleased dataset builder AISP 1401 & 1402
AI reviews
Claude will automatically review this PR against the docs style guide.
If you have questions or want it to look again at something specific, tag
@claudein a comment.