hg#

Homogenous Groups — find items that recur together.

To install: pip install hg

hg bundles two complementary ways of discovering repeated structure in data, with no third-party dependencies (pure standard library):

  • Duplication detection — find and remove the largest repeated contiguous blocks in an ordered sequence (e.g. repeated line-blocks in text).

  • Frequent-itemset mining — find sets of items that co-occur across transactions, optionally weighted by a per-transaction value.

Duplication detection#

The simplest case — de-duplicate repeated line-blocks in text, keeping the first occurrence:

>>> from hg import deduplicate_string_lines
>>> text = "A\nB\nC\nA\nB\nC\nD"
>>> final_text, removed = deduplicate_string_lines(text, min_block_size=3)
>>> print(final_text)
A
B
C
D
>>> removed
[RemovedBlock(removed_start=3, length=3, block_items=['A', 'B', 'C'])]

The same works on any sequence of items via deduplicate_sequence (or the reusable BlockDeduplicator), with an optional key to control how items are compared:

>>> from hg import deduplicate_sequence
>>> deduped, removed = deduplicate_sequence([1, 2, 1, 2, 3], min_block_size=2)
>>> deduped
[1, 2, 3]

min_block_size is the smallest repeated run to detect; detected blocks are then greedily extended to the largest repeated run.

Frequent-itemset mining#

Find sets of items that appear together in at least minimum_support transactions:

>>> from hg import find_frequent_itemsets
>>> transactions = [
...     ['bread', 'milk'],
...     ['bread', 'milk', 'eggs'],
...     ['milk', 'eggs'],
...     ['bread', 'butter'],
... ]
>>> for itemset in sorted(
...     find_frequent_itemsets(transactions, minimum_support=2),
...     key=lambda it: (-it.support, sorted(it.items)),
... ):
...     print(sorted(itemset.items), itemset.support)
['bread'] 3
['milk'] 3
['bread', 'milk'] 2
['eggs'] 2
['eggs', 'milk'] 2

Value-weighted itemsets#

The distinguishing feature: pass transaction_values to accumulate an arbitrary per-transaction quantity (revenue, duration, …) alongside the count. Each result is a FrequentItemset(items, support, value):

>>> prices = [4.0, 9.0, 5.0, 7.0]   # one value per transaction
>>> by_value = {
...     tuple(sorted(it.items)): it.value
...     for it in find_frequent_itemsets(
...         transactions, transaction_values=prices, minimum_support=2
...     )
... }
>>> by_value[('bread', 'milk')]     # baskets 0 (4.0) and 1 (9.0)
13.0

With no transaction_values, value simply equals support.

When to use which#

  • Reach for duplication detection when order matters and you want to collapse repeated runs (deduping logs, transcripts, generated text).

  • Reach for frequent-itemset mining when co-occurrence matters and order does not (market-basket analysis, tag/feature co-occurrence), especially when you want to weight occurrences by a value.

This documentation as a single file: hg.md (Markdown, for agents).

built 2026-09-22 14:31 UTC from 9ad945e (main) · hg 0.0.9 · about this build