Data AnalyticsCustomer and product analytics

Market-basket analysis without confusing popularity with affinity

PK
Pankit Kumar
Sr. Data Scientist at Parexel (a Goldman Sachs–backed company) · 20 September 2026 · 3 min read
Technically reviewed by Ishaan Sharma
In this article (5 sections)

A product can appear in many baskets simply because it is popular. Market-basket analysis asks whether two products appear together more often than their individual popularity would suggest. Support, confidence and lift answer different parts of that question.

A rule with high confidence is not automatically a strong association, and an association does not establish that recommending one item will cause an additional purchase.

Start with baskets rather than item quantities

The synthetic basket fixture contains six baskets:

BasketProducts present
B1Bread, milk
B2Bread, milk
B3Bread, milk, eggs
B4Bread
B5Milk
B6Eggs

Treat each product as present or absent within a basket. Buying three cartons of milk should not create three independent basket observations. The lab's primary key is basket plus product, which prevents duplicated presence rows.

Bread appears in four baskets, milk in four, and both together in three. For the rule bread → milk:

  • Support is 3/6 = 50%: the share of all baskets containing both.
  • Confidence is 3/4 = 75%: the share of bread baskets also containing milk.
  • Lift is (3/4)/(4/6) = 1.125: confidence relative to milk's overall prevalence.

The 75% confidence sounds substantial, but milk already appears in two-thirds of all baskets. Lift reveals the more modest relative association in this sample. IBM's association-rule lift documentation explains this baseline comparison.

Reproduce both a positive and a negative association

python
from collections import defaultdict
from math import isclose
from build_and_verify import database

db = database()
baskets = defaultdict(set)
for basket, product in db.execute('SELECT basket_id,product FROM baskets'):
    baskets[basket].add(product)
db.close()

def rule(antecedent, consequent):
    n = len(baskets)
    left = sum(antecedent in items for items in baskets.values())
    right = sum(consequent in items for items in baskets.values())
    joint = sum({antecedent, consequent} <= items for items in baskets.values())
    if not n or not left or not right:
        return None
    return {'baskets': n, 'joint': joint, 'support': joint/n,
            'confidence': joint/left, 'lift': (joint/left)/(right/n)}

bread_milk = rule('bread', 'milk')
milk_eggs = rule('milk', 'eggs')
assert bread_milk['joint'] == 3
assert bread_milk['support'] == .5 and bread_milk['confidence'] == .75
assert isclose(bread_milk['lift'], 1.125)
assert milk_eggs['confidence'] == .25
assert isclose(milk_eggs['lift'], .75)
assert rule('absent_product', 'milk') is None
print(bread_milk, milk_eggs)

Milk → eggs has confidence 25%, below eggs' overall presence of one-third. Its lift is 0.75. A low absolute confidence threshold could retain this rule despite the negative association relative to that baseline.

The function returns no result when a required denominator is zero. An undefined rule should not be presented as a measured lift of zero.

Preserve the population that produced the rule

This code derives the basket population from product rows, which is appropriate for these six completed, nonempty baskets. If a business includes empty carts, abandoned baskets or orders containing only filtered-out products, retain a separate basket header table. Otherwise product filtering silently changes the denominator.

Specify whether returns, canceled orders, bundles and promotions belong in the analysis. A forced bundle can create co-occurrence through merchandising rules rather than a customer's independent preference. Availability also matters: an out-of-stock item cannot co-occur even if customers wanted it.

Evaluate a recommendation before rollout

Six baskets demonstrate arithmetic, not reliable commercial evidence. At larger scale, searching thousands of pairs can produce apparently interesting rules by chance. Require adequate counts, examine stability in a later period and avoid selecting solely by the largest lift among tiny groups.

To assess a recommendation, measure incremental contribution and user experience in a suitable experiment. Displaying a recommendation could replace an item the customer already intended to buy, increase returns or add friction. Association strength alone cannot answer those questions.

Exercise: add many milk-only baskets. Recalculate confidence and lift for bread → milk. Explain why confidence can stay fixed while lift falls as the consequent becomes more common.

NeuraPath's Data Analytics with Generative AI course connects descriptive analysis with testable decisions. A useful basket project makes the baseline, sample size and proposed intervention explicit.

Continue learning

This article is part of the Customer and product analytics sequence. Use the neighbouring tasks when you need the prerequisite or the next application.

PK
Pankit Kumar
Lead Instructor, NeuraPath Academy

Pankit Kumar has 10 years in Data Science & AI, building and shipping production systems in regulated pharma and clinical environments. He is a freelance trainer at Boston Institute of Analytics, AnalytixLabs and Scaler, and has taught this material to thousands of working professionals.

This article is part of our Data Analytics with Generative AI programme — 3–4 months. The full analyst stack — Excel, SQL, Power BI and Python pipelines — then a generative-AI layer you can prove is right.

Explore Data Analytics with Generative AI
Counselling is free · no obligation

Not sure which programme fits?

Tell us your background and we will map it to the right entry point — including saying so when a cheaper programme is the better fit. A counsellor replies within one working day.