← Data Science & Engineeringภาษาไทย

CUSTOMER ANALYTICS · INTERACTIVE LAB

RFM is not only for segmentation. It reveals how a customer relationship moves.

Choose one customer and read three pieces of evidence together: how recently they returned, how often they purchased, and how much value they generated. Then inspect multi-period slopes to separate fading engagement from a naturally long repurchase cycle.

ONLINE RETAIL · REAL DATA · 541,909 SOURCE ROWS

Ready to experiment? Start here.

Every lab uses the same 18,532 valid invoices and population of 4,338 anonymized customers.

01 · DATA GRAIN

Before calculating, prove that the same customer can be followed over time.

The lab uses the real 541,909-row Online Retail dataset from 1 December 2010 to 9 December 2011—the same source used by the original SQL, notebooks and slides. Missing IDs, cancellations, negative quantities and zero prices are removed before product lines are aggregated into invoice rows.

Customer IDs are hashed into R-xxxxxxxx identifiers and the raw file remains outside the public web directory. Preparation yields 18,532 invoices from 4,338 customers, with a twelve-customer teaching cohort selected for contrasting behaviour.

COMMON DATA CONTRACTcustomer_id · invoice_id · occurred_at · amountOne row = one valid invoice after line aggregation; monetary values are GBP.

R · F · M ARE THREE DIFFERENT QUESTIONS

Do not combine the three too early. Each tells a different story.

RFM is attractive because its formulas are simple while its interpretation is not. We are not merely asking who spent the most; we measure distance, continuity and relationship size at a particular point in time.

R

Recency

How fresh is the relationship?

Count days from the last transaction to the snapshot. Lower is often better, but daily goods and annual purchases cannot share one threshold. Read recency against the expected purchase cycle.

R = snapshot_date − max(purchase_date)
F

Frequency

Does the relationship repeat?

Count distinct invoices, not product rows; otherwise one basket with ten items appears as ten purchases. Define the window explicitly because lifetime frequency automatically favours older customers.

F = count(distinct invoice_id)
M

Monetary

How much value arose in the same boundary?

Gross sales, net sales, margin and contribution are different. This lab uses paid amount for formula clarity; a real system should use the value aligned with the decision and handle refunds and cancellations correctly.

M = sum(valid transaction value)
BEFORE YOU RUN

Should the answer change when snapshot or window changes?

  1. Predict the selected customer segment first.
  2. Compare 90, 120 and 180-day windows.
  3. Separate behavioural change from definition change.
R = snapshot − last purchaseF = distinct invoices in windowM = Σ invoice amount in window
RECENCY · lower is more recentdaysR—
FREQUENCY · distinct invoicesordersF—
MONETARY · window valueTHBM—
RFM SEGMENTRFM —

RAW METRIC ≠ RFM SCORE

Fourteen days does not always mean R = 4.

The raw metric describes the customer; a 1–4 score describes relative position within the population at the same snapshot. This lab uses quartiles: recency is reversed because lower is better, while frequency and monetary reward higher values.

RawR=14 · F=6 · M=18,400Population rankQ4 · Q3 · Q4Segment codeRFM 434

When population or period changes, a score can change while the raw value stays constant. A feature store should retain raw values, binning logic and segmentation version.

04–05 · CUSTOMER MOVEMENT

Read the direction—not a single snapshot.

Each point uses the same rolling window; a line is fitted to values normalized within that customer.

Recency riskFrequencyMonetary
RECENCY SLOPE

Positive means days since last purchase are rising—a negative signal.

FREQUENCY SLOPE

Negative means rolling-window purchase frequency is falling.

MONETARY SLOPE

Negative means rolling-window monetary value is falling.

CHURN SIGNAL · NOT A CALIBRATED PROBABILITY

/ 100

HOW TO READ THREE SLOPES

Customers with the same falling score may require different responses.

R slopeF slopeM slopePossible readingInspect next
Broad disengagement

Product, channel, service issues and alternatives.

Less frequent, larger baskets

Possible order consolidation rather than churn.

Still returning, lower spend

Product mix, discounts, unit price and economic context.

Repurchase cycle may be lengthening

Compare category cadence and matched cohorts.

06 · FROM SIGNAL TO ACTION

A score should not make the decision. It should tell us what to inspect next.

Boundary to state clearly

The slope in this lab is a behavioural heuristic, not a trained and calibrated churn probability. A predictive model needs a churn horizon, future-derived labels, temporal validation, precision/recall and calibration checks, plus the product’s natural repurchase cycle.

FROM RFM HEURISTIC TO CHURN MODEL

To call it prediction, the future must provide the label.

RFM and slopes are useful, explainable features, but a model is credible only when every feature is built at prediction time without seeing the future.

01

Define the event

For example, no purchase within 60 days after snapshot, aligned with product cadence.

02

Build point-in-time features

Use RFM, slopes, tenure, interval variance, product diversity and refund rate from pre-snapshot data only.

03

Split by time

Train on the past, validate on the next period and test on the latest period; do not leak future rows through random splitting.

04

Evaluate for the decision

Use precision, recall, PR-AUC, lift@k and calibration alongside contact cost and retention value.

STUDENT INVESTIGATION

Questions students should answer after the lab

  1. Why must frequency count distinct invoices, and what breaks when product rows are counted?
  2. Does the same customer change segment under another window, and is that behavioural change or an artefact?
  3. When can recency worsen without implying churn?
  4. Why is a score of 80/100 here not an 80% churn probability?
  5. Which labels and validation design turn a signal into a prediction?

FORMULA → SQL

Translate the same question into an inspectable query.

SELECT customer_id,
       DATEDIFF(:snapshot, MAX(occurred_at))                         AS recency,
       COUNT(DISTINCT invoice_id)                                   AS frequency,
       SUM(amount)                                                  AS monetary
FROM transactions
WHERE occurred_at > :snapshot - INTERVAL 120 DAY
  AND occurred_at <= :snapshot
GROUP BY customer_id;

In production, persist weekly or monthly snapshots and estimate slope by regression over multiple points rather than dividing two period scores once.

THE SAME RFM IDEA · TWO COMPUTATIONAL LANGUAGES

The notebook makes the process visible; SQL keeps it close to the data.

Read the question first, then translate the same formula between dataframe and relational operations in the slide sequence.

01 · Clean02 · Derive03 · Aggregate04 · Score05 · Movement
01
DATA QUALITY

Which transactions belong in RFM?

Remove missing IDs, duplicates, negative quantities and zero prices; otherwise the formula may be correct while its meaning is wrong.

PYTHON · PANDAS
df = df.dropna(subset=['CustomerID'])
df = df.drop_duplicates()
df = df[(df.Quantity > 0) & (df.UnitPrice > 0)]
SQL · FILTER
WHERE customer_id IS NOT NULL
  AND invoice_no NOT LIKE 'C%'
  AND quantity > 0
  AND unit_price > 0
02
FEATURE DERIVATION

Derive transaction value

The notebook creates an in-memory column; SQL creates a query-plan expression. The formula is identical.

PYTHON
df['TotalSum'] = df['UnitPrice'] * df['Quantity']
SQL
unit_price * quantity AS line_value
04
RELATIVE SCORING

qcut versus NTILE

Recency reverses because fewer days are better; ties may make the two methods form different boundaries.

PYTHON · QCUT
r = pd.qcut(rfm.Recency, 4, labels=[4,3,2,1])
f = pd.qcut(rfm.Frequency, 4, labels=[1,2,3,4])
m = pd.qcut(rfm.Monetary, 4, labels=[1,2,3,4])
SQL · WINDOW
5 - NTILE(4) OVER (ORDER BY recency) AS r,
NTILE(4) OVER (ORDER BY frequency) AS f,
NTILE(4) OVER (ORDER BY monetary) AS m
05
CUSTOMER MOVEMENT

From Q1/Q2 ratio to multi-period slopes

The original notebook introduces movement with two periods; this lab extends it across snapshots and separates R, F and M slopes.

ORIGINAL NOTEBOOK
movement['Slope'] = (
  movement.RFM_ScoreQ2 /
  movement.RFM_ScoreQ1
)
EXTENDED SQL IDEA
REGR_SLOPE(recency_norm, snapshot_no) r_slope,
REGR_SLOPE(frequency_norm, snapshot_no) f_slope,
REGR_SLOPE(monetary_norm, snapshot_no) m_slope

Notebook is suited to

Missingness and distribution exploration, visualisation, clustering and cell-by-cell explanation.

SQL is suited to

Computing near data, publishing reproducible views/snapshots and retaining governance.

Practical combination

SQL builds point-in-time feature tables; notebooks validate, visualise and prototype models.

Intentional correction to the source examples

The original SQL uses COUNT(*) and directly ranks last_order_date. This lesson first counts distinct invoices and derives elapsed days from a snapshot so Frequency and Recency match their definitions.

FROM THE ORIGINAL LECTURE · VISUAL READING

The original slides show how RFM moves from tables to segments and movement.

These are not a decorative gallery. They follow the reasoning sequence: definition → query → metrics → scoring → visualisation → churn signal.

RFM definition slide showing Recency Frequency and Monetary
01 · DEFINEBegin with three distinct questions before combining them into one score.
SQL clean view for RFM
02 · CLEAN VIEWSQL aggregates transactions by customer and defines valid data boundaries.
SQL RFM analysis using NTILE
03 · SCORE IN SQLWindow functions translate raw metrics into relative population positions.
Python calculation of RFM metrics
04 · CALCULATEThe notebook exposes snapshot logic, aggregation and the result table together.
Python RFM actionable scoring
05 · SCORE IN PYTHONqcut forms quartiles and combines R, F and M into an interpretable code.
RFM snake plot comparing customer groups
06 · READ SHAPEA snake plot reveals which metric distinguishes each group—not merely the total score.
RFM heat maps comparing segment profiles
07 · COMPARE PROFILESHeat maps expose relative RFM importance across segments.
RFM segment dashboard
08 · SEGMENT MAPSegment area conveys population size; position and labels support business communication.
RFM customer movement toward churn prediction
09 · MOVEMENTMovement between segments bridges segmentation and churn signals, but is not yet a probability.
Teaching prompt

SQL and Python agree when data contract, snapshot, filters and quartile logic agree. If results differ, first inspect grain, cancelled invoices, distinct-invoice counting, ties and snapshot boundaries—not the engine.

BOUNDED PYTHON RUNNER · LIVE DASHBOARD

Choose a stage and run the real Python calculation.

This dashboard exposes parameters, not arbitrary execution. The displayed code is the actual bounded operation, allowing students to read, run and inspect output without opening a server shell.

CONNECTING…— ms
PYTHON CODE · READ ONLY
# Select an operation and run.
RESULT · JSON
{}
Safety boundary

Only four operations, twelve customer IDs and bounded snapshots/windows are accepted. There is no eval/exec, package installation, user filesystem access or public Python-service port.

ROLLING TIME WINDOW · DYNAMIC RFM

As time moves, RFM can change even without a new row.

Move the snapshot or press Play and watch both boundaries: the right edge is “today,” which increases recency; the left edge expires evidence, reducing frequency and monetary value when transactions fall out.

Expired
ROLLING WINDOW
Future
+ 0 entered0 expired0 inside
RECENCYdays since last purchase
FREQUENCYinvoices in window
MONETARYTHB in window
Recency riskFrequencyMonetary
01 · No new purchase

Recency rises with time; F and M hold until the left boundary reaches a transaction.

02 · A new purchase arrives

Recency resets near zero, frequency increases and monetary value rises by the transaction amount.

03 · An old purchase expires

Nothing is deleted from the database; the feature changes because the window no longer sees that evidence.

RFM SEGMENT MAP · CUSTOMER MOVEMENT

Where is the selected customer—and where are they moving?

The map scores all 4,338 customers for the selected snapshot and window. The dashed outline marks the previous position; the solid outline marks the current one.

LOADING POPULATION…4,338 customers scored
Read with care

A segment is a business rule translating RFM scores into shared language, not a permanent truth. Changing the snapshot, window, or population quartile boundaries may move a customer.