This document describes the comprehensive data quality validation framework added to AstroML, which provides extensive validation capabilities beyond the basic corruption detection.
The data quality validation framework includes:
- Temporal Consistency Validation - Timestamp ordering and future timestamp detection
- Referential Integrity Validation - Account and asset format validation, ledger sequence checks
- Business Rules Validation - Fee, amount, operation count, and balance validation
- Statistical Validation - Outlier detection, timestamp gap analysis, duplicate pattern detection
- Comprehensive Validation - Integrated validation pipeline with reporting
The main orchestrator that combines all validation types into a comprehensive validation pipeline.
Validates temporal aspects of transaction data:
- Monotonic timestamp ordering within batches
- Future timestamp detection with configurable tolerance
- Timestamp format validation
Validates referential integrity and format compliance:
- Stellar account address format validation (G + 56 alphanumeric chars)
- Asset code format validation (1-12 alphanumeric chars)
- Ledger sequence positivity validation
Validates domain-specific business rules:
- Non-negative fee validation
- Non-negative amount validation
- Operation count bounds (1-100 for Stellar)
- Balance format validation (no NaN/infinite values)
Performs statistical data quality checks:
- Amount outlier detection using IQR method
- Timestamp gap analysis
- Duplicate pattern detection
Standard result structure for individual validation checks:
@dataclass
class ValidationResult:
is_valid: bool
error_type: Optional[str] = None
message: Optional[str] = None
field: Optional[str] = None
details: Dict[str, Any] = field(default_factory=dict)Comprehensive report for batch validation:
@dataclass
class DataQualityReport:
total_records: int = 0
valid_records: int = 0
validation_results: List[ValidationResult] = field(default_factory=list)
summary: Dict[str, Any] = field(default_factory=dict)
@property
def quality_score(self) -> float:
"""Calculate data quality score as percentage of valid records."""from astroml.validation.data_quality import DataQualityValidator
validator = DataQualityValidator()
transactions = [...] # Your transaction data
report = validator.validate_batch(transactions)
print(f"Quality Score: {report.quality_score:.1f}%")
print(f"Total Records: {report.total_records}")
print(f"Error Types: {report.error_types}")from astroml.validation.data_quality import (
TemporalValidator,
ReferentialIntegrityValidator,
BusinessRulesValidator,
StatisticalValidator
)
# Temporal validation
temporal_validator = TemporalValidator()
result = temporal_validator.validate_timestamp_ordering(transactions)
# Referential integrity
ref_validator = ReferentialIntegrityValidator()
account_result = ref_validator.validate_account_format("GABC...")
# Business rules
biz_validator = BusinessRulesValidator()
fee_result = biz_validator.validate_fee_non_negative(100)
# Statistical validation
stat_validator = StatisticalValidator()
outlier_result = stat_validator.detect_amount_outliers(amounts)from astroml.validation.data_quality import (
validate_data_quality,
check_temporal_consistency,
check_referential_integrity
)
# Comprehensive validation
report = validate_data_quality(transactions)
# Specific validation types
temporal_results = check_temporal_consistency(transactions)
referential_results = check_referential_integrity(transactions)- Timestamp Ordering: Timestamps within a batch should be monotonically increasing
- Future Timestamps: No timestamps significantly in the future (configurable tolerance)
- Format Validation: Timestamps must be valid ISO 8601 format
- Account Format: Stellar accounts must match
^G[A-Z0-9]{56}$pattern - Asset Code Format: Asset codes must match
^[A-Z0-9]{1,12}$pattern - Ledger Sequence: Must be positive integers
- Fee Validation: Fees must be non-negative integers
- Amount Validation: Amounts must be non-negative numbers
- Operation Count: Must be between 1 and 100 (Stellar limit)
- Balance Format: Must be valid numbers (no NaN/infinite values)
- Amount Outliers: Uses IQR method with configurable multiplier (default 1.5)
- Timestamp Gaps: Detects gaps larger than threshold (default 60 minutes)
- Duplicate Patterns: Identifies repeated patterns across specified fields
The framework defines specific error types for different validation failures:
MISSING_TIMESTAMP: Timestamp field is missingINVALID_TIMESTAMP_FORMAT: Invalid timestamp formatTIMESTAMP_ORDER_VIOLATION: Timestamps not monotonically increasingFUTURE_TIMESTAMP: Timestamp significantly in the futureTIMESTAMP_VALIDATION_ERROR: General timestamp validation error
INVALID_ACCOUNT_TYPE: Account not a stringINVALID_ACCOUNT_FORMAT: Account doesn't match Stellar formatINVALID_ASSET_TYPE: Asset code not a stringINVALID_ASSET_FORMAT: Asset code doesn't match formatINVALID_LEDGER_SEQUENCE_TYPE: Ledger sequence not an integerINVALID_LEDGER_SEQUENCE: Ledger sequence not positive
INVALID_FEE_TYPE: Fee not numericNEGATIVE_FEE: Fee is negativeINVALID_AMOUNT_TYPE: Amount not numericNEGATIVE_AMOUNT: Amount is negativeINVALID_OPERATION_COUNT_TYPE: Operation count not integerINVALID_OPERATION_COUNT: Operation count out of boundsINVALID_BALANCE_TYPE: Balance not numericINVALID_BALANCE_VALUE: Balance is NaN or infinite
AMOUNT_OUTLIERS_DETECTED: Statistical outliers found in amountsUNUSUAL_TIMESTAMP_GAPS: Unusual gaps detected in timestampsDUPLICATE_PATTERNS_DETECTED: Repeated patterns foundOUTLIER_DETECTION_ERROR: Error during outlier detectionGAP_DETECTION_ERROR: Error during gap detectionPATTERN_DETECTION_ERROR: Error during pattern detection
validator = TemporalValidator(timestamp_field="timestamp") # Custom timestamp field
result = validator.validate_future_timestamps(transactions, tolerance_minutes=5)stat_validator = StatisticalValidator()
result = stat_validator.detect_amount_outliers(amounts, iqr_multiplier=2.0)
result = stat_validator.detect_timestamp_gaps(timestamps, gap_threshold_minutes=120)
result = stat_validator.detect_duplicate_patterns(transactions, ["amount", "source_account"])biz_validator = BusinessRulesValidator()
# The max operations per transaction is configurable (default 100 for Stellar)
biz_validator.max_operations_per_transaction = 50The data quality validation framework is designed to complement the existing validation infrastructure:
- Base Validation: Existing
validator.pyprovides corruption detection and basic schema validation - Deduplication: Existing
dedupe.pyprovides hash-based duplicate detection - Integrity Pipeline: Existing
integrity.pycombines validation and deduplication - Extended Validation: New
data_quality.pyadds comprehensive domain-specific validation
from astroml.validation import integrity, data_quality
# Use existing integrity validation
integrity_validator = integrity.IntegrityValidator(required_fields={"id", "source_account"})
integrity_result = integrity_validator.process(transactions)
# Use extended data quality validation
dq_validator = data_quality.DataQualityValidator()
dq_report = dq_validator.validate_batch(transactions)
# Combine results
print(f"Integrity: {integrity_result.is_valid}")
print(f"Data Quality Score: {dq_report.quality_score:.1f}%")The framework includes comprehensive test coverage:
tests/validation/test_extended_data_quality.py- Tests for new validation utilitiestests/validation/test_data_quality.py- Enhanced existing tests
- Unit Tests: Individual validator class tests
- Integration Tests: Comprehensive validator tests
- Fixture Tests: Tests using sample data fixtures
- Error Case Tests: Tests for invalid data scenarios
# Run extended data quality tests
python -m pytest tests/validation/test_extended_data_quality.py -v
# Run all validation tests
python -m pytest tests/validation/ -v
# Run specific test class
python -m pytest tests/validation/test_extended_data_quality.py::TestDataQualityValidator -v- Validators are designed for efficient batch processing
- Statistical validations require sufficient data for meaningful results
- Large datasets should be processed in manageable chunks
- Statistical validators store intermediate results for analysis
- Temporal validators maintain timestamp lists for ordering checks
- Pattern detection uses dictionaries for frequency counting
- Use appropriate batch sizes for large datasets
- Configure statistical thresholds based on your data characteristics
- Select relevant pattern fields for duplicate detection
- Adjust tolerance parameters for temporal validation
- Create a new validator class following the existing pattern
- Implement validation methods returning
ValidationResult - Add error types to the appropriate category
- Update
DataQualityValidatorto include the new validator - Add comprehensive tests
class CustomValidator:
def validate_custom_rule(self, data: Dict[str, Any]) -> ValidationResult:
# Implement custom validation logic
if self.check_condition(data):
return ValidationResult(is_valid=True, message="Custom rule passed")
else:
return ValidationResult(
is_valid=False,
error_type="CUSTOM_RULE_VIOLATION",
message="Custom rule failed"
)- Layered Validation: Use multiple validation layers for comprehensive coverage
- Error Handling: Always check validation results before processing
- Configuration: Adjust thresholds and parameters based on your data
- Monitoring: Track quality scores over time to detect data degradation
- Testing: Include validation tests in your CI/CD pipeline
- Import Errors: Ensure all dependencies are installed and paths are correct
- Timestamp Format: Use ISO 8601 format for timestamps
- Memory Issues: Process large datasets in smaller batches
- Performance: Optimize validation parameters for your data size
- Use detailed validation results to identify specific issues
- Enable logging to track validation progress
- Test with small, representative datasets first
- Monitor quality scores to detect trends
Planned improvements to the data quality validation framework:
- Machine Learning Validation: Add ML-based anomaly detection
- Real-time Validation: Support for streaming data validation
- Custom Rule Engine: Allow user-defined validation rules
- Performance Optimization: Parallel processing for large datasets
- Enhanced Reporting: More detailed analytics and visualization
- Integration: Better integration with data pipeline monitoring tools