| name | bias-detection |
| description | Detect demographic bias in LYDUS data quality metrics by computing all 16 QUIQ quality metrics (completeness, range/date/format/sequence validity, preciseness, fidelity, class/instance diversity, sentence/vocabulary diversity, logical accuracy, cross-sectional/time-series consistency, classification, note accuracy/fidelity) per Sex/Race/Age group and computing GDI (Group Disparity Index). Uses Claude CLI (no API key required). |
| tier | community |
| category | lydus |
| parameters | {"quiq_path":{"description":"Path to QUIQ-format CSV file.","type":"string"},"via_path":{"description":"Path to VIA (Variable Information Annotation) CSV file. Used by format-validity and cross-sectional-consistency.","type":"string"},"save_path":{"description":"Directory path to save output CSVs and sub-metric plots.","type":"string"},"operation_type_manual":{"description":"Passed to logical-accuracy skill. false = automatic mode. Default false.","type":"boolean"},"automatic_num":{"description":"Passed to logical-accuracy skill. Number of variables to analyze automatically. Default 5.","type":"integer"},"recommend_num":{"description":"Passed to logical-accuracy skill. Number of correlated variables to recommend. Default 5.","type":"integer"}} |
Bias Detection
Detects demographic bias in data quality by running all 16 LYDUS quality metrics on patient subgroups (Sex, Race, Age) and comparing scores. The GDI (Group Disparity Index) quantifies how much any group deviates from the overall mean for each metric.
When to Use This Skill
- After QUIQ conversion, to assess whether data quality differs across demographic groups
- To identify metrics where one group is systematically under-served or over-represented
- To generate an equity report for LYDUS quality management assessment
- Before clinical ML model training, to detect data quality biases that may propagate into model bias
SQL Support
Not applicable. Orchestrates Python implementations of all 16 sub-metrics plus Claude CLI calls.
Pipeline Overview
1. LLM identifies Sex / Race / BirthDate columns in QUIQ
2. Build per-patient demographics pivot (one row per Patient_id)
3. Compute Age_Group from BirthDate + Event_date
4. For each group in {Sex, Race, Age_Group}:
Run all 16 quality metrics on the group-filtered QUIQ subset
5. Build results table: rows = metrics, cols = group labels + Mean + GDI
16 Sub-Metrics
| Metric | API Key | Skill |
|---|
| Range Validity | โ | range-validity |
| Date Validity | optional | date-validity |
| Format Validity | optional | format-validity |
| Sequence Validity | Claude CLI | sequence-validity |
| Completeness | โ | completeness |
| Logical Accuracy | Claude CLI | logical-accuracy |
| Cross-Sectional Consistency | Claude CLI | cross-sectional-consistency |
| Time Series Consistency | โ | time-series-consistency |
| Class Diversity | โ | class-diversity |
| Instance Diversity | โ | instance-diversity |
| Fidelity | โ | fidelity |
| Preciseness | โ | preciseness |
| Accuracy / Precision / Recall / F1 / AUROC | โ | classification |
| Note Fidelity | Claude CLI | note-fidelity |
| Note Accuracy | Claude CLI | note-accuracy |
| Vocabulary Diversity | โ | vocabulary-diversity |
| Sentence Diversity | โ | sentence-diversity |
GDI (Group Disparity Index)
GDI = max(|group_score โ mean_score|) across all groups for each metric.
- GDI = 0 โ all groups have identical scores (no bias)
- High GDI โ large disparity between groups for that metric
Demographic Grouping
| Group | Column | Detection | Age Bins |
|---|
| Sex | LLM-identified | biological sex variable | โ |
| Race | LLM-identified | race variable | โ |
| Age | BirthDate + Event_date | date of birth variable | 0-9, 10-19, โฆ, 80+ |
Rows with null Sex/Race/Age_Group are dropped before group iteration.
Output
| File | Description |
|---|
bias_sex_summary.csv | Metrics ร sex groups + Mean + GDI |
bias_race_summary.csv | Metrics ร race groups + Mean + GDI |
bias_age_summary.csv | Metrics ร age groups + Mean + GDI |
| Sub-metric plots | SHAP plots, AUROC plots, boxplots (saved to save_path) |
How to Run
import pandas as pd
from scripts.bias_detection import get_bias_detection
quiq = pd.read_csv("/path/to/quiq.csv")
via = pd.read_csv("/path/to/via.csv")
config = {
'save_path': '/path/to/output',
'operation_type_manual': False,
'target_variable': '',
'automatic_num': 5,
'recommend_num': 5,
}
df_sex, df_race, df_age = get_bias_detection(quiq, via, config)
print(df_sex)
As a script with config
quiq_path: /path/to/quiq.csv
via_path: /path/to/via.csv
save_path: /path/to/output
operation_type_manual: false
target_variable: ""
automatic_num: 5
recommend_num: 5
python scripts/bias_detection.py --config config.yaml
Critical Notes
-
All 16 sub-metrics run per group โ each metric is wrapped in try/except; failures return np.nan without stopping the run. Expect long runtimes for large datasets or many groups.
-
Skill dependency imports โ bias_detection.py dynamically adds sibling skills' scripts/ directories to sys.path at runtime. All 17 sibling skills must be present under the same skills root (~/.claude/skills/ or src/m4/skills/lydus/).
-
์๋ณธ ์ฝ๋ ๋ฒ๊ทธ ์์ :
model_ver / api_key ์ ๊ฑฐ: _llm_ask_column์ด Claude CLI subprocess๋ก ๋์ฒด๋จ
get_time_series_consistency(config['save_path'], quiq) ์ธ์ ์์ ๋ฐ์ โ (quiq, save_path) ๋ก ์์
get_code_validity ๋ฐํ๊ฐ 3๊ฐ ์ธํฉ โ 2๊ฐ(validation_df, error_summary)๋ก ์์
get_unstructured_fidelity / get_unstructured_accuracy โ M4 ์คํฌ์ get_note_fidelity / get_note_accuracy ๋ก ๊ต์ฒด
config['save_path'] = -1 ํ๋์ฝ๋ฉ โ ์ค์ save_path ์ฌ์ฉ
-
GDI ๊ณ์ฐ โ df.sub(df['Mean'], axis=0).abs().max(axis=1): Mean ์ด์ ๋จผ์ ๊ณ์ฐ ํ ๊ทธ๋ฃน ์ด๋ค๊ณผ์ ์ต๋ ์ ๋๊ฐ ํธ์ฐจ. Mean ์ด ์์ฒด๋ GDI ๊ณ์ฐ์์ ์ ์ธ.
-
Age bins โ pd.cut(..., right=False): 0-9 includes 0 and excludes 10. 80+ = [80, 120).
-
Dependencies โ all 16 sub-metric skill dependencies (see each skill's SKILL.md). LLM ํธ์ถ์ Claude CLI via subprocess โ API ํค ๋ถํ์.
References
- LYDUS ํ์ง๊ด๋ฆฌ ํ๋ก๊ทธ๋จ ํ์ฉ ๊ฐ์ด๋๋ผ์ธ (๋น๊ณต๊ฐ ๋ด๋ถ ๋ฌธ์)
- Original Python implementation: LYDUS_Bias_Detection.py (์ด์ฑ๋ฏผ ์์ฑ)