-
Notifications
You must be signed in to change notification settings - Fork 236
Feat/add string derivation detection skill #2472
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
eugeneboms
wants to merge
8
commits into
microsoft:main
Choose a base branch
from
eugeneboms:feat/add-string-derivation-detection-skill
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
2f0a9d5
feat(skills): add string-derivation detection skill for data science
24f66ad
chore(collections): add string-derivation skill to data-science and h…
c30750c
fix(skills): add frontmatter to algorithms.md and apply table formatting
effd4e8
fix(skills): resolve PSScriptAnalyzer warnings in detect-string-deriv…
f83f362
chore(skills): add copyright headers to string-derivation scripts
7fe93c3
chore: apply table formatting fixes
2220cec
Potential fix for pull request finding
eugeneboms fb0e923
Merge branch 'main' into feat/add-string-derivation-detection-skill
jkim323 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
309 changes: 309 additions & 0 deletions
309
.github/skills/data-science/data-reduction/string-derivation/SKILL.md
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,309 @@ | ||
| --- | ||
| name: string-derivation | ||
| description: Detect derivable data columns via string operations for data reduction - Brought to you by microsoft/hve-core | ||
| user-invocable: true | ||
| --- | ||
|
|
||
| # String Derivation Detection | ||
|
|
||
| ## Overview | ||
|
|
||
| Detects data columns that can be derived from other columns using string operations, enabling safe column removal for data reduction. Identifies 9 derivation patterns including lookup expansion (CODE→DESCRIPTION), concatenation, substring extraction, and edit distance transformations using progressive sampling for performance. | ||
|
|
||
| Enterprise datasets often contain redundant string columns where one column is a deterministic transformation of another. This skill identifies these relationships so derived columns can be safely removed, reducing dataset dimensionality without information loss. Uses progressive sampling (3→10→30 rows) to achieve 10-100x speedup over full-dataset testing. | ||
|
|
||
| **Common patterns detected:** | ||
| - **Lookup expansion**: `GENDER` ('F', 'M') → `GENDER_DESCRIPTION` ('Female', 'Male') | ||
| - **Concatenation**: `FIRST_NAME` + `LAST_NAME` → `FULL_NAME` | ||
| - **Substring**: `EMPLOYEE_ID` contains `DEPT_CODE` | ||
| - **Character removal**: `PHONE_NUMBER` = `PHONE_DISPLAY` with formatting removed | ||
| - **Case transformation**: `email` vs `EMAIL` | ||
| - **Numeric extraction**: `ORDER_123` → `123` | ||
| - **Edit distance**: Systematic 1-2 character transformations | ||
| - **Format strings**: `{STATE}: {CITY}` patterns | ||
| - **Boolean checks**: Derived true/false flags | ||
|
|
||
| ## When to Use | ||
|
|
||
| Use this skill when: | ||
| - Reducing dimensionality of string columns while preserving information | ||
| - Identifying redundant columns for removal (CODE vs DESCRIPTION columns) | ||
| - Dataset contains >10 string columns with potential derivations | ||
| - Preparing data for machine learning (feature engineering) or ontology building | ||
| - Optimizing storage or processing by eliminating derived columns | ||
| - Building data dictionaries that document column relationships | ||
|
|
||
| **Do not use when:** | ||
| - Dataset has <30 rows (insufficient sample size) | ||
| - All columns are numeric (skill focuses on string operations) | ||
| - You need exact deterministic guarantees (uses sampling for performance) | ||
|
|
||
| **Common patterns detected:** | ||
| - **Lookup expansion**: `GENDER` ('F', 'M') → `GENDER_DESCRIPTION` ('Female', 'Male') | ||
| - **Concatenation**: `FIRST_NAME` + `LAST_NAME` → `FULL_NAME` | ||
| - **Substring**: `EMPLOYEE_ID` contains `DEPT_CODE` | ||
| - **Character removal**: `PHONE_NUMBER` = `PHONE_DISPLAY` with formatting removed | ||
| - **Case transformation**: `email` vs `EMAIL` | ||
| - **Numeric extraction**: `ORDER_123` → `123` | ||
| - **Edit distance**: Systematic 1-2 character transformations | ||
| - **Format strings**: `{STATE}: {CITY}` patterns | ||
| - **Boolean checks**: Derived true/false flags | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| **Python Dependencies:** | ||
|
Comment on lines
+44
to
+54
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The "Common patterns detected" bullet list appears verbatim twice in this file. This second occurrence is a duplicate of the block already present in the Overview section and should be removed. |
||
| ```bash | ||
| pip install pandas numpy | ||
| ``` | ||
|
|
||
| **Platform:** Python 3.7+ | ||
|
|
||
| **Dataset Requirements:** | ||
| - Tabular data with string (object) columns | ||
| - 100+ rows recommended for reliable pattern detection | ||
| - Multiple string columns to analyze for derivation relationships | ||
|
|
||
| ## Quick Start | ||
|
|
||
| **Note:** The detection algorithms are reference implementations in [references/algorithms.md](references/algorithms.md). Copy the relevant functions (`filter_derivation_candidates`, `detect_all_string_derivations_optimized`, and their dependencies) into your project before using them. | ||
|
|
||
| **Basic usage** (analyze one column): | ||
|
|
||
| ```python | ||
| import pandas as pd | ||
| # After copying functions from references/algorithms.md: | ||
| # from your_module import detect_all_string_derivations_optimized, filter_derivation_candidates | ||
|
|
||
| # Load data | ||
| df = pd.read_csv('data.csv') | ||
| string_cols = df.select_dtypes(include=['object']).columns.tolist() | ||
|
|
||
| # Filter candidates once (recommended for batch processing) | ||
| filtered_candidates = filter_derivation_candidates(df, string_cols) | ||
|
|
||
| # Detect derivations for target column | ||
| derivations = detect_all_string_derivations_optimized( | ||
| df=df, | ||
| target_col='EMPLOYEE_FULL_NAME', | ||
| candidate_cols=string_cols, | ||
| filtered_candidates=filtered_candidates | ||
| ) | ||
|
|
||
| # Show results | ||
| if derivations: | ||
| best = derivations[0] | ||
| print(f"Formula: {best['formula']}") | ||
| print(f"Confidence: {best['match_ratio']:.1%}") | ||
| ``` | ||
|
|
||
| **Batch processing** (all string columns): | ||
|
|
||
| ```python | ||
| # Filter candidates ONCE before loop (critical for performance) | ||
| filtered_candidates = filter_derivation_candidates(df, string_cols) | ||
|
|
||
| # Analyze all columns | ||
| all_findings = {} | ||
| for col in string_cols: | ||
| derivations = detect_all_string_derivations_optimized( | ||
| df, col, string_cols, | ||
| filtered_candidates=filtered_candidates, | ||
| verbose=True # Show progress | ||
| ) | ||
| if derivations: | ||
| all_findings[col] = derivations[0] # Store best match | ||
|
|
||
| # Summary | ||
| print(f"\nFound derivations for {len(all_findings)}/{len(string_cols)} columns") | ||
| for col, deriv in all_findings.items(): | ||
| print(f"{col} ← {deriv['formula']} ({deriv['match_ratio']:.1%})") | ||
| ``` | ||
|
|
||
| ## Parameters Reference | ||
|
|
||
| ### filter_derivation_candidates | ||
|
|
||
| Filters candidate columns based on cardinality and naming patterns. **Call once before batch processing.** | ||
|
|
||
| | Parameter | Type | Default | Description | | ||
| |-------------------|-----------|----------|-------------------------------------------------| | ||
| | `df` | DataFrame | Required | DataFrame containing the data | | ||
| | `candidate_cols` | list[str] | Required | Column names to filter | | ||
| | `max_cardinality` | int | 1000 | Skip columns with >N unique values (likely IDs) | | ||
| | `max_candidates` | int | 50 | Maximum candidates to return | | ||
|
|
||
| **Returns:** `list[str]` - Filtered column names prioritizing CODE/NAME/DESC/TYPE/STATUS patterns | ||
|
|
||
| ### detect_all_string_derivations_optimized | ||
|
|
||
| Detects all string derivations for a target column using progressive sampling. | ||
|
|
||
| | Parameter | Type | Default | Description | | ||
| |-----------------------|-----------|----------|-----------------------------------------------------| | ||
| | `df` | DataFrame | Required | DataFrame containing the data | | ||
| | `target_col` | str | Required | Column to analyze for derivations | | ||
| | `candidate_cols` | list[str] | Required | All column names (used if filtered_candidates=None) | | ||
| | `filtered_candidates` | list[str] | None | Pre-filtered candidates (RECOMMENDED for batch) | | ||
| | `verbose` | bool | False | Print phase-by-phase progress | | ||
|
|
||
| **Returns:** `list[dict]` - Derivation findings sorted by confidence (highest first) | ||
|
|
||
| **Derivation dictionary schema:** | ||
| ```python | ||
| { | ||
| 'type': str, # 'lookup_expansion', 'concatenation', 'substring', etc. | ||
| 'operands': list[str], # Source column name(s) | ||
| 'formula': str, # Human-readable formula | ||
| 'match_ratio': float, # Confidence score (0.0-1.0) | ||
| # Type-specific fields (varies by derivation) | ||
| } | ||
| ``` | ||
|
|
||
| ## Usage Patterns | ||
|
|
||
| ### Pattern 1: Quick Single-Column Check | ||
|
|
||
| Check if one specific column is derived from others: | ||
|
|
||
| ```python | ||
| derivations = detect_all_string_derivations_optimized(df, 'FULL_NAME', string_cols) | ||
| if derivations and derivations[0]['match_ratio'] >= 0.95: | ||
| print(f"✅ Can remove {target_col}: {derivations[0]['formula']}") | ||
| ``` | ||
|
|
||
| ### Pattern 2: Full Dataset Scan | ||
|
|
||
| Scan all string columns to build a column dependency graph: | ||
|
|
||
| ```python | ||
| filtered = filter_derivation_candidates(df, string_cols) | ||
| dependencies = {} | ||
| for col in string_cols: | ||
| derivs = detect_all_string_derivations_optimized(df, col, string_cols, filtered) | ||
| if derivs and derivs[0]['match_ratio'] >= 0.95: | ||
| dependencies[col] = derivs[0] | ||
|
|
||
| # Remove derived columns | ||
| safe_to_remove = list(dependencies.keys()) | ||
| df_reduced = df.drop(columns=safe_to_remove) | ||
| print(f"Reduced from {len(df.columns)} to {len(df_reduced.columns)} columns") | ||
| ``` | ||
|
|
||
| ## Algorithm Reference | ||
|
|
||
| See [references/algorithms.md](references/algorithms.md) for: | ||
| - **Complete Python implementations** of all 9 detection algorithms | ||
| - **Progressive sampling strategy** details (3→10→30 rows) | ||
| - **Performance optimization** techniques and complexity analysis | ||
| - **Full API reference** with parameter schemas | ||
| - **Detection type schemas** for each derivation pattern | ||
| - **Helper functions** and dependencies | ||
|
|
||
| ## Sample Prompts | ||
|
|
||
| **User Request:** | ||
|
|
||
| "Analyze my employee dataset to find redundant string columns that can be derived from other columns" | ||
|
|
||
| or | ||
|
|
||
| "Detect which columns in data.csv are lookup expansions or concatenations of other columns" | ||
|
|
||
| **Execution Flow:** | ||
|
|
||
| 1. **User invokes skill** via natural language request mentioning "string derivation", "redundant columns", "derived columns", or "data reduction" | ||
| 2. **Skill loads data** using pandas to read CSV file | ||
| 3. **Filter candidates** once using `filter_derivation_candidates()` to: | ||
| - Skip high-cardinality columns (>1000 unique values) | ||
| - Prioritize CODE/NAME/DESC/TYPE/STATUS pattern columns | ||
| - Limit to top 50 candidates | ||
| 4. **Progressive sampling detection** for each target column: | ||
| - Phase 1: Test all 9 detection types on 3 samples (100% match required) | ||
| - Phase 2: Re-test survivors on 10 samples (100% match required) | ||
| - Phase 3: Final validation on 30 samples (≥95% match accepted) | ||
| 5. **Sort results** by confidence (match_ratio descending) | ||
| 6. **Generate report** with derivation formulas and confidence scores | ||
|
|
||
| **Output Artifacts:** | ||
|
|
||
| CSV file `string_derivation_report.csv`: | ||
| ```csv | ||
| target_column,derivation_type,source_columns,formula,match_ratio,details | ||
| GENDER_DESCRIPTION,lookup_expansion,GENDER,GENDER_DESCRIPTION = lookup(GENDER),0.98,"{""sample_mapping"": [[""F"", ""Female""], [""M"", ""Male""]]}" | ||
| FULL_NAME,concatenation,"FIRST_NAME,LAST_NAME",FULL_NAME = FIRST_NAME + " " + LAST_NAME,1.0,"{""separator"": "" ""}" | ||
| PHONE_NUMBER,character_removal,PHONE_DISPLAY,PHONE_NUMBER = PHONE_DISPLAY.replace([- ()], ""),0.97,"{""characters"": ""- ()""}" | ||
| DEPT_CODE,substring,EMPLOYEE_ID,DEPT_CODE is substring of EMPLOYEE_ID,1.0,"{}" | ||
| EMAIL_LOWER,case_transformation,EMAIL,EMAIL_LOWER = case_transform(EMAIL),1.0,"{}" | ||
| ``` | ||
|
|
||
| Console output showing progress: | ||
| ``` | ||
| Loading data from employee_data.csv... | ||
| Found 45 string columns in dataset | ||
| Filtered to 32 candidate columns | ||
|
|
||
| Analyzing column: GENDER_DESCRIPTION | ||
| Phase 1: Testing with 3 samples... | ||
| Phase 2: Re-testing 5 candidates with 10 samples... | ||
| Phase 3: Final validation of 2 candidates with 30 samples... | ||
|
|
||
| Found 12 derivations | ||
| Results saved to: string_derivation_report.csv | ||
| ``` | ||
|
|
||
| **Success Indicators:** | ||
|
|
||
| 1. **Report generated** - CSV file exists with derivation findings | ||
| 2. **High confidence matches** - match_ratio ≥ 0.95 for actionable findings | ||
| 3. **Derivation types identified** - Clear formulas showing how columns are derived | ||
| 4. **Reduced column count** - Can safely remove derived columns, reducing from N to N-K columns | ||
| 5. **Performance acceptable** - Detection completes in <5 minutes for 100-column datasets | ||
|
|
||
| **Validation steps:** | ||
| - Verify formulas by spot-checking a few rows manually | ||
| - Confirm match_ratio is ≥95% before removing columns | ||
| - Test data pipeline with reduced dataset to ensure no information loss | ||
| - Compare memory/processing time before and after reduction | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### Slow performance on large datasets | ||
|
|
||
| **Symptom:** Detection takes >10 minutes for 100+ columns | ||
|
|
||
| **Solutions:** | ||
| 1. **Always use filtered_candidates** - Compute once, reuse for all columns | ||
| 2. **Increase max_cardinality threshold** - Skip more high-cardinality columns | ||
| 3. **Reduce max_candidates** - Limit to top 30-40 most likely candidates | ||
| 4. **Skip concatenation** - O(n²) complexity; test manually if needed | ||
| 5. **Disable verbose mode** - Printing slows down tight loops | ||
|
|
||
| ### False positives (low confidence matches) | ||
|
|
||
| **Symptom:** Derivations found with <95% match ratio | ||
|
|
||
| **Solutions:** | ||
| 1. **Increase sampling size** - Modify progressive sampling to use more rows | ||
| 2. **Check data quality** - Inconsistent formatting breaks pattern detection | ||
| 3. **Review match_ratio threshold** - Only act on ≥95% confidence findings | ||
|
|
||
| ### Missing obvious derivations | ||
|
|
||
| **Symptom:** Known derived columns not detected | ||
|
|
||
| **Solutions:** | ||
| 1. **Check cardinality filtering** - Lower max_cardinality to include more candidates | ||
| 2. **Verify data types** - Only detects string (object) columns | ||
| 3. **Review naming patterns** - Add keywords to filter_derivation_candidates priority list | ||
| 4. **Check for data corruption** - Null values or encoding issues break matching | ||
|
|
||
| ### Memory errors | ||
|
|
||
| **Symptom:** Out of memory when processing very wide datasets (300+ columns) | ||
|
|
||
| **Solutions:** | ||
| 1. **Reduce max_candidates** - Process in smaller batches | ||
| 2. **Filter by column type** - Exclude numeric columns from string_cols | ||
| 3. **Process chunks** - Split string_cols into batches of 50 | ||
|
|
||
| > Brought to you by microsoft/hve-core | ||
Oops, something went wrong.
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The frontmatter is missing
license: MITand themetadatablock (authors,spec_version,last_updated) that all other skills in this repository include. See.github/skills/shared/pr-reference/SKILL.md,.github/skills/experimental/powerpoint/SKILL.md, or.github/skills/coding-standards/code-review/SKILL.mdfor examples of the expected structure.