---
name: ppa-value-perception
description: >
  Measures and optimizes consumer value perception, decision hierarchies, and
  willingness-to-pay (WTP) across price-pack combinations. Trigger when asked to:
  measure WTP by segment, detect perception failures (larger pack costs more per
  kg/ml than smaller), model consumer decision hierarchy, identify value drivers by
  attribute, test value communication messages, or design value propositions by
  channel and SKU. Also trigger for: "percepción de valor", "WTP", "disposición a
  pagar", "jerarquía de decisión", "conjoint analysis", "MaxDiff", "value drivers",
  "precio por kg más caro en pack grande", "percepción de precio". Always renders
  inline HTML dashboard. Includes marketer NBA, WTP curves, and perception failure
  alerts by market, category, and SKU.
---

# ppa-value-perception

Measures consumer value perception, models decision hierarchies, estimates WTP via
logit and conjoint, and detects perception failures. Always outputs dashboard first.

---

## Plain Language: What This Does

```
"¿Cuánto pagaría el consumidor por este pack?"  → WTP estimation (logit/conjoint)
"¿El pack 1L es percibido como mejor valor que 500ml?"  → Perception failure check
"¿Qué atributo importa más: precio, marca o tamaño?"  → Decision hierarchy + value drivers
"¿Cómo comunicar mejor el valor de este SKU?"  → Value communication A/B test
"¿El segmento premium paga más por conveniencia?"  → WTP by segment × occasion
```

**Core insight (EY PPA Framework p.3):**
A larger pack that costs MORE per kg/ml than the smaller pack creates a negative brand
impression — the shopper feels cheated. This is a perception failure that reduces
brand equity even if the absolute price is rational.

---

## Core Equations

### WTP from logit model (choice-based conjoint)
```python
# Logit utility model:
U(alternative) = β_price × price + β_size × size + β_brand × brand + ε

# WTP for attribute X (eq. from Lancaster-McFadden):
WTP_X = -β_X / β_price

# Where β_price < 0 (price always reduces utility)
# β_X > 0 → consumer pays MORE for attribute X
# β_X < 0 → consumer pays LESS (negative preference)

# Example: β_brand_premium = 2.3, β_price = -0.8
# WTP_brand_premium = -2.3 / -0.8 = $2.88 above reference
```

### Perception failure detector
```python
# Price-per-unit consistency check across pack sizes:
price_per_unit_i = price_shelf_i / volume_i   # for each SKU i

# Violation flag: larger pack should be CHEAPER per unit
for each (small_pack, large_pack) in same_brand_same_tier:
    if price_per_unit(large_pack) > price_per_unit(small_pack):
        flag = "PERCEPTION_FAILURE"
        penalty_score = (ppu_large - ppu_small) / ppu_small  # % premium paradox

# Benchmark: >5% paradox triggers brand equity risk (EY PPA p.3)
```

### Value Score index
```python
# Composite perceived value:
value_score = (quality_perception × w_quality +
               price_fairness    × w_price +
               pack_convenience  × w_convenience +
               brand_trust       × w_brand) / Σw

# Weights from conjoint/MaxDiff by segment
# Benchmark: value_score > 0.65 = strong value proposition
```

### MaxDiff scaling (Sawtooth methodology)
```python
# Best-Worst scaling for attribute importance:
importance_score_i = exp(utility_i) / Σ_j exp(utility_j)

# Output: ranked importance 0–100 for each attribute
```

---

## Workflow

### Step 1 — Load SKU + price data
```bash
# Always run data-intake-normalizer first
python scripts/perception_failure_detector.py \
    --skus /mnt/user-data/uploads/sku_data.xlsx \
    --brand "BrandName" \
    --output results/perception_failures.json
```

### Step 2 — Model decision hierarchy
```bash
python scripts/decision_hierarchy.py \
    --survey /mnt/user-data/uploads/conjoint_survey.csv \
    --method logit \
    --attributes "price,size,brand,format,flavor" \
    --output results/decision_hierarchy.json
```

### Step 3 — Estimate WTP
```bash
python scripts/wtp_estimate.py \
    --hierarchy results/decision_hierarchy.json \
    --segments "value_seeker,mainstream,premium" \
    --output results/wtp.json
```

### Step 4 — Identify value drivers
```bash
python scripts/value_drivers.py \
    --transactions /mnt/user-data/uploads/transactions.csv \
    --attributes "price,size,brand,channel,promo" \
    --output results/value_drivers.json
```

### Step 5 — Test value communication (optional)
```bash
python scripts/value_communication_tester.py \
    --messages /mnt/user-data/uploads/messages.csv \
    --segment "mainstream" \
    --output results/communication_test.json
```

### Step 6 — Dashboard
```bash
python scripts/value_perception_report.py \
    --perception results/perception_failures.json \
    --wtp results/wtp.json \
    --drivers results/value_drivers.json \
    --output dashboard_data.json
```

**Output sequence:**
```
1. [bash_tool] perception_failure_detector.py → immediate flags
2. [bash_tool] wtp_estimate.py + decision_hierarchy.py
3. [web_search] WTP benchmarks [category] [market] [year] +
                "price perception consumer behavior [category] LATAM"
4. [show_widget] Dashboard: perception failure alerts + WTP curves +
                 decision hierarchy + value driver chart
5. [text] NBA + market context (brand, category, SKU, segment)
6. [text] Caveats: stated vs revealed preference, survey bias
```

---

## Market Context (always include)

- **Market**: country + city/zone
- **Category** + sub-category
- **Brand** + competitive set
- **Segment**: value seeker / mainstream / premium / super-premium
- **Occasion**: on-the-go / household / HoReCa / gifting
- **Channel**: MT / TT / convenience / e-comm
- **Data source**: conjoint survey / panel / transaction data

---

## Dashboard Panels

1. **KPI bar** — perception failures count, avg WTP gap vs current price,
   decision hierarchy top attribute, value score index, % SKUs with price paradox
2. **Perception failure table** — SKU pairs where large pack > small pack per unit,
   with paradox % and brand equity risk rating
3. **WTP curves** — price vs probability-of-choice by segment (S-curves)
4. **Decision hierarchy** — horizontal bar chart of attribute importance (MaxDiff scores)
5. **Value drivers** — feature importance from logit/RF model
6. **Value score map** — brand × tier × channel heat map of perceived value

---

## Marketer Insights Layer (MANDATORY)

### Search before benchmarking
```
web_search: "willingness to pay [category] [market] consumer research [year]"
web_search: "price perception pack size paradox [category] CPG [year]"
web_search: "conjoint analysis WTP FMCG LATAM benchmark [year]"
```

### Translate metrics to business language

| Technical | Business meaning |
|---|---|
| WTP = $24.50 | "Segment will pay up to $24.50 before switching — current price $21 = $3.50 headroom" |
| β_brand = 2.3 | "Brand preference is worth $2.88 in additional WTP vs generic" |
| paradox_pct = 12% | "Pack 1L costs 12% MORE per ml than 500ml — shopper perceives brand as unfair" |
| importance(price) = 45% | "Price is the #1 decision driver — brand only contributes 20% to choice" |
| value_score = 0.42 | "Below benchmark (0.65) — price, quality and convenience messages misaligned" |

### NBA — Next Best Actions

Always produce 5-6 specific actions:
- **Fix perception failures first**: "SKU [X] 1L costs $[A]/ml vs 500ml at $[B]/ml — reduce
  1L shelf price by [C]% or increase 500ml price to restore economic logic"
- **Capture WTP headroom**: "Segment [Y] has $[Z] WTP above current price —
  test +[X]% price increase in [channel] with no volume risk"
- **Hierarchy insight**: "Price is attribute #1 for [segment] (45% importance) —
  value messages must lead with economy, not quality or brand"
- **Reframe value communication**: "For premium segment, communication should
  emphasize [top driver] not [current message] — drivers show [X]% more impact on choice"
- **Segment-specific pricing**: "Value seekers WTP = $[A], premium = $[B] — [C]%
  gap justifies a dedicated entry SKU below $[D]"
- **Channel differentiation**: "WTP in convenience is $[A] vs supermarket $[B] —
  price the same SKU $[C] higher in convenience without switching risk"

---

## Key Caveats

- **Stated vs revealed preference**: Conjoint/survey WTP overstates actual behavior
  by 20–40% on average — apply deflation factor before pricing decisions
- **Hypothetical bias**: Survey respondents overstate premium brand preference;
  cross-validate with actual transaction data (value_drivers.py)
- **Segment stability**: WTP shifts with inflation — retune model every 6 months
  in high-inflation markets (MX, ARG, COL)
- **Perception failure ≠ always wrong**: Some brands intentionally price large packs
  at premium per-unit (luxury positioning) — flag but confirm strategic intent first
- **Survey design matters**: Choice-based conjoint requires ≥200 respondents per
  segment; MaxDiff requires ≥150

---

## Integration with OS

| Skill | Handoff |
|---|---|
| `data-intake-normalizer` | Always first — validate SKU/price/survey data |
| `ppa-assortment-diagnosis` | Diagnosis finds white spaces → perception tells what value to offer there |
| `ppa-portfolio-optimizer` | WTP by segment feeds optimal price-pack mix |
| `price-demand-optimization` | WTP = upper bound for p_opt estimation |
| `customer-segmentation-clustering` | Segments feed WTP estimation per persona |
| `trade-promotion-roi` | WTP gap = headroom for promo depth without brand damage |

---

## References

- `references/wtp_methodology.md` — Logit WTP derivation + conjoint design guide
- `references/perception_failure_cases.md` — EY case studies + paradox benchmarks
- `references/value_driver_benchmarks.md` — Attribute importance by category (LATAM)
