Package: kiwi-apriori
aprioriPip installable association analysis package.Our datasets is a list of transactions, individual people that 'purchased'
items together. We are trying to find things that are associated with each other.Installationpipinstallkiwi-aprioriIt seems someone already hasapriorion Twine. The package will be used byimport apriori.Quick exampleThis dataset looks at the purchases of 4 customers:transactions=[['fish','white wine','cheese','bread'],['beer','nachos','cheese','peanuts'],['white wine','cheese'],['white wine','cheese','bread']]We are interested in which items are associated with one another. It seems that people that
bought white wine also bought cheese. Here are some "association rules" we find:If you buy ...... we think you'd likeSupportConfidenceLiftwhite winebread0.50000.66671.3333breadwhite wine0.50001.00001.3333white winebread AND cheese0.50000.66671.3333breadcheese AND white wine0.50001.00001.3333cheese AND white winebread0.50000.66671.3333bread AND cheesewhite wine0.50001.00001.3333Let's look at the first two rows to illustrate support, confidence, and lift.Support: Fractions of transactions containing these items. i.e. the probability a randomly chosen transaction contains all the items.The first two rows are about{white wine}and{bread}. Half of our transactions contain both these items (transactions[0]amdtransactions[3])Order doesn't matter, the support of{white wine}-->{bread}and{bread}-->{white wine}are the sameCan be applied to single items (e.g. support for{white wine}is 0.75, as 3/4 transactions contain white wine)Confidence of A --> B: Fraction of transactions containing A that also contain B. i.e. the probability that a randomly chosen transaction containing A also contains B2 of the 3 transactions containing{white wine}also contain{bread}, so confidence ofwhite wine -> breadis 0.6672 of the 2 transactions containing{bread}also contain{white wine}, so confidence ofbread -> white wineis 1.000Can be calculated assupport(A AND B)/support(A)Lift of A --> B: The support of A AND B divided by the support of A and the support of BMeasures the amount of information you get knowing AKnowing the lift of white wine to bread is 1.3333 tells us that someone buying white wine is 1.3333 times more likely than the average person to buy bread as well.If A and B were independent, Lift would be 1If the lift is less than one, that tells us someone islesslikely than the average person to buy the other item.QuickstartTaken fromexample.pyimportapriorisample_transactions=[['fish','white wine','cheese','bread'],['beer','nachos','cheese','peanuts'],['white wine','cheese'],['white wine','cheese','bread']]forruleinapriori.generate_rules(sample_transactions,min_support=0.5):msg=(f'{rule.format_rule():20s}\t\t'f'(support={rule.support:0.4f}, confidence={rule.confidence:0.4f}, lift={rule.lift:0.4f})')print(msg)Output:{whitewine}--->{cheese}(support=0.7500,confidence=1.0000,lift=1.0000){cheese}--->{whitewine}(support=0.7500,confidence=0.7500,lift=1.0000){whitewine}--->{bread}(support=0.5000,confidence=0.6667,lift=1.3333){bread}--->{whitewine}(support=0.5000,confidence=1.0000,lift=1.3333){cheese}--->{bread}(support=0.5000,confidence=0.5000,lift=1.0000){bread}--->{cheese}(support=0.5000,confidence=1.0000,lift=1.0000){whitewine}--->{bread,cheese}(support=0.5000,confidence=0.6667,lift=1.3333){cheese}--->{bread,whitewine}(support=0.5000,confidence=0.5000,lift=1.0000){bread}--->{cheese,whitewine}(support=0.5000,confidence=1.0000,lift=1.3333){cheese,whitewine}--->{bread}(support=0.5000,confidence=0.6667,lift=1.3333){bread,whitewine}--->{cheese}(support=0.5000,confidence=1.0000,lift=1.0000){bread,cheese}--->{whitewine}(support=0.5000,confidence=1.0000,lift=1.3333)Alternative approachesThis is one approach to determining "this-goes-with-that". Here are comparisons to other alternativesGraph / Network modelsWe could model each item as a node in a graph, and put a weighted edge between items that appear in the same transaction.
In our example, "white wine" and "cheese" would both be nodes, and be joined by a weight of 3. We could then do a community
detection algorithm to find things that are associated with one another, or look for hubs (items that are associated with a
lot of different purchases).ProsAlgorithm is a lot faster (only deal with $N$ items, and the $O(N^2)$ relationships between items, not all possible subsets of items).ConsEdges are formed between pairs of nodes, so this approach tells you about pairs of items that are associated.
It doesn't find cases like "everyone who bought all three of A, B, and C also bought D".Matrix FactorizationWe are focusing on items that are associated with each other; we can score them by one-hot encoding the different
transactions and finding the dot product between pairs of items. This score will be the number of transactions both
items coexist in.ProsA lot fasterCan be trained online / streamingLots of supportConsPopular items have higher scores (can mitigate this using cosine distance)Limited to comparing pairs of items (although you can try and make a lower dimensional representation and see which
items have a similar representation in this lower dimensional space)Max-MinerUnlike the other two algorithms, this one is specifically designed for this problem. It deals with sets of items, not
just pairs of items. It also deals with the drawback of this algorithm being slow.ProsA lot faster than aprioriDeals with sets of items, rather than pairs of itemsConsFinds most, but not all, association rulesOther applicationsAlthough the examples have all been framed in terms of items bought in transactions with one another, this algorithm
can be used to find what sets of things "belong together", similar to clustering. Clustering works by looking
at features of individual points, and grouping items with similar features together. Association analysis doesn't give
the items any individual features, but clusters on the similarities of the relationships.Other examples:Finding voting patterns (if you vote for A, B, and C, you are likely to vote for D). Transactions are representatives, items are bills with "yea" votes.Finding associated medical conditions that may have an underlying root causes. Transactions are patients, items are treatments or symptoms.Finding outfits. Transactions are things that were worn together, items are individual pieces of clothing. (This is an interesting problem, as two shirts have more
in common than a shirt and trousers based on features, but you wouldn't wear two shirts and no trousers).ReferencesWikipedia has great psuedo-code on theapriori algorithmThere is another pip installable package,apyroriandeffecient apriori