# EZPsych for Market Research ## Overview EZPsych was built for academic questionnaire pilots — LLM-simulated respondents answer your instrument so you can check reliability, item quality, and dimension structure *before* recruiting real participants. The same machinery (workbook format, persona sampling, scoring, psychometric report) is directly reusable for brand and market research pre-testing: concept tests, ad/copy comparisons, pricing research, and questionnaire QA for a survey firm's fieldwork instrument. This guide covers what fits, how to design consumer personas, and a worked example. It assumes you have already read `docs/workbook_creation_prompt.md` for the base workbook format (four sheets: `questionnaire`, `codebook`, `personas`, `experiment_config`). --- ## What fits vs. what does not ### Fits: pre-testing and directional insight | Use case | How EZPsych supports it | |---|---| | **Concept testing** | Model purchase intent, uniqueness, believability, brand fit, and overall appeal as 5-point `single_choice` items, each its own `dimension`. Embed the concept description directly in every relevant `question_text` (each item is answered independently — there is no shared chat history between questions), so every rating is grounded in the same stimulus. | | **Pricing research (Van Westendorp)** | Model the 4 classic price questions ("too expensive," "too cheap," "getting expensive," "a bargain") as `single_choice` items with price bands as options, and `score_value` set to each band's midpoint. This gives you a mean price point per question, which is what the Van Westendorp method needs. | | **Ad / copy A-B comparisons via the item-effect mechanism** | Put each variant (e.g., `AD_COPY_A`, `AD_COPY_B`) in as its own question item sharing the same rating scale, then set `item_effect_enabled=true`. The order-monitoring pass re-runs a subsample with item order shuffled and reports whether scores move with presentation order. Use this to sanity-check that a copy-A-vs-copy-B difference you see is a real preference and not just a first-shown / last-shown artifact — counterbalance or discount the comparison if the order-effect check flags one. | | **Questionnaire QA before fieldwork** | Run your real, human-bound survey draft through EZPsych first. Cronbach's alpha, inter-item correlations, and item discrimination per dimension surface confusing wording, redundant items, or a scale that will not hold together — cheaply, before you pay a panel provider. | ### Does not fit: standing in for real fieldwork - **Claiming real market share, revenue, or adoption numbers.** Simulated respondents are not a substitute for your target population; they cannot tell you what percentage of the real market will buy. - **Final go/no-go launch decisions.** Use EZPsych to catch bad questions, weak differentiation, or a confusing price frame before you spend fieldwork budget — not to replace the fieldwork itself. - **Anything requiring real behavior** (actual purchase, willingness to pay measured in an incentive-compatible way, real brand recall over time). LLM personas answer as language models predicting a plausible response, not as economic agents. > **Positioning rule:** EZPsych sells pre-testing / pilot / directional insight before > real fieldwork. Never present simulated output as if it were real consumer research > data, and say so explicitly in any report or deck built from these results. --- ## Designing consumer personas The `personas` sheet is a wide-format table: one column per dimension, candidate values listed downward, sampled via Latin Hypercube Sampling (LHS) into diverse, non-repeating persona combinations. For market research, pick dimensions that actually predict how someone reacts to your product/price — demographic dimensions alone are a weak proxy; usage frequency and price sensitivity usually matter more than age or gender. ### China-market consumer preset (6 dimensions) Ready to copy into the `personas` sheet header row: | city_tier | age_band | income_band | gender | category_usage_frequency | price_sensitivity | |---|---|---|---|---|---| | Tier 1 (Beijing / Shanghai / Guangzhou / Shenzhen) | 18-24 | Under RMB 5,000/mo | Male | Daily | Very price-sensitive | | Tier 2 (provincial capital) | 25-34 | RMB 5,000-10,000/mo | Female | A few times a week | Somewhat price-sensitive | | Tier 3 (prefecture-level city) | 35-44 | RMB 10,000-20,000/mo | | A few times a month | Neutral | | Tier 4-5 (county town / rural) | 45-54 | RMB 20,000-40,000/mo | | Rarely | Not very price-sensitive | | | 55+ | Over RMB 40,000/mo | | Never tried this category | Price-insensitive | Suggested `persona_template`: ``` A {gender} aged {age_band} living in a {city_tier} city in China, household income {income_band}. Drinks beverages in this category {category_usage_frequency} and is {price_sensitivity} about price. ``` This is exactly the preset used in `examples/market_research_workbook_example.xlsx`. ### Western-market variant Same 6 dimensions, swapped for a US/UK-style geography and USD income bands: | region | age_band | income_band | gender | category_usage_frequency | price_sensitivity | |---|---|---|---|---|---| | Urban | 18-24 | Under $30,000/yr | Male | Daily | Very price-sensitive | | Suburban | 25-34 | $30,000-60,000/yr | Female | A few times a week | Somewhat price-sensitive | | Rural | 35-44 | $60,000-100,000/yr | | A few times a month | Neutral | | | 45-54 | $100,000-150,000/yr | | Rarely | Not very price-sensitive | | | 55+ | Over $150,000/yr | | Never tried this category | Price-insensitive | Suggested `persona_template`: ``` A {gender} aged {age_band} living in a {region} area, household income {income_band}. Drinks beverages in this category {category_usage_frequency} and is {price_sensitivity} about price. ``` ### Notes - Column headers become `{placeholder}` names in `persona_template` — keep them simple identifiers (snake_case, no spaces) as shown above. - Reserved words (`dimension`, `field`, `value`, `weight`, etc.) cannot be used as column headers — the loader treats a header containing one of those as a non-wide-format sheet and will reject it. See `docs/workbook_creation_prompt.md` for the full reserved-word list. - You do not need equal-length columns; short columns (e.g., `gender` with 2 values) are fine next to long ones (e.g., `income_band` with 5) — empty cells are skipped. - Swap in whatever dimensions actually matter for your category (e.g., `household_size`, `parental_status`, `existing_brand_used`) — the 6-dimension presets above are a starting point, not a fixed schema. --- ## Worked example: `market_research_workbook_example.xlsx` `examples/market_research_workbook_example.xlsx` is a full concept test for a fictional beverage, "Qing Studio" — a sparkling, low-sugar oolong tea in a 480ml can. It has 10 questionnaire items across three groups. ### 1. Concept-rating items (5 items, `single_choice`, 5-point scale, `choice_score`) Each question repeats the concept description in its `question_text` (there is no shared context between items) and asks about one attribute: | question_id | dimension | What it measures | |---|---|---| | `PI1` | `Purchase_Intent` | "How likely are you to buy this product?" | | `UNQ1` | `Uniqueness` | How different it is from what's already available | | `BEL1` | `Believability` | Whether the claims (low sugar, real fruit juice) are credible | | `FIT1` | `Brand_Fit` | Fit with brands the respondent would normally consider | | `APPEAL1` | `Overall_Appeal` | Overall appeal, as a catch-all summary rating | Each is scored `A=1 ... E=5`, its own `dimension`, `score_aggregation=mean` (single item per dimension, so aggregation is a no-op but must still be a valid value). ### 2. Van Westendorp price questions (4 items, `single_choice` price bands, `choice_score`) All four share the same 6 price bands as options (`Under ¥4` through `Over ¥12`), with `score_value` set to each band's midpoint (3, 5, 7, 9, 11, 13) so the resulting mean per question is a usable price point: | question_id | dimension | Classic Van Westendorp question | |---|---|---| | `VW_TOOEXP` | `VW_TooExpensive` | Price at which it's too expensive to consider | | `VW_TOOCHEAP` | `VW_TooCheap` | Price at which you'd doubt its quality | | `VW_EXP` | `VW_Expensive` | Price starting to feel expensive but still acceptable | | `VW_BARGAIN` | `VW_Bargain` | Price that feels like a bargain | The concept description deliberately omits any suggested price — showing a price before asking these questions anchors respondents and defeats the method. ### 3. Open-text purchase barrier (1 item, `text`, `text_score`) `BARRIER1` asks "what (if anything) would stop you from buying this product?" and is scored with a simple 3-level rubric in `codebook.scoring_instructions`: | Label | Score | Meaning | |---|---|---| | `LEVEL_1` | 1 | A clear deal-breaker (health/safety, price, dislike of the category) | | `LEVEL_2` | 2 | A soft concern that likely wouldn't stop the purchase | | `LEVEL_3` | 3 | No real barrier mentioned | ### Personas and run settings `personas` uses the China-market preset above (`city_tier`, `age_band`, `income_band`, `gender`, `category_usage_frequency`, `price_sensitivity`). `experiment_config` sets `sample_size=200`, `repeats=1`, `report_enabled=true`, and `item_effect_enabled=false` (this example is a plain concept test, not an A/B copy comparison — flip that flag to `true` and add a second variant item if you want to run the ad/copy A-B pattern described above). ### Validating it yourself ```python from survey_workbook import load_survey_workbook_bundle from budget import estimate_from_workbook bundle = load_survey_workbook_bundle("examples/market_research_workbook_example.xlsx") estimate = estimate_from_workbook("examples/market_research_workbook_example.xlsx") print(len(bundle.questions), "items;", estimate.persona_count, "personas;", "$%.2f" % estimate.estimated_price_usd, "estimated price") ``` `tests/test_market_example.py` runs this exact round-trip plus shape assertions — `python tests/test_market_example.py` should print `All checks passed.` --- ## Honest-use disclaimer Results from EZPsych — including everything produced from this workbook — are LLM-simulated directional signal, not real consumer research. Use them to catch weak concepts, confusing price framing, or a shaky questionnaire early and cheaply. Do not present simulated purchase intent, price points, or open-text themes as real market data, and do not use them as the sole basis for a launch, pricing, or budget decision. Validate anything that matters with real respondents before you act on it.