-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathtest_ingredient_matching.py
More file actions
202 lines (165 loc) · 7.04 KB
/
test_ingredient_matching.py
File metadata and controls
202 lines (165 loc) · 7.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
"""
Script per testare il matching di ingredienti con il sistema FAISS.
Questo script permette di:
1. Testare il matching di ingredienti specifici
2. Verificare come verranno interpretati gli ingredienti generati dall'LLM
3. Visualizzare i dettagli nutrizionali e dietetici degli ingredienti matchati
"""
from utils import find_best_match_faiss, normalize_name
from loaders import load_ingredient_database_with_mappings
from ingredient_synonyms import FALLBACK_MAPPING
import os
import pickle
import faiss
from sentence_transformers import SentenceTransformer
# Percorsi dei file (adatta in base alla tua struttura)
INGREDIENTS_FILE = "data/ingredients.csv"
FAISS_INDEX_FILE = "data/ingredients.index"
INDEX_TO_NAME_FILE = "data/ingredient_names.pkl"
# Carica database ingredienti e mappature
ingredient_data, normalized_to_original, original_to_normalized = load_ingredient_database_with_mappings(
INGREDIENTS_FILE)
# Funzione per caricare l'indice FAISS e il modello
def load_faiss_resources(index_path, mapping_path):
"""
Carica l'indice FAISS, il mapping dei nomi e il modello di embedding.
Args:
index_path: Percorso al file dell'indice FAISS
mapping_path: Percorso al file del mapping dei nomi
Returns:
Tupla (faiss_index, index_to_name_mapping, embedding_model)
"""
print(f"Caricamento indice FAISS da {index_path}...")
faiss_index = faiss.read_index(index_path)
print(f"Caricamento mapping nomi da {mapping_path}...")
with open(mapping_path, 'rb') as f:
index_to_name_mapping = pickle.load(f)
print(f"Caricamento modello SentenceTransformer...")
embedding_model = SentenceTransformer(
'paraphrase-multilingual-mpnet-base-v2')
return faiss_index, index_to_name_mapping, embedding_model
# Carica indice FAISS e modello
faiss_index, index_to_name_mapping, embedding_model = load_faiss_resources(
FAISS_INDEX_FILE, INDEX_TO_NAME_FILE)
def test_ingredient_matching(ingredient_name, threshold=0.60):
"""
Testa il matching di un singolo ingrediente e mostra i risultati.
Args:
ingredient_name: Nome dell'ingrediente da testare
threshold: Soglia di similarità (default: 0.60)
"""
print(f"\n--- Matching test per '{ingredient_name}' ---")
# Normalizza il nome per debug
normalized_name = normalize_name(ingredient_name)
print(f"Nome normalizzato: '{normalized_name}'")
# Cerca il miglior match
match_result = find_best_match_faiss(
llm_name=ingredient_name,
faiss_index=faiss_index,
index_to_name_mapping=index_to_name_mapping,
model=embedding_model,
normalize_func=normalize_name,
threshold=threshold
)
if match_result:
matched_db_name, match_score = match_result
print(f"Miglior match: '{matched_db_name}' (score: {match_score:.4f})")
# Verifica se il match è presente nel database
if matched_db_name in ingredient_data:
print(f"✅ Presente nel database")
info = ingredient_data[matched_db_name]
print(f" CHO per 100g: {info.cho_per_100g}")
print(
f" Vegan: {info.is_vegan}, Vegetarian: {info.is_vegetarian}")
print(
f" Gluten-Free: {info.is_gluten_free}, Lactose-Free: {info.is_lactose_free}")
else:
print(f"❌ NON presente nel database")
# Verifica normalizzazione e mapping
if normalized_name in normalized_to_original:
original_name = normalized_to_original[normalized_name]
print(f" Tramite normalizzazione → '{original_name}'")
if original_name in ingredient_data:
print(f" ✅ Trovato tramite normalizzazione")
# Verifica fallback mapping
if normalized_name in FALLBACK_MAPPING:
fallback_name = FALLBACK_MAPPING[normalized_name]
print(f" Presente nel fallback mapping → '{fallback_name}'")
if fallback_name in ingredient_data:
print(f" ✅ Trovato tramite fallback mapping")
else:
print("❌ Nessun match trovato con threshold corrente")
# Verifica fallback mapping per ingredienti senza match
if normalized_name in FALLBACK_MAPPING:
fallback_name = FALLBACK_MAPPING[normalized_name]
print(f" Presente nel fallback mapping → '{fallback_name}'")
if fallback_name in ingredient_data:
print(f" ✅ Trovato tramite fallback mapping")
# Suggerimento per test con threshold più bassa
print(" Prova a ridurre la threshold per vedere match potenziali")
def test_multiple_ingredients(ingredients_list):
"""
Testa una lista di ingredienti e mostra statistiche riassuntive.
Args:
ingredients_list: Lista di nomi di ingredienti da testare
"""
print(f"\n=== Testando {len(ingredients_list)} ingredienti ===")
matched_count = 0
for i, ing in enumerate(ingredients_list, 1):
print(f"\n[{i}/{len(ingredients_list)}]", end="")
test_ingredient_matching(ing)
# Conta quanti match abbiamo ottenuto
match_result = find_best_match_faiss(
llm_name=ing,
faiss_index=faiss_index,
index_to_name_mapping=index_to_name_mapping,
model=embedding_model,
normalize_func=normalize_name,
threshold=0.60
)
if match_result:
matched_db_name, _ = match_result
if matched_db_name in ingredient_data:
matched_count += 1
# Statistiche finali
print(f"\n=== Risultati ===")
print(f"Ingredienti testati: {len(ingredients_list)}")
print(
f"Match trovati: {matched_count} ({matched_count/len(ingredients_list)*100:.1f}%)")
print(f"Match mancanti: {len(ingredients_list) - matched_count}")
# Test con alcuni ingredienti predefiniti
ingredienti_test = [
"Farina",
"Farina integrale",
"Patate",
"Patate dolci",
"Zucchine",
"Pomodori ciliegini",
"Olio di oliva",
"Ceci in scatola (sciacquati e sgocciolati)"
]
# Esegui i test
print("\n\n======== BATCH TEST =========")
test_multiple_ingredients(ingredienti_test)
# Modalità interattiva
print("\n\n======== MODALITÀ INTERATTIVA =========")
print("Inserisci un ingrediente alla volta per testare il matching")
print("(inserisci 'q' per uscire, 'batch' per testare una lista di ingredienti)")
while True:
test_input = input(
"\nInserisci un ingrediente da testare (o 'q' per uscire): ")
if test_input.lower() == 'q':
break
elif test_input.lower() == 'batch':
# Permette di testare una lista di ingredienti
print("Inserisci gli ingredienti uno per riga. Linea vuota per terminare:")
batch_ingredients = []
while True:
line = input()
if not line.strip():
break
batch_ingredients.append(line.strip())
if batch_ingredients:
test_multiple_ingredients(batch_ingredients)
else:
test_ingredient_matching(test_input)