<jupyter_start><jupyter_text>Load dataThe store sells 5 items:1. Milk2. Jam3. Bread4. Wheat Bread5. ButterWe have have 4 transactions. In the first one, 3 products were purchased: Milk, Bread and Wheat Bread.<jupyter_code>data = [
  ['Milk', 'Bread', 'Wheat Bread'],
  ['Jam', 'Bread', 'Butter'],
  ['Milk', 'Jam', 'Butter'],
  ['Jam', 'Butter']
]
data
from mlxtend.preprocessing import TransactionEncoder
encoder = TransactionEncoder()
df = pd.DataFrame(
    encoder.fit_transform(data),
    columns=encoder.columns_
)
df<jupyter_output><empty_output><jupyter_text>Using mlxtend<jupyter_code>from mlxtend.frequent_patterns import apriori
df_support = apriori(df, min_support=0.1)
df_support
df_support = apriori(df, min_support=0.1, use_colnames=True)
df_support
from mlxtend.frequent_patterns import association_rules
rules = association_rules(
    df_support, metric="confidence", min_threshold=0.7)
rules
rules[rules['antecedents'] == {'Butter'}]<jupyter_output><empty_output><jupyter_text>If someone buys butter, we're 75% confident he'll also buy jam  From scratch<jupyter_code>MIN_SUPPORT = 0.1

df_support = pd.DataFrame(columns=['support', 'itemsets'])
n = len(df)

# For each item, count the number of times they appear
for col in df.columns:
    support = df[col].sum()/n

    if support > MIN_SUPPORT:
        df_support.loc[len(df_support)] = [
            support, frozenset([col])
        ]
df_support
import itertools
# For each item that appears at least 10% of times
# Create combinations of 2
offset_1 = len(df_support)

for a, b in itertools.combinations(df_support['itemsets'], r=2):
    c = frozenset([*a, *b])
    print(c)

    support = df[c].all(axis=1).sum()/n

    if support > MIN_SUPPORT:
        df_support.loc[len(df_support)] = [
            support, c
        ]

df_support
# For each combinations of 2 that appears at least 10% of times
# Create combinations of 3 (by adding combinations of 1 >10%)
seen = set()

for a, b in itertools.product(
    df_support[:offset_1]['itemsets'],
    df_support[offset_1:]['itemsets']
):
    c = frozenset([*a, *b])

    # Check we've got a combination of 3
    if len(c) != 3: continue
    if c in seen: continue
    seen.add(c)

    # Check support
    print(c)
    support = df[c].all(axis=1).sum()/n

    if support > MIN_SUPPORT:
        df_support.loc[len(df_support)] = [
            support, c
        ]

seen = None
df_support
df_support['length'] = df_support['itemsets'].apply(lambda x: len(x))
df_support
df_support[df_support['length'] == 2]<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12764291307752546, 'fraction_numerical': 0.014487079091620987, 'mean_word_length': 4.203665987780041, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '162640', 'license': 'MIT', 'n_tokens_mistral': 916, 'n_tokens_neox': 872, 'n_words': 228, 'path': 'docs/!ml/notebooks/Apriori.ipynb', 'repo_name': 'a-mt/dev-roadmap', 'size': '2554'}