association rules algorithm recommender systems with python
from apyori import apriori from apyori import load_transactions class Recommender(): def __init__(self, inputFile): self.AssociationRulesDictionary = {} # holds final output self.dataFile = inputFile # input datafile in csv form self.association_rules = [] # holds output from Apriori algo def computeRules(self): """ Computes all association rules. :return: """ with open(self.dataFile ) as fileObj: transactions = list(load_transactions(fileObj, delimiter=",")) # remove empty strings if any transactions_filtered = [] for li in transactions: li = list(filter(None, li)) transactions_filtered.append(li) # Following line does all computations # lift > 1 shows that there is a positive correlation within the itemset, i.e., items in the # itemset, are more likely to be bought together. # lift < 1 shows that there is a negative correlation within the itemset, i.e., items in the # itemset, are unlikely to be bought together. # hence we have set min_lift=1.0 to ignore all rules with lift < 1.0 self.association_rules = apriori(transactions_filtered, min_support=0.01, min_confidence=0.01, min_lift=1.0, max_length=None) def extractRules(self): for item in self.association_rules: # first index of the inner list # Contains base item and add item if len(item[0]) < 2: continue for k in item[2]: baseItemList = list(k[0]) # if base item set is empty then go to the next record. if not baseItemList: continue # sort the baseItemList before adding it as a key to the AssociationRules dictionary baseItemList.sort() baseItemList_key = tuple(baseItemList) if baseItemList_key not in self.AssociationRulesDictionary.keys(): self.AssociationRulesDictionary[baseItemList_key] = [] self.AssociationRulesDictionary[baseItemList_key].append((list(k[1]), k[3])) # if something goes wrong, then use the following print block to print values #print("Base item: ", baseItemList_key) #print("Target item: ", list(k[1])) #print("Confidence: " + str(k[2])) #print("Lift: " + str(k[3])) # sort the rules in descending order of lift values. for ruleList in self.AssociationRulesDictionary: self.AssociationRulesDictionary[ruleList].sort(key=lambda x: x[1], reverse=True) def recommend(self, itemList, Num=1): """ itemList is a list of items selected by user Num is total recommendations required. :param item: :return: """ # convert itemList to itemTuple as our dictionary key is a sorted tuple itemList.sort() itemTuple = tuple(itemList) if itemTuple not in self.AssociationRulesDictionary.keys(): return [] return self.AssociationRulesDictionary[itemTuple][:Num] def studyRules(self): """ This is a template method for computation and rule extraction. :return: """ self.computeRules() self.extractRules() def showDeals(self, itemList, Num=1): """ we are converting the recommendations into deals. The lift value is used to calculate discount percentage discount percentage = 10 * lift itemList is a list of items selected by user Num is total deals required. :return: """ recommendations = self.recommend(itemList, Num) for item in recommendations: print( "If you buy ", item[0], " along with ", itemList, " then you will get ", round((item[1] * 10), 2), \ "% discount on total cost!!" ) Alexa = Recommender("store_data.csv") Alexa.studyRules() print (Alexa.recommend(['red wine'], 1)) Alexa.showDeals(['red wine'], 2)