Function to generate association rules from frequent itemsets
from mlxtend.frequent_patterns import association_rules
Rule generation is a common task in the mining of frequent patterns. An association rule is an implication expression of the form $X \rightarrow Y$, where $X$ and $Y$ are disjoint itemsets [1]. A more concrete example based on consumer behaviour would be $\{Diapers\} \rightarrow \{Beer\}$ suggesting that people who buy diapers are also likely to buy beer. To evaluate the "interest" of such an association rule, different metrics have been developed. The current implementation make use of the confidence
and lift
metrics.
[1] Tan, Steinbach, Kumar. Introduction to Data Mining. Pearson New International Edition. Harlow: Pearson Education Ltd., 2014. (pp. 327-414).
The generate_rules
takes dataframes of frequent itemsets as produced by the apriori
function in mlxtend.association. To demonstrate the usage of the generate_rules
method, we first create a pandas DataFrame
of frequent itemsets as generated by the apriori
function:
import pandas as pd
from mlxtend.preprocessing import OnehotTransactions
from mlxtend.frequent_patterns import apriori
dataset = [['Milk', 'Onion', 'Nutmeg', 'Kidney Beans', 'Eggs', 'Yogurt'],
['Dill', 'Onion', 'Nutmeg', 'Kidney Beans', 'Eggs', 'Yogurt'],
['Milk', 'Apple', 'Kidney Beans', 'Eggs'],
['Milk', 'Unicorn', 'Corn', 'Kidney Beans', 'Yogurt'],
['Corn', 'Onion', 'Onion', 'Kidney Beans', 'Ice cream', 'Eggs']]
oht = OnehotTransactions()
oht_ary = oht.fit(dataset).transform(dataset)
df = pd.DataFrame(oht_ary, columns=oht.columns_)
frequent_itemsets = apriori(df, min_support=0.6, use_colnames=True)
frequent_itemsets
support | itemsets | |
---|---|---|
0 | 0.8 | [Eggs] |
1 | 1.0 | [Kidney Beans] |
2 | 0.6 | [Milk] |
3 | 0.6 | [Onion] |
4 | 0.6 | [Yogurt] |
5 | 0.8 | [Eggs, Kidney Beans] |
6 | 0.6 | [Eggs, Onion] |
7 | 0.6 | [Kidney Beans, Milk] |
8 | 0.6 | [Kidney Beans, Onion] |
9 | 0.6 | [Kidney Beans, Yogurt] |
10 | 0.6 | [Eggs, Kidney Beans, Onion] |
The generate_rules()
function allows you to (1) specify your metric of interest and (2) the according threshold. Currently implemented measures are confidence and lift. Let's say you are interesting in rules derived from the frequent itemsets only if the level of confidence is above the 90 percent threshold (min_threshold=0.9
):
from mlxtend.frequent_patterns import association_rules
association_rules(frequent_itemsets, metric="confidence", min_threshold=0.9)
antecedants | consequents | support | confidence | lift | |
---|---|---|---|---|---|
0 | (Eggs) | (Kidney Beans) | 0.8 | 1.0 | 1.00 |
1 | (Onion) | (Eggs) | 0.6 | 1.0 | 1.25 |
2 | (Milk) | (Kidney Beans) | 0.6 | 1.0 | 1.00 |
3 | (Onion) | (Kidney Beans) | 0.6 | 1.0 | 1.00 |
4 | (Yogurt) | (Kidney Beans) | 0.6 | 1.0 | 1.00 |
5 | (Eggs, Onion) | (Kidney Beans) | 0.6 | 1.0 | 1.00 |
6 | (Kidney Beans, Onion) | (Eggs) | 0.6 | 1.0 | 1.25 |
7 | (Onion) | (Eggs, Kidney Beans) | 0.6 | 1.0 | 1.25 |
If you are interested in rules fulfilling a different interest metric, you can simply adjust the parameters. E.g. if you are interested only in rules that have a lift score of >= 1.2, you would do the following:
rules = association_rules(frequent_itemsets, metric="lift", min_threshold=1.2)
rules
antecedants | consequents | support | confidence | lift | |
---|---|---|---|---|---|
0 | (Eggs) | (Onion) | 0.8 | 0.75 | 1.25 |
1 | (Onion) | (Eggs) | 0.6 | 1.00 | 1.25 |
2 | (Eggs, Kidney Beans) | (Onion) | 0.8 | 0.75 | 1.25 |
3 | (Kidney Beans, Onion) | (Eggs) | 0.6 | 1.00 | 1.25 |
4 | (Eggs) | (Kidney Beans, Onion) | 0.8 | 0.75 | 1.25 |
5 | (Onion) | (Eggs, Kidney Beans) | 0.6 | 1.00 | 1.25 |
Pandas DataFrames
make it easy to filter the results further. Let's say we are ony interested in rules that satisfy the following criteria:
We could compute the antecedent length as follows:
rules["antecedant_len"] = rules["antecedants"].apply(lambda x: len(x))
rules
antecedants | consequents | support | confidence | lift | antecedant_len | |
---|---|---|---|---|---|---|
0 | (Eggs) | (Onion) | 0.8 | 0.75 | 1.25 | 1 |
1 | (Onion) | (Eggs) | 0.6 | 1.00 | 1.25 | 1 |
2 | (Eggs, Kidney Beans) | (Onion) | 0.8 | 0.75 | 1.25 | 2 |
3 | (Kidney Beans, Onion) | (Eggs) | 0.6 | 1.00 | 1.25 | 2 |
4 | (Eggs) | (Kidney Beans, Onion) | 0.8 | 0.75 | 1.25 | 1 |
5 | (Onion) | (Eggs, Kidney Beans) | 0.6 | 1.00 | 1.25 | 1 |
Then, we can use pandas' selection syntax as shown below:
rules[ (rules['antecedant_len'] >= 2) &
(rules['confidence'] > 0.75) &
(rules['lift'] > 1.2) ]
antecedants | consequents | support | confidence | lift | antecedant_len | |
---|---|---|---|---|---|---|
3 | (Kidney Beans, Onion) | (Eggs) | 0.6 | 1.0 | 1.25 | 2 |
with open('../../api_modules/mlxtend.frequent_patterns/association_rules.md', 'r') as f:
print(f.read())
## association_rules *association_rules(df, metric='confidence', min_threshold=0.8)* Generates a DataFrame of association rules including the metrics 'score', 'confidence', and 'lift' **Parameters** - `df` : pandas DataFrame pandas DataFrame of frequent itemsets with columns ['support', 'itemsets'] - `metric` : string (default: 'confidence') Metric to evaluate if a rule is of interest. Supported metrics are 'confidence' and 'lift' - `min_threshold` : float (default: 0.8) Minimal threshold for the evaluation metric to decide whether a candidate rule is of interest. **Returns** pandas DataFrame with columns ['antecedants', 'consequents', 'support', 'lift', 'confidence'] of all rules for which metric(rule) >= min_threshold.