TomassiniDigital commited on
Commit
2db9c75
Β·
verified Β·
1 Parent(s): fa42fd0

Update recognizers.py

Browse files
Files changed (1) hide show
  1. 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": "spacy",
13
- "models": [{"lang_code": "it", "model_name": "it_core_news_lg"}],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
- # Custom recognizers – gare d'appalto
21
  # ---------------------------------------------------------------------------
22
- _CUSTOM_RECOGNIZERS: list[PatternRecognizer] = [
23
-
24
- PatternRecognizer(
25
- supported_entity="CIG",
26
  supported_language="it",
27
- patterns=[Pattern("cig", r"\b[0-9A-Z]{10}\b", score=0.6)],
28
- context=["CIG", "codice identificativo", "gara", "appalto"],
29
- ),
30
 
31
- PatternRecognizer(
32
- supported_entity="CUP",
33
- supported_language="it",
34
- patterns=[Pattern("cup", r"\b[A-Z][0-9A-Z]{14}\b", score=0.6)],
35
- context=["CUP", "codice unico", "progetto", "investimento"],
36
- ),
37
 
38
- PatternRecognizer(
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
- PatternRecognizer(
46
- supported_entity="CODICE_FISCALE",
47
- supported_language="it",
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
- PatternRecognizer(
53
- supported_entity="PEC",
54
- supported_language="it",
55
- patterns=[Pattern("pec", r"\b[\w.\-]+@[\w.\-]*pec[\w.\-]*\.\w+\b", score=0.85)],
56
- context=["PEC", "posta certificata", "posta elettronica certificata"],
57
- ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  ]
59
 
60
- for _r in _CUSTOM_RECOGNIZERS:
61
- analyzer.registry.add_recognizer(_r)
 
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)