fix(learning): text dtypes compatible in replay; merge list memory patterns - #419
Merged
Merged
Conversation
The drift gate only treated object as text, so a profile learned on a categorical or string column and replayed on the same values as object (or the reverse) reported mild drift and dropped that column's value maps and hints. A text categorical replayed on numeric data was also not flagged. Compare text-ness with _util.is_text_dtype on the frame's dtype and a name-based equivalent for the stored learned dtype. object, string, Arrow string and text categoricals are interchangeable; text vs non-text is still reported as drift.
union_min_precision and error_on_conflict assumed every entry of the
embedded memory's value_patterns was a {raw: clean} mapping and raised
ValueError when memory held the semantic_repairs list.
Union list patterns with de-duplication. A semantic repair both sides
propose differently is dropped and recorded under union_min_precision
and raises ProfileMergeError under error_on_conflict; differing scalar
patterns are handled the same way. prefer_self/prefer_other still copy
the preferred side's memory.
The masking salt comes from the frame signature (row count, dtypes and a head sample), so the same values can mask to different tokens in different profiles and merged profiles cannot match each other's masked entries.
Contributor
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
FreshData benchmark report —
|
| fixture | n_rows | n_cols | p50 s | p95 s | peak MB | repair % | false-repair % | preserve % | trust | monotonic | export % |
|---|
Authored-code reduction (Metric 6)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This fixes two bugs in learned profiles and documents one existing behaviour.
mergewithunion_min_precisionorerror_on_conflictno longer crashes when the embedded memory holds asemantic_repairslist.Root cause
Replay:
check_profile_drifttreated onlyobjectas text. When a profile learned on a categorical or string column was replayed on object data (or the reverse), it reported mild drift and didn't replay that column's value maps and hints. The same check also missed drift when a text categorical became numeric.Merge: the union path assumed every
value_patternsentry was a{raw: clean}mapping. It calleddict()on thesemantic_repairslist, which raisedValueError: dictionary update sequence element #0 has length 4.error_on_conflictgoes through the same path, and memory was only merged after the conflict check.Changes:
is_text_dtypehelper. Text dtypes are interchangeable, and text vs non-text still counts as drift. A storedcategorycarries no category info, so it is treated as text, as memory signatures already do.union_min_precision, the repair is dropped and recorded;error_on_conflict, it raisesProfileMergeError.Scalar patterns that differ are handled the same way. Conflict messages name only the column and issue type, never raw values.
prefer_selfandprefer_otherare unchanged.Behaviour change: a text categorical replayed as numeric is now reported as drift. So is a numeric categorical learned and then replayed as int64.
Tests
none, every column compatible, value maps replayed;semantic_repairsunion with duplicates removed;17 of the new tests fail on the previous code.
Verification
ruff check .andmypy src/freshdata: clean.pytest -m "not online and not large":