saraNour commited on
Commit
bf2fcf4
Β·
verified Β·
1 Parent(s): e030e42

Upload README.md with huggingface_hub

Browse files
Files changed (1) hide show
  1. README.md +266 -0
README.md ADDED
@@ -0,0 +1,266 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Phase 4 β€” Variant Assignment / Variant Modeling
2
+
3
+ ## Compliments Reference DB Pipeline
4
+
5
+ **Version:** 1.0.0
6
+ **Date:** 2026-07-30
7
+ **Status:** PASS
8
+
9
+ ---
10
+
11
+ ## Purpose
12
+
13
+ Phase 4 transforms the Phase 3 product-group representation into a structured product variant model. Products belonging to the same reference product group can have different purchasable variants such as size, package quantity, formulation, flavour, fat level, etc.
14
+
15
+ ---
16
+
17
+ ## Key Concepts
18
+
19
+ ### Reference Product Group (from Phase 3)
20
+
21
+ A reference product group represents the same underlying product identity. All products in a group share the same identity attributes (organic, gluten-free, fat level, flavour, formulation, product_line).
22
+
23
+ ### Variant
24
+
25
+ A **variant** is a purchasable representation of the same reference product that differs in attributes such as:
26
+
27
+ - **Size**: 500 g, 1 kg, 2 kg
28
+ - **Package quantity**: 1 Γ— 500 g, 2 Γ— 500 g
29
+ - **Pack configuration**: single, multipack, case
30
+
31
+ ### Identifier Hierarchy
32
+
33
+ | Identifier | Level | Description |
34
+ |------------|-------|-------------|
35
+ | `external_id` | Source product | Voila retailer product ID (unique per product) |
36
+ | `upc` | Source product | Barcode (may be reused across variants) |
37
+ | `group_id` | Reference group | Deterministic UUID5 from Phase 3 |
38
+ | `variant_id` | Variant | Deterministic UUID5 from group_id + variant_key |
39
+
40
+ ---
41
+
42
+ ## Input Datasets
43
+
44
+ | Dataset | Source | Description |
45
+ |---------|--------|-------------|
46
+ | Phase 3 mapping | `phase3/outputs/product_group_mapping.csv` | Product-to-group mapping |
47
+ | Phase 2 output | `phase2/outputs/phase2_output.parquet` | Variant-relevant attributes |
48
+
49
+ ---
50
+
51
+ ## What Phase 4 Does
52
+
53
+ 1. **Loads Phase 3 outputs** β€” product_group_mapping.csv
54
+ 2. **Loads Phase 2 output** β€” for variant_attributes, flavour, formulation, fat_level, fat_percentage
55
+ 3. **Merges data** β€” combines group assignments with variant attributes
56
+ 4. **Builds variant keys** β€” deterministic keys from size/package attributes
57
+ 5. **Generates variant IDs** β€” deterministic UUID5 from group_id + variant_key
58
+ 6. **Creates variant tables** β€” main variant table, mapping, summary
59
+ 7. **Validates** β€” checks all consistency rules
60
+ 8. **Generates audit** β€” Peanut Butter example
61
+
62
+ ---
63
+
64
+ ## Variant Key Logic
65
+
66
+ The variant key captures size/package information:
67
+
68
+ ```
69
+ If count-based: "count{count}"
70
+ If size-based: "amt{amount}|unit{unit}[|qty{qty}][|mult{multiplier}]"
71
+ If raw: "raw{raw_string}"
72
+ If missing: "nosize"
73
+ ```
74
+
75
+ Examples:
76
+ - `"amt500.0|unitg"` β†’ 500 g
77
+ - `"amt1.0|unitkg"` β†’ 1 kg
78
+ - `"amt12|unitml|qty12"` β†’ 12 Γ— 12 ml
79
+ - `"count20"` β†’ 20 per pack
80
+ - `"nosize"` β†’ size missing
81
+
82
+ ---
83
+
84
+ ## Variant ID Generation
85
+
86
+ ```python
87
+ variant_id = uuid5(NAMESPACE_DNS, f"{group_id}||{variant_key}")
88
+ ```
89
+
90
+ This is:
91
+ - **Deterministic**: Same input β†’ same output
92
+ - **Reproducible**: Runs produce identical IDs
93
+ - **Collision-resistant**: UUID5 namespace-based
94
+
95
+ ---
96
+
97
+ ## Output Files
98
+
99
+ ### reference_product_variants.parquet
100
+
101
+ One row per unique variant.
102
+
103
+ | Column | Type | Description |
104
+ |--------|------|-------------|
105
+ | variant_id | str | Deterministic UUID5 |
106
+ | group_id | str | Reference group UUID |
107
+ | group_name | str | Most frequent core_title |
108
+ | brand | str | Normalized brand |
109
+ | product_line | str | Product line |
110
+ | product_domain | str | food/non_food/unknown |
111
+ | taxonomy | str | Taxonomy category |
112
+ | core_title | str | Core product title |
113
+ | variant_key | str | Deterministic variant key |
114
+ | size | str | Size string |
115
+ | size_amount | float | Numeric size amount |
116
+ | size_unit | str | Size unit |
117
+ | size_qty | int | Quantity multiplier |
118
+ | flavour | list | Flavour keywords |
119
+ | formulation | list | Formulation keywords |
120
+ | fat_level | str | Fat level |
121
+ | fat_percentage | float | Fat percentage |
122
+ | product_count | int | Products in this variant |
123
+ | unique_upcs | int | Unique UPCs in this variant |
124
+ | source | str | Data source |
125
+ | source_url | str | Source URL |
126
+
127
+ ### product_variant_mapping.parquet
128
+
129
+ Product-to-variant mapping.
130
+
131
+ | Column | Type | Description |
132
+ |--------|------|-------------|
133
+ | external_id | str | Source product ID |
134
+ | upc | str | Barcode |
135
+ | group_id | str | Reference group UUID |
136
+ | variant_id | str | Variant UUID |
137
+ | core_title | str | Core title |
138
+ | original_title | str | Raw title |
139
+ | brand | str | Normalized brand |
140
+ | size | str | Size string |
141
+ | variant_key | str | Deterministic variant key |
142
+ | source | str | Data source |
143
+ | source_url | str | Source URL |
144
+
145
+ ### reference_product_variant_summary.parquet
146
+
147
+ Group-level variant summary.
148
+
149
+ | Column | Type | Description |
150
+ |--------|------|-------------|
151
+ | group_id | str | Reference group UUID |
152
+ | group_name | str | Most frequent core_title |
153
+ | brand | str | Normalized brand |
154
+ | product_domain | str | food/non_food/unknown |
155
+ | taxonomy | str | Taxonomy category |
156
+ | variant_count | int | Number of variants |
157
+ | variant_ids | str | Comma-separated variant IDs |
158
+ | product_count | int | Total products in group |
159
+
160
+ ---
161
+
162
+ ## Validation Rules
163
+
164
+ | Rule | Description | Status |
165
+ |------|-------------|--------|
166
+ | 1 | Every product has exactly one variant | PASS |
167
+ | 2 | Every variant belongs to exactly one group | PASS |
168
+ | 3 | No product maps to multiple variants | PASS |
169
+ | 4 | Variant count matches across tables | PASS |
170
+ | 5 | All products have group_id | PASS |
171
+ | 6 | All products have variant_id | PASS |
172
+
173
+ ---
174
+
175
+ ## Handling Missing Size
176
+
177
+ - Products with missing size receive `variant_key = "nosize"`
178
+ - They still get deterministic variant_ids
179
+ - They are NOT merged together just because size is missing
180
+ - Phase 3 group identity remains authoritative
181
+
182
+ ---
183
+
184
+ ## Files
185
+
186
+ ```
187
+ phase4/
188
+ β”œβ”€β”€ README.md
189
+ β”œβ”€β”€ src/
190
+ β”‚ └── phase4.py
191
+ β”œβ”€β”€ notebooks/
192
+ β”‚ β”œβ”€β”€ phase4.ipynb
193
+ β”‚ └── phase4_executed.ipynb
194
+ β”œβ”€β”€ outputs/
195
+ β”‚ β”œβ”€β”€ reference_product_variants.parquet
196
+ β”‚ β”œβ”€β”€ reference_product_variants.csv
197
+ β”‚ β”œβ”€β”€ product_variant_mapping.parquet
198
+ β”‚ β”œβ”€β”€ product_variant_mapping.csv
199
+ β”‚ β”œβ”€β”€ reference_product_variant_summary.parquet
200
+ β”‚ └── reference_product_variant_summary.csv
201
+ β”œβ”€β”€ validation/
202
+ β”‚ └── phase4_validation.json
203
+ β”œβ”€β”€ statistics/
204
+ β”‚ └── phase4_statistics.json
205
+ └── audit/
206
+ └── phase4_peanut_butter_example.parquet
207
+ ```
208
+
209
+ ---
210
+
211
+ ## How to Run
212
+
213
+ ```bash
214
+ cd /home/sara/gsoc/compliments-reference-db
215
+ python -m phase4.src.phase4
216
+ ```
217
+
218
+ ---
219
+
220
+ ## LLM Usage
221
+
222
+ None. All variant assignment is deterministic.
223
+
224
+ ## Nutrition Usage
225
+
226
+ None. This phase does NOT load or use nutrition data.
227
+
228
+ ## External Datasets
229
+
230
+ None. This phase does NOT use GPC, Agribalyse, or any external taxonomy.
231
+
232
+ ---
233
+
234
+ ## Traceability
235
+
236
+ ```
237
+ source_of_truth/products.parquet
238
+ ↓
239
+ Phase 1 output (phase1_output.parquet)
240
+ ↓
241
+ Phase 2 output (phase2_output.parquet)
242
+ ↓
243
+ Phase 3 product_group_mapping.csv
244
+ ↓
245
+ Phase 4 product_variant_mapping.parquet
246
+ ↓
247
+ Phase 4 reference_product_variants.parquet
248
+ ```
249
+
250
+ ---
251
+
252
+ ## Known Limitations
253
+
254
+ - Variant assignment is based solely on size/package attributes
255
+ - Products with identical size but different packaging (e.g., bottle vs jar) cannot be distinguished
256
+ - The current dataset does not contain packaging type information
257
+
258
+ ---
259
+
260
+ ## Recommendation for Phase 5
261
+
262
+ Phase 5 (Nutrition Merge) should:
263
+ 1. Load `nutrition.parquet` from the authoritative source
264
+ 2. Join with `product_variant_mapping.parquet` on `external_id`
265
+ 3. Create a merged product-nutrition table
266
+ 4. Preserve all variant and group information