truthlens-ml-api / src /preprocessing.py
Param0304's picture
Deploy TruthLens ML API to Hugging Face Space
3abf967
Raw History Blame Contribute Delete
4.36 kB
"""
preprocessing.py - Text Cleaning and Schema Normalization for TruthLens AI.
This module provides preprocessing utilities for the TruthLens AI pipeline,
including text normalization, label mapping, and schema formatting across
FEVER, LIAR, and SciFact.
"""
import re
import html
from typing import Dict, List, Any, Optional
import pandas as pd
def clean_text(text: str) -> str:
"""
Cleans raw text by normalizing unicode characters, removing unescaped entities,
collapsing redundant whitespace, and handling quotes.
"""
if not isinstance(text, str):
return ""
# Unescape HTML entities (e.g., & -> &)
text = html.unescape(text)
# Replace non-breaking spaces and other special spaces
text = text.replace("\u00a0", " ").replace("\u200b", "")
# Standardize curly single/double quotes to standard quotes
text = re.sub(r"[\u2018\u2019\u201a\u201b]", "'", text)
text = re.sub(r"[\u201c\u201d\u201e\u201f]", '"', text)
# Standardize dashes
text = re.sub(r"[\u2013\u2014]", "-", text)
# Remove control characters except standard tabs/newlines
text = re.sub(r"[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]", "", text)
# Collapse multiple spaces into one
text = re.sub(r"\s+", " ", text).strip()
return text
def map_scifact_label(raw_label: str) -> str:
"""
Maps SciFact raw labels ('SUPPORT', 'CONTRADICT', '') to standardized
verification labels ('SUPPORTS', 'REFUTES', 'NOT_ENOUGH_INFO').
"""
label_norm = str(raw_label).strip().upper()
mapping = {
"SUPPORT": "SUPPORTS",
"CONTRADICT": "REFUTES",
"NOT_ENOUGH_INFO": "NOT_ENOUGH_INFO",
"NEI": "NOT_ENOUGH_INFO",
"": "NOT_ENOUGH_INFO",
}
return mapping.get(label_norm, label_norm)
def map_liar_label_to_3way(raw_label: str) -> str:
"""
Proposes a mapping of LIAR's 6-point scale into a 3-way verification schema:
- 'true', 'mostly-true' -> 'SUPPORTS'
- 'barely-true', 'false', 'pants-fire' -> 'REFUTES'
- 'half-true' -> 'NOT_ENOUGH_INFO' (ambiguous / mixed claims)
NOTE: LIAR does NOT contain evidence text in its raw tsv files.
This mapping is intended for downstream claim classification or when
retrieving external news evidence.
"""
label_norm = str(raw_label).strip().lower()
mapping = {
"true": "SUPPORTS",
"mostly-true": "SUPPORTS",
"half-true": "NOT_ENOUGH_INFO",
"barely-true": "REFUTES",
"false": "REFUTES",
"pants-fire": "REFUTES",
}
return mapping.get(label_norm, "UNKNOWN")
def map_liar_label_to_binary(raw_label: str) -> Optional[str]:
"""
Binary mapping commonly used in political fact-checking literature:
- 'true', 'mostly-true' -> 'TRUE'
- 'barely-true', 'false', 'pants-fire' -> 'FALSE'
- 'half-true' -> Ambiguous (often excluded or evaluated separately)
"""
label_norm = str(raw_label).strip().lower()
if label_norm in ("true", "mostly-true"):
return "TRUE"
elif label_norm in ("barely-true", "false", "pants-fire"):
return "FALSE"
return None
def format_to_unified_schema(
claim_id: str,
claim: str,
evidence: str,
label: str,
source: str,
domain: str,
dataset: str,
metadata: Optional[Dict[str, Any]] = None,
) -> Dict[str, Any]:
"""
Formats a fact-checking record into the unified TruthLens schema.
Schema Fields:
- claim_id (str): Unique globally qualified identifier (e.g., 'fever_75397')
- claim (str): Normalized claim statement
- evidence (str): Concatenated text of verified evidence or rationale
- label (str): Normalized 3-way label ('SUPPORTS', 'REFUTES', 'NOT_ENOUGH_INFO')
- source (str): Citation, document ID, Wikipedia title, or speaker
- domain (str): Subject domain ('encyclopedic', 'political', 'biomedical')
- dataset (str): Origin dataset ('fever', 'liar', 'scifact')
- metadata (dict): Dataset-specific attributes preserved in full
"""
return {
"claim_id": str(claim_id),
"claim": clean_text(claim),
"evidence": clean_text(evidence),
"label": label,
"source": str(source) if source else "",
"domain": domain,
"dataset": dataset,
"metadata": metadata or {},
}