This repository provides the reviewer-facing PyTorch implementation of GamePEM, a theory-guided framework for demand modeling and constrained dynamic pricing in virtual goods markets.
GamePEM combines neural demand estimation with pricing structure that is useful in deployment:
- Dynamic Substitution Module (DSM) for competitor-side promotion and substitution signals.
- Multi-Scale Lifecycle Encoder (MLE) for short-term volatility and long-term lifecycle fatigue.
- Constant-elasticity demand backbone that enforces a non-positive price-demand relationship.
- Discrete constrained price optimization over valid price tiers with volatility, discount-depth, and manual-review guardrails.
The proprietary production dataset and paper draft are not included in this repository. For transparent reproduction, the code includes a synthetic data generator that creates SKU-level demand, price, lifecycle, engagement, and competitor-promotion signals following the same modeling assumptions.
git clone https://github.com/Qqqq5910/GamePEM.git
cd GamePEM
python3 -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install -e ".[dev]"The project requires Python 3.9+ and runs on CPU for the included reproduction path. PyTorch will use CUDA or Apple MPS automatically when available.
Run the complete synthetic reproduction:
bash scripts/run_reproduction.shThis script generates synthetic data, trains GamePEM, evaluates demand prediction, and writes constrained price recommendations.
Expected generated artifacts:
outputs/reproduction/
checkpoint.pt
checkpoint_best.pt
metrics.json
predictions.csv
predictions_last.csv
recommendations.csv
If a machine has a CUDA/cuDNN mismatch, force CPU execution:
CUDA_VISIBLE_DEVICES="" bash scripts/run_reproduction.shFor a fast CI-style check:
bash scripts/run_smoke.shGenerate synthetic reviewer data:
python scripts/generate_synthetic_data.py \
--output-dir data/sample \
--num-skus 20 \
--num-days 420 \
--seed 37 \
--top-k 5Train the model:
python scripts/train.py \
--config configs/default.json \
--data-dir data/sample \
--output-dir outputs/reproductionGenerate T+1 price recommendations:
python scripts/recommend.py \
--config configs/default.json \
--checkpoint outputs/reproduction/checkpoint_best.pt \
--data-dir data/sample \
--output outputs/reproduction/recommendations.csvThe public repository does not contain proprietary production data. Use the synthetic generator above for review and debugging, or place private data under data/private/.
Minimum daily SKU columns:
| column | meaning |
|---|---|
date |
Daily observation date. |
sku_id |
SKU identifier. If absent, the loader treats the file as one SKU. |
price |
Realized SKU price. |
demand |
Realized demand or units sold. |
Optional daily columns:
| column | meaning |
|---|---|
engagement |
Engagement score, sessions, or normalized activity. |
active_users |
Active users for the SKU/game. |
calendar_event |
Event or holiday indicator. |
promo_flag |
Focal SKU promotion indicator. |
Optional competitor columns:
| column | meaning |
|---|---|
date |
Observation date. |
sku_id |
Target SKU. |
competitor_id |
Competitor SKU or product. |
similarity |
Substitution similarity score. |
competitor_price |
Observed competitor price. |
competitor_price_change |
Relative competitor price change. |
competitor_promo_flag |
Competitor promotion indicator. |
Optional price-constraint columns:
| column | meaning |
|---|---|
sku_id |
SKU identifier. |
min_price |
Minimum allowed recommendation. |
max_price |
Maximum allowed recommendation. |
max_delta |
Maximum one-step absolute price change. |
max_discount_depth |
Maximum discount depth relative to reference price. |
price_tiers |
Pipe-separated valid tiers, such as `0.99 |
See docs/DATA_SCHEMA.md for details. The loader also supports the legacy column names Date, Price, and Daily Est. Units Sold.
configs/ JSON configs for full and smoke reproduction
data/ schema notes; generated/public data is ignored by git
docs/ reproduction guide, data schema, and method mapping
scripts/ CLI entry points for generation, training, and recommendation
src/gamepem/ reusable GamePEM package
tests/ lightweight unit tests
| Paper component | Code |
|---|---|
| Dynamic Substitution Module | src/gamepem/model.py::DynamicSubstitutionModule |
| Multi-Scale Lifecycle Encoder | src/gamepem/model.py::MultiScaleLifecycleEncoder |
| Constant-elasticity demand backbone | src/gamepem/model.py::DemandBackbone |
| Multi-task training objective | src/gamepem/training.py::compute_loss |
| Segment metrics | src/gamepem/metrics.py::evaluate_segments |
| Discrete constrained optimization | src/gamepem/optimization.py |
| T+1 recommendation workflow | scripts/recommend.py |
metrics.json reports WMAPE, MAE, and RMSE for the validation split, including high/low volatility and early/late lifecycle slices. By default:
validationreports the best epoch selected by validation WMAPE.validation_lastreports the final training epoch.checkpoint.ptstores the final epoch.checkpoint_best.ptstores the lowest-WMAPE validation epoch.
recommendations.csv contains the latest feasible recommendation per SKU, including current_price, recommended_price, predicted_demand, predicted_elasticity, expected_revenue, manual_review, and the scored candidate tier set.
Run unit tests:
pytest -qRun the smoke reproduction:
bash scripts/run_smoke.shGenerated data, model checkpoints, outputs, private data, and manuscript PDFs are ignored by git.
If you use this repository, please cite the associated GamePEM paper. The citation metadata is available in CITATION.cff and can be updated after the paper is accepted.
This project is released under the MIT License. See LICENSE.