Spaces:
Sleeping
Sleeping
Update recognizers.py
Browse files- recognizers.py +98 -37
recognizers.py
CHANGED
|
@@ -4,58 +4,119 @@ from presidio_analyzer.nlp_engine import NlpEngineProvider
|
|
| 4 |
from utils import ensure_spacy_model
|
| 5 |
|
| 6 |
# ---------------------------------------------------------------------------
|
| 7 |
-
# Spacy model
|
| 8 |
# ---------------------------------------------------------------------------
|
| 9 |
ensure_spacy_model("it_core_news_lg")
|
| 10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 11 |
_nlp_config = {
|
| 12 |
-
"nlp_engine_name": "
|
| 13 |
-
"models": [{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
}
|
| 15 |
|
| 16 |
_nlp_engine = NlpEngineProvider(nlp_configuration=_nlp_config).create_engine()
|
| 17 |
analyzer = AnalyzerEngine(nlp_engine=_nlp_engine, supported_languages=["it"])
|
| 18 |
|
| 19 |
# ---------------------------------------------------------------------------
|
| 20 |
-
#
|
| 21 |
# ---------------------------------------------------------------------------
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
supported_entity="CIG",
|
| 26 |
supported_language="it",
|
| 27 |
-
patterns=[Pattern(
|
| 28 |
-
context=
|
| 29 |
-
)
|
| 30 |
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
),
|
| 37 |
|
| 38 |
-
|
| 39 |
-
supported_entity="PARTITA_IVA",
|
| 40 |
-
supported_language="it",
|
| 41 |
-
patterns=[Pattern("piva", r"\b(IT)?\d{11}\b", score=0.75)],
|
| 42 |
-
context=["partita IVA", "P.IVA", "PIVA", "IVA", "impresa", "ditta"],
|
| 43 |
-
),
|
| 44 |
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
patterns=[Pattern("cf", r"\b[A-Z]{6}\d{2}[A-Z]\d{2}[A-Z]\d{3}[A-Z]\b", score=0.9)],
|
| 49 |
-
context=["codice fiscale", "C.F.", "CF"],
|
| 50 |
-
),
|
| 51 |
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
]
|
| 59 |
|
| 60 |
-
for
|
| 61 |
-
analyzer.registry.add_recognizer(
|
|
|
|
| 4 |
from utils import ensure_spacy_model
|
| 5 |
|
| 6 |
# ---------------------------------------------------------------------------
|
| 7 |
+
# Spacy model (per tokenizzazione) β l'NER vero Γ¨ sul transformer
|
| 8 |
# ---------------------------------------------------------------------------
|
| 9 |
ensure_spacy_model("it_core_news_lg")
|
| 10 |
|
| 11 |
+
# ---------------------------------------------------------------------------
|
| 12 |
+
# NLP engine IBRIDO
|
| 13 |
+
# β’ spacy β tokenizzazione, sentence splitting
|
| 14 |
+
# β’ transformer β NER (PERSON, ORG, LOC, DATE) context-aware
|
| 15 |
+
# ---------------------------------------------------------------------------
|
| 16 |
_nlp_config = {
|
| 17 |
+
"nlp_engine_name": "transformers",
|
| 18 |
+
"models": [{
|
| 19 |
+
"lang_code": "it",
|
| 20 |
+
"model_name": {
|
| 21 |
+
"spacy": "it_core_news_lg",
|
| 22 |
+
"transformers": "Babelscape/wikineural-multilingual-ner",
|
| 23 |
+
},
|
| 24 |
+
}],
|
| 25 |
+
"ner_model_configuration": {
|
| 26 |
+
"model_to_presidio_entity_mapping": {
|
| 27 |
+
"PER": "PERSON",
|
| 28 |
+
"ORG": "ORGANIZATION",
|
| 29 |
+
"LOC": "LOCATION",
|
| 30 |
+
"MISC": "NRP",
|
| 31 |
+
},
|
| 32 |
+
"low_confidence_score_multiplier": 0.4,
|
| 33 |
+
"low_score_entity_names": [],
|
| 34 |
+
},
|
| 35 |
}
|
| 36 |
|
| 37 |
_nlp_engine = NlpEngineProvider(nlp_configuration=_nlp_config).create_engine()
|
| 38 |
analyzer = AnalyzerEngine(nlp_engine=_nlp_engine, supported_languages=["it"])
|
| 39 |
|
| 40 |
# ---------------------------------------------------------------------------
|
| 41 |
+
# Helper per recognizer regex
|
| 42 |
# ---------------------------------------------------------------------------
|
| 43 |
+
def _r(entity: str, name: str, regex: str, score: float, context: list[str]) -> PatternRecognizer:
|
| 44 |
+
return PatternRecognizer(
|
| 45 |
+
supported_entity=entity,
|
|
|
|
| 46 |
supported_language="it",
|
| 47 |
+
patterns=[Pattern(name, regex, score)],
|
| 48 |
+
context=context,
|
| 49 |
+
)
|
| 50 |
|
| 51 |
+
# ---------------------------------------------------------------------------
|
| 52 |
+
# Recognizer regex β pattern deterministici italiani
|
| 53 |
+
# (NER transformer copre giΓ PERSON / ORG / LOCATION / DATE)
|
| 54 |
+
# ---------------------------------------------------------------------------
|
| 55 |
+
_RECOGNIZERS: list[PatternRecognizer] = [
|
|
|
|
| 56 |
|
| 57 |
+
# ββ Identificativi fiscali / societari ββββββββββββββββββββββββββββββββ
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 58 |
|
| 59 |
+
_r("PARTITA_IVA", "piva",
|
| 60 |
+
r"\b(IT)?\d{11}\b", 0.7,
|
| 61 |
+
["P.IVA", "partita IVA", "PIVA", "IVA", "impresa", "ditta", "stazione appaltante"]),
|
|
|
|
|
|
|
|
|
|
| 62 |
|
| 63 |
+
_r("CODICE_FISCALE", "cf_persona",
|
| 64 |
+
r"\b[A-Z]{6}\d{2}[A-Z]\d{2}[A-Z]\d{3}[A-Z]\b", 0.9,
|
| 65 |
+
["C.F.", "codice fiscale", "CF", "dipendente", "responsabile"]),
|
| 66 |
+
|
| 67 |
+
_r("CODICE_FISCALE", "cf_azienda",
|
| 68 |
+
r"\b\d{11}\b", 0.65,
|
| 69 |
+
["C.F.", "codice fiscale"]),
|
| 70 |
+
|
| 71 |
+
_r("REA", "rea",
|
| 72 |
+
r"\b[A-Z]{2}-\d{4,7}\b", 0.85,
|
| 73 |
+
["REA", "registro imprese"]),
|
| 74 |
+
|
| 75 |
+
# ββ Dati gara βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 76 |
+
|
| 77 |
+
_r("CIG", "cig",
|
| 78 |
+
r"\b[0-9A-Z]{10}\b", 0.6,
|
| 79 |
+
["CIG", "codice identificativo", "gara", "appalto"]),
|
| 80 |
+
|
| 81 |
+
_r("CUP", "cup",
|
| 82 |
+
r"\b[A-Z][0-9A-Z]{14}\b", 0.6,
|
| 83 |
+
["CUP", "codice unico", "progetto", "investimento"]),
|
| 84 |
+
|
| 85 |
+
_r("NUMERO_GARA_ANAC", "num_gara",
|
| 86 |
+
r"\b\d{7,8}\b", 0.6,
|
| 87 |
+
["ANAC", "numero gara", "gara ANAC"]),
|
| 88 |
+
|
| 89 |
+
_r("IMPORTO_GARA", "importo",
|
| 90 |
+
r"β¬\s*[\d\.]+,\d{2}", 0.75,
|
| 91 |
+
["importo", "base d'asta", "aggiudicato", "offerta", "valore"]),
|
| 92 |
+
|
| 93 |
+
# ββ Comunicazioni βββββοΏ½οΏ½οΏ½βββββββββββββββββββββββββββββββββββββββββββββββ
|
| 94 |
+
|
| 95 |
+
_r("PEC", "pec",
|
| 96 |
+
r"\b[\w.\-]+@[\w.\-]*(?:pec|postacert|legalmail|pecmail)[\w.\-]*\.\w+\b", 0.85,
|
| 97 |
+
["PEC", "posta certificata", "posta elettronica certificata"]),
|
| 98 |
+
|
| 99 |
+
# ββ Persona con titolo professionale (rinforzo NER) βββββββββββββββββββ
|
| 100 |
+
|
| 101 |
+
_r("PERSONA_CON_TITOLO", "titolo_nome",
|
| 102 |
+
r"\b(Ing\.|Dott\.ssa|Dott\.|Avv\.|Geom\.|Arch\.|Rag\.|Prof\.|Dr\.|Sig\.ra|Sig\.)\s+"
|
| 103 |
+
r"[A-ZΓ-Γ][a-zΓ -ΓΌ]+(?:\s+[A-ZΓ-Γ][a-zΓ -ΓΌ]+)+", 0.88,
|
| 104 |
+
["rappresentante", "responsabile", "referente", "legale", "direttore"]),
|
| 105 |
+
|
| 106 |
+
# ββ Dati previdenziali / assicurativi / bancari βββββββββββββββββββββββ
|
| 107 |
+
|
| 108 |
+
_r("MATRICOLA_INPS", "inps",
|
| 109 |
+
r"\b\d{10}\b", 0.65,
|
| 110 |
+
["INPS", "matricola", "previdenziale", "matricola INPS"]),
|
| 111 |
+
|
| 112 |
+
_r("POLIZZA_ASSICURATIVA", "polizza",
|
| 113 |
+
r"\b[A-Z]{2,5}-\d{4}-[A-Z]{2}-\d{6,12}\b", 0.85,
|
| 114 |
+
["polizza", "assicurativa", "N. polizza", "numero polizza"]),
|
| 115 |
+
|
| 116 |
+
_r("BIC_SWIFT", "bic",
|
| 117 |
+
r"\b[A-Z]{4}[A-Z]{2}[A-Z0-9]{2}(?:[A-Z0-9]{3})?\b", 0.8,
|
| 118 |
+
["BIC", "SWIFT", "codice banca", "codice swift"]),
|
| 119 |
]
|
| 120 |
|
| 121 |
+
for _rec in _RECOGNIZERS:
|
| 122 |
+
analyzer.registry.add_recognizer(_rec)
|