# Reproduce the RFM exercise

These are derived teaching materials from UCI Online Retail. Source transactions run from 2010-12-01 to 2011-12-09. The original analysis date is 2026-10-03; the fixed recency reference date is 2011-12-10.

## Source and transformations

Chen, D. (2015). Online Retail [Dataset]. UCI Machine Learning Repository. DOI: [10.24432/C5BW33](https://doi.org/10.24432/C5BW33). License: [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). [Dataset page](https://archive.ics.uci.edu/dataset/352/online+retail); [official ZIP](https://archive.ics.uci.edu/static/public/352/online+retail.zip).

We filter missing customer IDs, cancellation invoices, nonpositive quantities, and nonpositive unit prices in that order, then aggregate by customer. Exact duplicate rows are preserved; postage and manual-item codes are not additionally excluded. M is the positive purchase amount without cancellation offsets, not net revenue or profit. Prices remain in GBP.

`six-customers-source.csv` contains all 402 source rows for six fixed IDs, including records later excluded. It is not a representative sample. `rfm-six-customers.csv` contains their filtered RFM results. `rfm-all-customers.csv` contains all eligible customers. `analysis-summary.json` records definitions, sequential row counts, totals, examples, and checksums.

## Run the analysis

Download the official ZIP and the [analysis script](analyze_retail.py). With Python 3, pandas, and openpyxl available, run these commands in your download directory:

```sh
python3 -m pip install pandas openpyxl
python3 analyze_retail.py online-retail.zip rfm-results
```

Save the ZIP as `online-retail.zip`, or substitute its actual filename in the command. The script reads the ZIP without changing it and writes derived files into `rfm-results`. Choose another output directory if needed. The official ZIP is approximately 22.6 MB.

ZIP SHA-256: `f5385cbb54bbebf7196389109c6b0621faab0c304e3702548165e71c84aede8b`.

Inner XLSX SHA-256: `43465a06f2ccf7c8b5bd2892bc7defb52f97487934fe93b16ae4c3936424676d`.

## Check the result

Sequential exclusions plus eligible rows must total 541,909. The result has 4,338 customers and 18,532 distinct invoices. Customer-level M must sum to the eligible row-level quantity-times-price total of GBP 8,911,407.904. Round for display, not before multiplying individual prices.

R uses calendar-date differences, not elapsed hours: customer 12347 should have R = 3. F counts distinct invoices, not line items: that customer's F should be 7. Evaluate each illustrative group independently; the two groups do not cover all customers.

The dataset page's missing-value metadata does not replace inspecting the file. This file contains 135,080 rows with missing CustomerID. Wholesale customers and the limited observation period affect interpretation. Validate thresholds in your own business context before using them for marketing decisions.
