超市購物小票關聯關係
阿新 • • 發佈:2020-10-12
需求:對超市購物小票資訊進行分析,得到商品的關聯關係,從而向用戶進行推薦,提升營業額。
資料:BreadBasket_DMS.csv
所用演算法:apriori
完整程式碼:
# 表格容器,對錶格進行處理 import pandas as pd import time # 資料載入(得到DataFrame) data = pd.read_csv('./BreadBasket_DMS.csv') # 統一小寫(Item列的資料全部小寫) data['Item'] = data['Item'].str.lower() # 去掉none項(通過拿到具體的行索引來刪除掉資料) data = data.drop(data[data.Item == 'none'].index) # 採用efficient_apriori工具包 def rule1(): from efficient_apriori import apriori # 當前時間(此時主要程式碼開始) start = time.time() # 得到一維陣列orders_series(是一個類似於一維陣列的series物件),並且將Transaction作為index, value為Item取值 # 然後就出現了同一個索引對應多個值 # orders_series型別是pandas.core.series.Series orders_series = data.set_index('Transaction')['Item'] # print(orders_series) # print("=============列印測試==============") # print(orders_series.items()) # print("=============列印測試==============") # 將資料集轉換成apriori模型需要的形式 # 將資料集進行格式轉換(建立列表,等下里面放集合(集合裡面資料不重複)) transactions = [] temp_index = 0 for i, v inorders_series.items(): if i != temp_index: # set() 函式建立一個無序不重複元素集(這樣可以保證訂單裡面的物品不重複,即我只關心你買了什麼,不關心你相同物品買了多少) temp_set = set() temp_index = i temp_set.add(v) transactions.append(temp_set) else: # 因為是set集合,所以重複的物品不會新增進來 temp_set.add(v) # 挖掘頻繁項集和頻繁規則(同時定義閾值min_support和min_confidence) # transactions包含了所有訂單資訊,但是同一個訂單中刪除了重複物品(相同物品只保留一個) itemsets, rules = apriori(transactions, min_support=0.02, min_confidence=0.5) print('頻繁項集:', itemsets) print('關聯規則:', rules) # 當前時間(此時主要程式碼結束) end = time.time() print("用時:", end - start) # 使>=1的數值全部變為1,目的是隻考慮你買了啥,不考慮同一件商品你買了多少 def encode_units(x): if x <= 0: return 0 if x >= 1: return 1 # 這裡用到的模型是機器學習擴充套件包 # 採用mlxtend.frequent_patterns工具包 def rule2(): from mlxtend.frequent_patterns import apriori from mlxtend.frequent_patterns import association_rules pd.options.display.max_columns = 100 # 開始時間 start = time.time() # stack()即“堆疊”,作用是將列旋轉到行(預設操作最裡層資料) # unstack()即stack()的反操作,將行旋轉到列(預設操作最裡層資料) # reset_index()把索引重置(從0開始) 把原來的索引刪掉 # .fillna(0),填充缺失資料(這裡用常數0填充NaN) # set_index('Transaction') 索引還是用Transaction # 按照['Transaction', 'Item']進行分組(同一個訂單、相同的商品分到一組),然後對['Item']列進行後續資料處理 hot_encoded_df = data.groupby(['Transaction', 'Item'])['Item'].count().unstack().reset_index().fillna( 0).set_index('Transaction') # print(hot_encoded_df) # print("=============列印測試(開始)==============") # print() # print("=============列印測試(結束)==============") # 先計算頻繁項集、再計算關聯規則 # 將自定義函式encode_units作用於DataFrame的所有元素(使>=1的數值全部變為1,目的是隻考慮你買了啥,不考慮同一件商品你買了多少) hot_encoded_df = hot_encoded_df.applymap(encode_units) # 設定資料集、最小支援度、是否使用列名(因為是熱編碼資料,所以列名就是商品名) # 獨熱編碼(one-hot編碼) frequent_itemsets = apriori(hot_encoded_df, min_support=0.02, use_colnames=True) # metric(判定標準,這裡設定判定標準為lift提升度),min_threshold(metric引數的閾值) # 因為下面設定lift>=1了,所以這裡的0.5就沒有作用了(其實lift>1才有意義) rules = association_rules(frequent_itemsets, metric="lift", min_threshold=0.5) print("頻繁項集:", frequent_itemsets) # 進一步篩選出提升度lift>=1和置信度>=0.5的關聯規則 print("關聯規則:", rules[(rules['lift'] >= 1) & (rules['confidence'] >= 0.5)]) # print("=============列印測試==============") # print(rules['lift']) # print("=============列印測試==============") # 結束時間 end = time.time() print("用時:", end - start) # 兩個規則分別執行 # rule1() print('-' * 100) rule2()