File size: 6,064 Bytes
bb489f8
 
 
 
96e1b12
bb489f8
 
 
 
 
 
 
 
 
 
 
 
96e1b12
bb489f8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96e1b12
 
 
 
bb489f8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96e1b12
bb489f8
 
 
 
 
 
96e1b12
bb489f8
 
 
 
 
 
 
96e1b12
bb489f8
 
 
 
 
 
 
 
 
 
 
 
 
 
96e1b12
 
bb489f8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96e1b12
bb489f8
 
 
 
 
96e1b12
 
 
 
 
 
 
bb489f8
 
 
 
 
 
 
96e1b12
 
bb489f8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# Phase 3 β€” Product Domain + Taxonomy + Product Grouping

## Compliments Reference DB Pipeline

**Version:** 1.1.0
**Date:** 2026-07-30
**Status:** PASS

---

## Input

| Property | Value |
|----------|-------|
| Source | `phase2/outputs/phase2_output.parquet` |
| HF Repo | `saraNour/compliments-reference-phase2` |
| Row Count | 4,440 |
| Column Count | 38 |

---

## What Phase 3 Does

### A. Food / Non-Food Classification

Deterministic keyword-based rules. Creates `product_domain` column with values: `food`, `non_food`, `unknown`.

- **Food:** Dairy, meat, seafood, bakery, beverages, frozen, produce, pantry, snacks, confectionery
- **Non-food:** Pet food, medications, personal care, household cleaning, kitchenware, health remedies
- **Unknown:** Products that don't match any rule

### B. Taxonomy Classification

Deterministic keyword-based taxonomy. Classification metadata only β€” NOT used as grouping key.

19 categories: DAIRY, MEAT_SEAFOOD, BEVERAGES, BAKERY, FROZEN, BREAKFAST, PASTA_RICE, CANNED_GOODS, CONDIMENTS_SAUCES, SNACKS, CONFECTIONERY, PRODUCE, PERSONAL_CARE, HOUSEHOLD_CLEANING, HEALTH_REMEDIES, PET_FOOD, HOUSEHOLD_SUPPLIES, BABY_CARE, GENERAL_GROCERY

### C. Product Grouping

Identity-based deterministic grouping:

```
group_key = identity_hash + product_domain + normalized_core_title
```

- `identity_hash`: 14-field hash from Phase 2 (9 flags + fat + product_line + flavour + formulation)
- `product_domain`: food/non_food/unknown β€” **structurally prevents food/non-food mixing**
- `normalized_core_title`: Core title with generic packaging words removed, tokens sorted

### D. Ambiguous Case Detection

Groups with >1 product are inspected for:
- Multiple core_titles
- Multiple flavours
- Multiple formulations
- Multiple fat levels
- Multiple product lines

### E. Rule-Based Resolution

All grouping is deterministic. No LLM was required.

---

## Output Files

### A. reference_product_catalog.csv (Group-Level)

| Column | Type | Description |
|--------|------|-------------|
| group_id | str | Deterministic UUID |
| group_name | str | Most frequent core_title |
| brand | str | Normalized brand |
| product_domain | str | food/non_food/unknown |
| taxonomy | str | Taxonomy category |
| identity_hash | str | 14-field identity hash |
| product_count | int | Products in group |
| unique_upcs | int | Unique UPCs in group |

### B. product_group_mapping.csv (Product-Level)

| Column | Type | Description |
|--------|------|-------------|
| upc | str | Barcode |
| external_id | str | Voila ID |
| group_id | str | Group UUID |
| group_name | str | Core title |
| core_title | str | Core title |
| original_title | str | Raw title |
| brand | str | Normalized brand |
| size | str | Raw size |
| variant_attributes | str | Parsed size JSON |
| identity_hash | str | Identity hash |
| product_domain | str | Food/non-food |
| taxonomy | str | Taxonomy |
| product_line | str | Product line |
| source | str | Data source |
| source_url | str | Source URL |

### C. ambiguous_cases.csv

Groups with potential ambiguity and the reason.

### D. unknown_products.csv

Products classified as "unknown" domain (1,243 products).

---

## Deterministic Grouping Rules

| # | Rule | Implementation |
|---|------|----------------|
| 1 | Identity hash captures 14 fields | `build_identity_hash()` in Phase 2 |
| 2 | Product domain is part of grouping key | `build_group_key()` in Phase 3 |
| 3 | Core title normalized (generic words removed, sorted) | `normalize_title_for_grouping()` |
| 4 | Same normalized title + same identity = same group | Group key construction |
| 5 | Different identity = different group | Identity hash is first component |
| 6 | Food vs non_food = always different group | Product domain is second component |

---

## Food/Non-Food Rules

100+ deterministic regex rules based on product title keywords.

- Pet food β†’ non_food
- Medications (ibuprofen, acetaminophen, etc.) β†’ non_food
- Personal care (tampons, shampoo, etc.) β†’ non_food
- Household (detergent, garbage bags, etc.) β†’ non_food
- Kitchenware (light bulbs, pans, etc.) β†’ non_food
- Everything else matching food keywords β†’ food
- No match β†’ unknown

---

## Regression Tests β€” ALL PASS (12/12)

| Test | Result |
|------|--------|
| PB smooth sizes same group | PASS |
| PB crunchy sizes same group | PASS |
| PB organic smooth different | PASS |
| PB organic crunchy different | PASS |
| PB naturally simple different | PASS |
| PB light different | PASS |
| PB honey different | PASS |
| PB cookies different | PASS |
| PB ice cream different | PASS |
| PB dog treats different | PASS |
| CC 1% vs 2% different | PASS |
| Cottage cheese sizes same | PASS |

---

## Validation Results

| Check | Result |
|-------|--------|
| Row count preserved | PASS |
| No duplicate mappings | PASS |
| No food/non-food mixing | PASS |
| No brand conflicts | PASS |
| Identity consistent | PASS |
| Taxonomy populated | PASS |
| No empty group names | PASS |
| One group per product | PASS |
| No orphans | PASS |
| **Overall** | **PASS** |

---

## Files

```
phase3/
    README.md
    src/phase3.py
    notebooks/phase3.ipynb
    outputs/
        reference_product_catalog.csv
        product_group_mapping.csv
        ambiguous_cases.csv
        unknown_products.csv
        phase3_executed.ipynb
    validation/
        phase3_validation.json
    statistics/
        phase3_statistics.json
    audit/
        phase3_1_unknown_audit.csv
        phase3_1_unknown_audit.parquet
        phase3_1_audit_summary.parquet
        peanut_butter_grouping_example.parquet
    notebooks/
        phase3_1_audit.ipynb
```

---

## How to Run

```bash
cd /home/sara/gsoc/compliments-reference-db
python -m phase3.src.phase3
```

---

## LLM Usage

None. All grouping is deterministic.

---

## Handoff

Phase 3 outputs are the frozen product-grouping layer.

Future phases will add:
- Phase 4: Variant assignment
- Phase 5: Nutrition merge
- Phase 6: Nutrition scoring (NutriScore, NOVA, EcoScore)
- GPC integration
- Agribalyse integration