1. 程式人生 > >利用mlxtend進行資料關聯分析

利用mlxtend進行資料關聯分析

今天本該是個剁手的日子,只可惜餘額不足高攀不起那臺i7-8565,只有再寫一篇文章聊以慰籍~~

前言:之前很少做關於資料關聯分析的題,而當初學關聯分析時也是自己寫程式碼來實現底層轉換與運算,粗略一點的整體程式碼量也達到150行左右,所以沒有高階的開源工具使用是很費時間的,由此阻礙了一顆想學習的心。後來遇到相關問題便Google了一些解決辦法,其中有一個整合很優秀,使用也很方便的GitHub開源專案,也是本篇文章的重點——

首先簡單介紹一下關聯分析的三個相關知識點:

頻繁項集:

頻繁項集是指那些經常出現在一起的物品,例如上圖的{葡萄酒、尿布、豆奶},從上面的資料集中也可以找到尿布->葡萄酒的關聯規則,這意味著有人買了尿布,那很有可能他也會購買葡萄酒。那如何定義和表示頻繁項集和關聯規則呢?這裡引入支援度和可信度(置信度)。

支援度:

支援度:一個項集的支援度被定義為資料集中包含該項集的記錄所佔的比例,上圖中,豆奶的支援度為4/5,(豆奶、尿布)為3/5。支援度是針對項集來說的,因此可以定義一個最小支援度,只保留最小支援度的項集。

置信度:

可信度(置信度):針對如{尿布}->{葡萄酒}這樣的關聯規則來定義的。計算為 支援度{尿布,葡萄酒}/支援度{尿布},尿布,{葡萄酒}的支援度為3/5,{尿布}的支援度為4/5,所以“尿布->葡萄酒”的可行度為3/4=0.75,這意味著尿布的記錄中,我們的規則有75%都適用(買了尿布的顧客有75%還會買葡萄酒)。

上面簡單介紹三個基本概念,下面我們就來利用 mlxtend 完整簡單的實現上面購物表單的關聯分析問題。

關聯分析示例:

首先建立資料:

轉換為DataFrame格式,然後再教一個後續轉換回來的方法。

import pandas as pd

shopping_list = [['豆奶','萵苣'],
	        ['萵苣','尿布','葡萄酒','甜菜'],
	        ['豆奶','尿布','葡萄酒','橙汁'],
	        ['萵苣','豆奶','尿布','葡萄酒'],
	        ['萵苣','豆奶','尿布','橙汁']]

shopping_df = pd.DataFrame(shopping_list)

轉換資料列表:

接著轉換DataFrame資料為包含資料的列表。(由於我們接觸到的可能是DataFrame資料所以這裡介紹了兩個轉換為上面列表的方法)

# df_arr = shopping_df.stack().groupby(level=0).apply(list).tolist()	# 方法一

def deal(data):
	return data.dropna().tolist()
df_arr = shopping_df.apply(deal,axis=1).tolist()		        # 方法二

轉換為模型可接受資料:

由於mlxtend的模型只接受特定的資料格式。(TransactionEncoder類似於獨熱編碼,每個值轉換為一個唯一的bool值)

from mlxtend.preprocessing import TransactionEncoder	# 傳入模型的資料需要滿足特定的格式,可以用這種方法來轉換為bool值,也可以用函式轉換為0、1

te = TransactionEncoder()	# 定義模型
df_tf = te.fit_transform(df_arr)
# df_01 = df_tf.astype('int')			# 將 True、False 轉換為 0、1 # 官方給的其它方法
# df_name = te.inverse_transform(df_tf)		# 將編碼值再次轉化為原來的商品名
df = pd.DataFrame(df_tf,columns=te.columns_)

求頻繁項集:

匯入apriori方法設定最小支援度min_support=0.05求頻繁項集,還能選擇出長度大於x的頻繁項集。

from mlxtend.frequent_patterns import apriori

frequent_itemsets = apriori(df,min_support=0.05,use_colnames=True)	# use_colnames=True表示使用元素名字,預設的False使用列名代表元素
# frequent_itemsets = apriori(df,min_support=0.05)
frequent_itemsets.sort_values(by='support',ascending=False,inplace=True)	# 頻繁項集可以按支援度排序
# print(frequent_itemsets[frequent_itemsets.itemsets.apply(lambda x: len(x)) >= 2])  # 選擇長度 >=2 的頻繁項集

求關聯規則:

匯入association_rules方法判斷'confidence'大於0.9,求關聯規則。

from mlxtend.frequent_patterns import association_rules

association_rule = association_rules(frequent_itemsets,metric='confidence',min_threshold=0.9)	# metric可以有很多的度量選項,返回的表列名都可以作為引數
association_rule.sort_values(by='leverage',ascending=False,inplace=True)    #關聯規則可以按leverage排序
# print(association_rule)

下面便得到了上表中滿足設定條件的關聯規則

mlxtend使用了 DataFrame 方式來描述關聯規則,而不是 —> 符號,其中:

  • antecedents:規則先導項

  • consequents:規則後繼項

  • antecedent support:規則先導項支援度

  • consequent support:規則後繼項支援度

  • support:規則支援度 (前項後項並集的支援度)

  • confidence:規則置信度 (規則置信度:規則支援度support / 規則先導項)

  • lift:規則提升度,表示含有先導項條件下同時含有後繼項的概率,與後繼項總體發生的概率之比。

  • leverage:規則槓桿率,表示當先導項與後繼項獨立分佈時,先導項與後繼項一起出現的次數比預期多多少。

  • conviction:規則確信度,與提升度類似,但用差值表示。

提升度計算公式:

lift(X\rightarrow Y) = \frac{support(X\bigcap Y)}{support(X)*support(Y)}

其中,當先導項與後繼項獨立分佈時,值為 1,提升度越大,表示先導項與後繼項的關聯性越強。

槓桿率計算公式:

leverage(X\rightarrow Y) = support(X\rightarrow Y)-support(X)*support(Y)

確信度計算公式:

conviction(X\rightarrow Y) = \frac{1-support(Y)}{1-confidence(X\rightarrow Y)}

確信度值越大,則先導項與後繼項的關聯性越強。 以上三個值都是越大關聯強度也就越大。