Cross-sell recommendations with association-rule learning — pure Python, no heavy dependencies.
Give arulerec your customers' purchase histories and it mines
association rules
(own Apriori implementation) and turns them into individual cross-sell
recommendations — the item a basket is most likely to be missing, ranked by
lift.
pip install -e ".[test]"Zero runtime dependencies.
from arulerec import ARuleRec
transactions = [
{"milk", "bread", "butter"},
{"milk", "bread"},
{"bread", "butter"},
{"milk", "butter"},
{"milk", "bread", "butter"},
]
model = ARuleRec(min_support=0.3, min_confidence=0.6).fit(transactions)
for rec in model.recommend({"bread", "butter"}):
print(rec.as_dict())
# {'item': 'milk', 'confidence': 0.75, 'lift': 0.9375, 'support': 0.6}Recommendations exclude items already in the basket and are ranked by lift then confidence.
from arulerec import ARuleRec, baskets_from_tidy
rows = [("c1", "milk"), ("c1", "bread"), ("c2", "butter"), ...]
baskets = baskets_from_tidy(rows)
model = ARuleRec(min_support=0.02, min_confidence=0.5).fit(baskets.values())
recs_by_customer = model.recommend_all(baskets, n=5) # top-5 per customerOnly customers with at least one recommendation are returned.
| Object | Purpose |
|---|---|
ARuleRec(min_support, min_confidence, max_len) |
.fit(transactions), .recommend(basket, n), .recommend_all(baskets, n) |
apriori(transactions, min_support, max_len) |
Frequent-itemset mining |
generate_rules(support, min_confidence) |
Build rules with support / confidence / lift |
baskets_from_tidy(rows) |
{user: {items}} from tidy rows |
Rule, Recommendation |
Result dataclasses |
This is textbook Apriori:
mine the itemsets that appear in at least min_support of baskets, build
antecedent -> item rules above min_confidence, rank recommendations by
lift. Every recommendation traces back to a rule you can print and read.
The limits follow from the method. You need enough baskets for support and
confidence to mean anything. Items rarer than min_support are never
recommended, so this won't solve cold starts. Lowering min_support blows up
the candidate set, so keep it reasonable (and cap max_len) on large catalogs.
And lift measures co-occurrence, not causation. For personalized (user × item)
recommendations at scale, use a matrix-factorization or embedding model
instead.
The original R implementation lives at
HenrikVarmer/aruleRec-R
(a wrapper around the arules package).
MIT © Henrik Varmer