보고서나 모델이 사용하기 전에 흔한 데이터 문제를 찾고 설명하고 수정합니다. — Claude Skill
Claude Code용 Claude 스킬 · 제공: masterkram · 실행: /data-quality (Claude 내)·업데이트: 2026년 6월 14일·vmain@8b32590
누락값, 중복, 이상치, 잘못된 값, 규칙 위반을 프로파일링하고 수리가 실제로 데이터를 개선했는지 검증합니다.
- 누락값, 중복 레코드, 이상치, 잘못된 도메인, 깨진 제약조건을 찾습니다.
- 문제가 무해한지, 정리가 필요한지, 보고를 막아야 하는지 설명합니다.
- 의심스러운 행을 무작정 삭제하지 않고 수리 전략을 제안합니다.
- 정리 후 검사를 다시 실행해 무엇이 개선됐는지 보여줍니다.
분석가가 데이터셋을 눈으로 훑고 명백히 나쁜 행을 삭제한 뒤 downstream 분석이 여전히 유효하길 기대합니다.
/data-quality를 실행해 품질 규칙을 정의하고, 결함을 정량화하고, 체계적으로 수리하고, 개선을 검증합니다.
대상
기능
보고서, 마이그레이션, 모델에 충분히 신뢰할 수 있는 데이터인지 결정합니다.
중복 고객, 계정, 제품, 거래를 찾아 어떻게 병합할지 선택합니다.
필수 필드, 허용 값, 고유 키, 테이블 간 관계를 확인합니다.
작동 방식
데이터셋, 비즈니스 규칙, 데이터가 중요한 이유를 정의합니다.
완전성, 유일성, 유효성, 일관성, 이상치를 프로파일링합니다.
누락값, 중복, 문자열, 제약조건에 대한 수리 전략을 선택합니다.
정리된 데이터를 원래 규칙에 맞춰 검증하고 남은 위험을 문서화합니다.
입력 옵션
CSV, 스프레드시트, SQL 추출, dataframe, 스키마 또는 샘플 행입니다.
예시
데이터셋: customer_내보내기.csv, 52,000 rows. 용도: 다음 주 새 CRM으로 계정을 마이그레이션합니다. 규칙: - 연락처에는 email이 필수입니다, - account_id는 고유해야 합니다, - country는 유효한 ISO 국가여야 합니다, - annual_revenue는 음수가 아니어야 합니다. 알려진 우려: 중복 회사명과 누락 이메일. 필요: 마이그레이션이 안전한지, 무엇을 먼저 고칠지 결정합니다.
이 스킬은 이를 일반 정리가 아니라 마이그레이션 준비 상태로 다룹니다. CRM 마이그레이션을 막거나 오염시킬 문제에 집중합니다.
이메일이 누락된 행 1,148개, 중복 account_id 값 392개, 잘못된 country 값 86개, 음수 매출 행 14개가 있습니다.
중복 account_id는 잘못된 계정을 병합할 수 있어 차단 이슈입니다. 누락 이메일은 계정 레코드에는 허용될 수 있지만 연락처 레코드에는 허용되지 않을 수 있습니다.
중복 account_id를 먼저 고치고, 잘못된 country를 두 번째로 매핑하고, 누락 이메일은 정보 보강 대상으로 표시하고, 음수 매출은 삭제하지 말고 조사합니다.
같은 검사를 다시 실행하고 전후 카운트를 보여줘 마이그레이션 담당자가 승인할 수 있게 합니다.
개선되는 지표
지원 도구
데이터 품질을(를) 사용해 보시겠어요?
시작 방법을 선택하세요.
이 스킬을 컴퓨터에 로컬로 설치하고 실행합니다.
컴퓨터에서 터미널을 열고 이 명령을 붙여넣으세요:
이 명령은 스킬과 모든 파일을 컴퓨터에 다운로드합니다:
모든 프로젝트에서 사용하려면 끝에 -g를 추가하세요.
Claude Code를 시작한 다음 명령을 입력하세요:
데이터 품질 스킬
데이터 품질 문제를 체계적으로 진단하고 수정하는 접근 방식입니다.
데이터 품질 프로세스
정의 및 식별 → 탐지 및 정량화 → 정리 및 수정 → 측정 및 검증
- 정의: 데이터 맥락, 비즈니스 규칙, 품질 요구사항을 이해합니다
- 탐지: 데이터를 프로파일링하고 결함(결측, 중복, 이상치, 위반)을 찾습니다
- 정리: 적절한 복구 전략을 적용합니다
- 측정: 수정 결과를 검증하고 개선 폭을 정량화합니다
빠른 참조
| 문제 | 스크립트 | 핵심 함수 |
|---|---|---|
| 데이터 개요 | data_profiling.py | profile_dataframe(df) |
| 품질 이슈 찾기 | data_profiling.py | detect_glitches(df) |
| 결측값 | missing_data.py | analyze_missing(df) |
| 대치 | missing_data.py | impute_mean/median/regression() |
| 중복 | duplicate_detection.py | find_duplicates(df, cols) |
| 중복 제거 | duplicate_detection.py | deduplicate(df, cols) |
| 이상치 | anomaly_detection.py | detect_anomalies(df) |
| 제약 조건 확인 | constraint_checking.py | validate_constraints(df, rules) |
| 문자열 매칭 | similarity_metrics.py | jaro_winkler_similarity() |
작업 흐름
1단계: 데이터 프로파일링
from scripts.data_profiling import profile_dataframe, detect_glitches, generate_quality_report
# 빠른 개요
print(generate_quality_report(df))
# 상세 프로파일
profile = profile_dataframe(df)
# 이슈 찾기
glitches = detect_glitches(df)
2단계: 특정 이슈 분석
결측 데이터:
from scripts.missing_data import analyze_missing, test_mcar
analysis = analyze_missing(df)
# 행 삭제가 안전한지 확인
mcar_test = test_mcar(df, 'column_with_missing', ['other_cols'])
중복:
from scripts.duplicate_detection import find_duplicates, cluster_duplicates
matches = find_duplicates(df, ['name', 'email'], threshold=0.85)
clusters = cluster_duplicates(matches)
이상치:
from scripts.anomaly_detection import detect_anomalies, iqr_outliers
# 여러 열 요약
anomalies = detect_anomalies(df, method='iqr')
# 단일 열 상세
result = iqr_outliers(df, 'price', multiplier=1.5)
제약 조건:
from scripts.constraint_checking import validate_constraints
constraints = [
{'type': 'unique', 'columns': ['id']},
{'type': 'not_null', 'columns': ['name', 'email']},
{'type': 'fd', 'determinant': ['id'], 'dependent': ['name']},
{'type': 'domain', 'column': 'age', 'min_value': 0, 'max_value': 150},
]
results = validate_constraints(df, constraints)
3단계: 데이터 정리
결측 처리:
from scripts.missing_data import impute_median, impute_regression, listwise_deletion
# 단순 방식: 숫자형에는 중앙값
df_clean = impute_median(df, 'age')
# 더 나은 방식: 회귀 기반
df_clean = impute_regression(df, 'income', ['age', 'education'])
# MCAR이 확인된 경우
df_clean = listwise_deletion(df)
중복 제거:
from scripts.duplicate_detection import deduplicate
df_clean, summary = deduplicate(
df,
columns=['name', 'email', 'address'],
threshold=0.8,
merge_strategy='most_complete'
)
print(f"Reduced from {summary['original_rows']} to {summary['final_rows']} rows")
이상치 처리:
# 극단값 상한/하한 처리
q01, q99 = df['col'].quantile([0.01, 0.99])
df['col'] = df['col'].clip(q01, q99)
# 또는 제거
df_clean = df[~detect_anomalies(df)['col']['outlier_indices']]
4단계: 검증
정리된 데이터에서 프로파일링과 제약 조건 검사를 다시 실행해 개선 여부를 확인합니다.
참조
더 깊이 이해하려면:
- references/dimensions.md: 데이터 품질 차원(정확성, 완전성 등)
- references/glitch_taxonomy.md: 데이터 결함 유형과 탐지 접근 방식
- references/repair_strategies.md: 상세 복구 및 정리 전략
핵심 개념
데이터 품질 = 사용 목적에 적합함
- 결함이 없음
- 작업에 필요한 특성을 갖춤
- 올바른 정보가 올바른 위치에 올바른 시점에 있음
결측 데이터 메커니즘:
- MCAR: 완전 무작위 결측(삭제해도 안전)
- MAR: 무작위 결측(대치가 작동할 수 있음)
- MNAR: 비무작위 결측(가장 문제가 큼)
제약 조건:
- 함수 종속성:
X → Y는 X가 Y를 고유하게 결정한다는 뜻입니다 - 참조 무결성: 외래 키가 유효한 기본 키를 참조합니다
- 도메인 제약 조건: 값이 허용된 집합/범위 안에 있습니다
엔터티 해소:
- 블로킹은 O(n²)을 O(n·window)로 줄입니다
- 유사도 지표: Jaro-Winkler(이름), Levenshtein(오타), Jaccard(집합)
- 전이 폐쇄로 클러스터링하고 전략에 따라 병합합니다
유사도 지표 비교
| 지표 | 가장 적합한 경우 | 예시 |
|---|---|---|
| Jaro-Winkler | 이름, 짧은 문자열 | "Robert" vs "Rupert" |
| Levenshtein | 오타, 편집 거리 | "recieve" vs "receive" |
| Jaccard | 토큰/단어 비교 | "John Doe" vs "Doe, John" |
| Q-gram | 퍼지 부분 문자열 매칭 | 부분 일치 |
참조 문서
데이터 품질 차원
데이터 품질은 "사용 목적에 적합함"으로 결정됩니다. 즉 주어진 맥락의 요구사항을 데이터가 충족할 수 있는 능력입니다.
핵심 차원
정확성
데이터가 실제 세계의 엔터티나 이벤트를 올바르게 나타냅니다.
측정:
- 권위 있는 출처(gold standard)와 비교
- 전문가 검토 샘플링
- 교차 참조 검증
흔한 이슈:
- 오타와 전사 오류
- 오래된 정보
- 측정 오류
완전성
필수 데이터 값이 모두 존재합니다.
수준:
- 스키마 완전성: 예상 attribute가 모두 존재
- 열 완전성: 열별 non-null 값 비율
- 모집단 완전성: 예상 record가 모두 존재
측정:
completeness = (non_null_count / total_count) * 100
일관성
데이터 값이 데이터셋 또는 시스템 간에 서로 모순되지 않습니다.
유형:
- record 내부: 같은 record 안의 값이 일관됨(나이가 생년월일과 일치)
- record 간: record 사이의 값이 일관됨(중복 ID 없음)
- 시스템 간: 같은 entity가 다른 database에서도 일관된 값을 가짐
측정:
- 제약 조건 위반 수
- 교차 참조 불일치
적시성
의도한 사용에 충분히 최신 상태입니다.
측면:
- 최신성: 데이터가 마지막으로 업데이트된 시점
- 변동성: 데이터가 얼마나 자주 변하는지
- 지연: 실제 세계 변화와 데이터 업데이트 사이의 지연
측정:
timeliness_score = 1 - (current_time - last_update) / max_acceptable_age
유효성
데이터가 정의된 format, type, range를 따릅니다.
검사:
- 데이터 type 검증
- format 검증(날짜, 이메일, 전화번호)
- range/domain 검증
- 패턴 매칭
고유성
의도치 않은 중복이 없습니다.
수준:
- primary key 고유성
- natural key 고유성
- entity 수준 deduplication
확장 차원
관련성
데이터가 작업에 적용 가능하고 유용합니다.
해석 가능성
데이터 의미가 명확하고 모호하지 않습니다(문서화가 잘 되어 있음).
접근성
권한 있는 사용자가 데이터를 쉽게 얻을 수 있습니다.
신뢰성
데이터가 신뢰할 수 있는 출처에서 나옵니다.
비즈니스 맥락
사용 목적에 따라 품질 우선순위가 달라집니다.
| 사용 사례 | 우선 차원 |
|---|---|
| 재무 보고 | 정확성, 완전성, 일관성 |
| 실시간 분석 | 적시성, 가용성 |
| 고객 커뮤니케이션 | 정확성, 완전성 |
| ML 모델 학습 | 완전성, 일관성, 유효성 |
| 규제 준수 | 정확성, 완전성, 감사 가능성 |
전체 품질 측정
가중 composite score:
quality_score = sum(weight[dim] * score[dim] for dim in dimensions) / sum(weights)
품질 threshold:
- Critical: < 70% - 즉시 조치 필요
- Warning: 70-90% - 개선 필요
- Acceptable: > 90% - degradation 모니터링
데이터 결함 분류
데이터 결함은 데이터 품질을 손상시키는 defect입니다. 결함 유형을 이해하면 탐지와 복구 전략을 정할 수 있습니다.
결함 카테고리
1. 결측 데이터
값 수준: 개별 cell이 NULL/empty입니다
- 탐지 쉬움:
df.isnull().sum()
record 수준: 예상 모집단에서 전체 row가 빠져 있습니다
- 탐지 어려움: 외부 reference 필요
attribute 수준: 예상 column이 schema에서 빠져 있습니다
- 중간 난이도: schema documentation과 비교
결측 데이터 메커니즘:
| 메커니즘 | 설명 | 의미 |
|---|---|---|
| MCAR | 완전 무작위 결측 - 상관관계 없음 | row 삭제가 안전 |
| MAR | 무작위 결측 - 관측 데이터와 상관 | 대치가 작동할 수 있음 |
| MNAR | 비무작위 결측 - missing value 자체와 상관 | 가장 문제가 큼 |
2. 불일치/오류 데이터
구문 오류:
- 오타: "John" 대신 "Jhon"
- format: 일관되지 않은 날짜 format, 전화번호 format
- encoding: character encoding 이슈
의미 오류:
- 잘못된 값: age = 250
- 모순: birth_date > current_date
- 제약 조건 위반: 중복 primary key
탐지:
- 제약 조건 확인(FDs, 참조 무결성)
- domain validation
- 패턴 분석
3. 이상 현상과 이상치
점 이상: 정상 범위에서 멀리 떨어진 단일 데이터 포인트
- Age = -5 또는 Age = 200
맥락 이상: 특정 맥락에서 비정상
- Temperature = 90°F는 여름에는 정상, 겨울에는 이상
집합 이상: 관련 포인트 그룹이 함께 이상
- 모든 sensor reading이 갑자기 spike
탐지 방법:
- 통계 기반: z-score, IQR, modified z-score
- ML 기반: isolation forest, autoencoders, k-NN
4. 의미적 중복
동일한 실제 entity를 서로 다른 표현으로 가리키는 record:
Row 1: "John Smith", "123 Main St", "NYC"
Row 2: "J. Smith", "123 Main Street", "New York City"
탐지:
- 비교 공간을 줄이는 blocking
- 유사도 지표를 이용한 fuzzy matching
- 전이 폐쇄를 통한 clustering
5. 문서화되지 않은 데이터
충분한 metadata가 없는 데이터:
- column 의미 불명
- data dictionary 누락
- 측정 단위 불명확
- lineage/provenance 정보 없음
증상:
- "col1", "field_a", "x" 같은 컬럼 이름
- 허용 값에 대한 문서 없음
- 모호한 의미
결함 복합체
실제 데이터에는 복합 결함 패턴이 자주 있습니다.
다중 유형 결함
하나의 값이 여러 결함 유형을 동시에 가집니다.
- 값이 이상치이면서 제약조건과도 불일치
동반 결함
같은 레코드가 여러 컬럼에서 결함을 가집니다.
- 이름 결측, 잘못된 이메일, 나이 이상치
다발 결함
같은 결함 유형이 많은 레코드에 나타납니다.
- 1000개 레코드에서 같은 필드가 모두 결측
탐지 복잡성 요인
관련성
심각도는 도메인에 따라 달라집니다.
- 이메일 결측: 마케팅에는 중요, 배송에는 무관
모호성
유효/무효 경계가 불명확합니다.
- 나이 120은 오류인가, 드문 정상값인가?
복잡한 의존성
한 결함이 다른 결함을 가릴 수 있습니다.
- 결측값은 제약조건 위반이 되었을 값을 숨김
동적 특성
결함 유형은 진화합니다.
- 새 데이터 소스가 새 오류 패턴을 만듦
결함 정량화
값별 scoring
glitch_signature = [has_missing, has_outlier, has_format_error, ...]
glitch_score = sum(weight[i] * signature[i] for i in range(len(signature)))
전체 scoring
total_glitch_score = sum(all_value_scores) / total_values
탐지 우선순위
- 넓게 시작: 전체 dataset을 profile(profiling script)
- 패턴 식별: 흔한 결함 유형 찾기
- 우선순위화: impact와 frequency가 높은 이슈에 집중
- Deep dive: 우선 결함의 root cause 조사
데이터 복구 전략
데이터 품질 이슈 복구에는 데이터 손실, 정확성, 계산 비용 사이의 trade-off가 있습니다.
기본 개념: 최소 복구
최소 복구 = 제약 조건 위반을 제거하는 가장 작은 변경입니다.
핵심 인사이트: 제약 조건이 위반되면 어떤 값이 잘못되었는지 모호합니다. 최소 복구는 원본 데이터를 최대한 보존합니다.
결측 데이터 전략
삭제 방법
Listwise deletion: 값이 하나라도 결측이면 전체 row 제거
df_clean = df.dropna()
- 장점: 단순하고 남은 데이터의 관계를 보존
- 단점: 많은 데이터를 잃을 수 있으며 MCAR에서만 유효
- 사용 시점: 결측 < 5%, MCAR 확인
Pairwise deletion: 각 계산에 사용 가능한 데이터만 사용
df.dropna(subset=['col1', 'col2']) # Only for this analysis
- 장점: 더 많은 데이터 보존
- 단점: 분석마다 N이 달라짐
- 사용 시점: 분석별 완전성이 필요할 때
Attribute deletion: 결측이 너무 많은 column 제거
df.drop(columns=[col for col in df if df[col].isnull().mean() > 0.5])
- 사용 시점: column 결측 > 50%, critical하지 않음
대치 방법
단순 대치:
| 방법 | 공식 | 가장 적합한 경우 |
|---|---|---|
| Mean | df[col].fillna(df[col].mean()) | 숫자형, 정규분포 |
| Median | df[col].fillna(df[col].median()) | 숫자형, skewed/outliers |
| Mode | df[col].fillna(df[col].mode()[0]) | 범주형 |
| Constant | df[col].fillna(value) | domain-specific default |
| Forward fill | df[col].ffill() | 시계열 |
주의:
- mean/median은 variance를 과소추정합니다
- 변수 간 상관을 약화합니다
- MCAR이 아니면 bias를 만들 수 있습니다
모델 기반 대치:
# Regression imputation
from scripts.missing_data import impute_regression
df_imputed = impute_regression(df, target='income', predictors=['age', 'education'])
- 관계를 더 잘 보존합니다
- noise를 추가하지 않으면 여전히 variance를 과소추정합니다
Multiple imputation:
- random variation을 넣어 여러 번 대치
- 각 imputed dataset 분석
- imputation uncertainty를 고려해 결과 pooling
Indicator Method
결측 여부 binary flag 추가(ML에 유용):
df['col_missing'] = df['col'].isnull().astype(int)
df['col'] = df['col'].fillna(df['col'].median())
중복 복구 전략
Record Selection
Survivor strategy: 가장 완전한 record 유지
from scripts.duplicate_detection import merge_records
survivor = merge_records(df, cluster, strategy='most_complete')
First/Last: 시간상 첫 record 또는 최신 record 유지
- 사용 시점: 시간적 우선순위가 중요할 때
Record Fusion
Attribute-based: composite record 생성
merged = merge_records(df, cluster, strategy='combine')
# Takes first non-null value for each attribute
데이터 type별 aggregation rules:
- 숫자형: max, min, avg, sum(semantics에 따라)
- 문자열: longest, most recent, most frequent
- 날짜: earliest, latest
병합 후 작업
관련 table의 foreign key 업데이트:
# After merging records 2,3,4 into record 1
other_table['fk_col'] = other_table['fk_col'].replace({2: 1, 3: 1, 4: 1})
제약 조건 위반 복구
삭제 vs 수정
Tuple deletion: 위반 row 전체 제거
- 단순하지만 정보를 잃음
- dependent table로 cascade될 수 있음
Value modification: 제약 조건을 만족하도록 값 업데이트
- 더 많은 데이터 보존
- 다른 오류를 도입할 위험
Consistent Query Answering(CQA)
데이터를 복구하는 대신 모든 가능한 minimal repair에서 일관된 query result를 반환합니다.
-- Original: SELECT * FROM Students
-- CQA version: Only return students with no FD conflicts
SELECT * FROM Students s1
WHERE NOT EXISTS (
SELECT * FROM Students s2
WHERE s1.id = s2.id AND s1.name != s2.name
)
Active Integrity Constraints
제약 조건과 함께 repair action 지정:
IF violation(student_id -> name) THEN keep_most_recent
IF violation(age BETWEEN 0 AND 150) THEN set_null
이상 현상/이상치 복구
Correction strategies
Capping/Winsorization: 극단값을 boundary value로 대체
lower, upper = df['col'].quantile([0.01, 0.99])
df['col'] = df['col'].clip(lower, upper)
삭제: outlier row 제거
- outlier가 systematic이면 bias 위험
대치: 결측처럼 처리하고 대치
df.loc[outlier_mask, 'col'] = np.nan
df = impute_median(df, 'col')
조사: 진짜 extreme인지 오류인지 확인
- outlier가 실제이고 중요할 때도 있습니다!
복구 의사결정 프레임워크
1. 영향 평가
- 이 데이터가 얼마나 critical한가?
- 잘못된 복구 vs 복구 없음의 비용은 무엇인가?
2. 원인 이해
- Systematic error → source에서 수정
- Random error → statistical repair
3. 전략 선택
- Low risk: aggressive cleaning
- High risk: conservative (CQA, flagging)
4. 검증
- 복구가 새 이슈를 만들지 않았는지 확인
- 전후 분포 비교
- business logic이 여전히 성립하는지 확인
5. 문서화
- 무엇을 왜 바꿨는지 기록
- audit trail 활성화
모범 사례
- 원본 데이터를 절대 파괴하지 마세요 - backup 유지
- 모든 transformation을 문서화하세요 - 재현 가능성
- 예방을 우선하세요 - downstream이 아니라 data entry를 수정
- 복구를 검증하세요 - 의도치 않은 결과 확인
- 맥락을 고려하세요 - 복구 전략은 use case에 따라 달라집니다
name: data-quality description: 데이터셋의 데이터 품질 문제를 진단하고 수정합니다. 더러운 데이터 처리, 중복 탐지, 결측값 처리, 이상치/이상 현상 탐지, 제약 조건 검증(함수 종속성, 참조 무결성), 데이터셋 프로파일링, 분석 또는 ML을 위한 데이터 정리에 사용합니다. 정의, 탐지, 정리, 측정까지 데이터 품질 전체 수명주기를 다룹니다.
데이터 품질 스킬
데이터 품질 문제를 체계적으로 진단하고 수정하는 접근 방식입니다.
데이터 품질 프로세스
정의 및 식별 → 탐지 및 정량화 → 정리 및 수정 → 측정 및 검증
- 정의: 데이터 맥락, 비즈니스 규칙, 품질 요구사항을 이해합니다
- 탐지: 데이터를 프로파일링하고 결함(결측, 중복, 이상치, 위반)을 찾습니다
- 정리: 적절한 복구 전략을 적용합니다
- 측정: 수정 결과를 검증하고 개선 폭을 정량화합니다
빠른 참조
| 문제 | 스크립트 | 핵심 함수 |
|---|---|---|
| 데이터 개요 | data_profiling.py | profile_dataframe(df) |
| 품질 이슈 찾기 | data_profiling.py | detect_glitches(df) |
| 결측값 | missing_data.py | analyze_missing(df) |
| 대치 | missing_data.py | impute_mean/median/regression() |
| 중복 | duplicate_detection.py | find_duplicates(df, cols) |
| 중복 제거 | duplicate_detection.py | deduplicate(df, cols) |
| 이상치 | anomaly_detection.py | detect_anomalies(df) |
| 제약 조건 확인 | constraint_checking.py | validate_constraints(df, rules) |
| 문자열 매칭 | similarity_metrics.py | jaro_winkler_similarity() |
작업 흐름
1단계: 데이터 프로파일링
from scripts.data_profiling import profile_dataframe, detect_glitches, generate_quality_report
# 빠른 개요
print(generate_quality_report(df))
# 상세 프로파일
profile = profile_dataframe(df)
# 이슈 찾기
glitches = detect_glitches(df)
2단계: 특정 이슈 분석
결측 데이터:
from scripts.missing_data import analyze_missing, test_mcar
analysis = analyze_missing(df)
# 행 삭제가 안전한지 확인
mcar_test = test_mcar(df, 'column_with_missing', ['other_cols'])
중복:
from scripts.duplicate_detection import find_duplicates, cluster_duplicates
matches = find_duplicates(df, ['name', 'email'], threshold=0.85)
clusters = cluster_duplicates(matches)
이상치:
from scripts.anomaly_detection import detect_anomalies, iqr_outliers
# 여러 열 요약
anomalies = detect_anomalies(df, method='iqr')
# 단일 열 상세
result = iqr_outliers(df, 'price', multiplier=1.5)
제약 조건:
from scripts.constraint_checking import validate_constraints
constraints = [
{'type': 'unique', 'columns': ['id']},
{'type': 'not_null', 'columns': ['name', 'email']},
{'type': 'fd', 'determinant': ['id'], 'dependent': ['name']},
{'type': 'domain', 'column': 'age', 'min_value': 0, 'max_value': 150},
]
results = validate_constraints(df, constraints)
3단계: 데이터 정리
결측 처리:
from scripts.missing_data import impute_median, impute_regression, listwise_deletion
# 단순 방식: 숫자형에는 중앙값
df_clean = impute_median(df, 'age')
# 더 나은 방식: 회귀 기반
df_clean = impute_regression(df, 'income', ['age', 'education'])
# MCAR이 확인된 경우
df_clean = listwise_deletion(df)
중복 제거:
from scripts.duplicate_detection import deduplicate
df_clean, summary = deduplicate(
df,
columns=['name', 'email', 'address'],
threshold=0.8,
merge_strategy='most_complete'
)
print(f"Reduced from {summary['original_rows']} to {summary['final_rows']} rows")
이상치 처리:
# 극단값 상한/하한 처리
q01, q99 = df['col'].quantile([0.01, 0.99])
df['col'] = df['col'].clip(q01, q99)
# 또는 제거
df_clean = df[~detect_anomalies(df)['col']['outlier_indices']]
4단계: 검증
정리된 데이터에서 프로파일링과 제약 조건 검사를 다시 실행해 개선 여부를 확인합니다.
참조
더 깊이 이해하려면:
- references/dimensions.md: 데이터 품질 차원(정확성, 완전성 등)
- references/glitch_taxonomy.md: 데이터 결함 유형과 탐지 접근 방식
- references/repair_strategies.md: 상세 복구 및 정리 전략
핵심 개념
데이터 품질 = 사용 목적에 적합함
- 결함이 없음
- 작업에 필요한 특성을 갖춤
- 올바른 정보가 올바른 위치에 올바른 시점에 있음
결측 데이터 메커니즘:
- MCAR: 완전 무작위 결측(삭제해도 안전)
- MAR: 무작위 결측(대치가 작동할 수 있음)
- MNAR: 비무작위 결측(가장 문제가 큼)
제약 조건:
- 함수 종속성:
X → Y는 X가 Y를 고유하게 결정한다는 뜻입니다 - 참조 무결성: 외래 키가 유효한 기본 키를 참조합니다
- 도메인 제약 조건: 값이 허용된 집합/범위 안에 있습니다
엔터티 해소:
- 블로킹은 O(n²)을 O(n·window)로 줄입니다
- 유사도 지표: Jaro-Winkler(이름), Levenshtein(오타), Jaccard(집합)
- 전이 폐쇄로 클러스터링하고 전략에 따라 병합합니다
유사도 지표 비교
| 지표 | 가장 적합한 경우 | 예시 |
|---|---|---|
| Jaro-Winkler | 이름, 짧은 문자열 | "Robert" vs "Rupert" |
| Levenshtein | 오타, 편집 거리 | "recieve" vs "receive" |
| Jaccard | 토큰/단어 비교 | "John Doe" vs "Doe, John" |
| Q-gram | 퍼지 부분 문자열 매칭 | 부분 일치 |