关联分析是一种在大型数据库中发现变量之间的有意义的关系的方法。这种关系表现为两种形式:频繁项集和关联规则。关联分析的目的是利用一些度量来识别数据库中的强规则。数学定义:
假设 I = { I 1 , I 2 , … , I m } {\displaystyle I=\{I_{1},I_{2},\ldots ,I_{m}\}} I={I1,I2,…,Im}是项的集合。给定一个交易数据库 D = { t 1 , t 2 , … , t n } {\displaystyle D=\{t_{1},t_{2},\ldots ,t_{n}\}} D={t1,t2,…,tn},其中每个事务 t t t是 I I I的非空子集,即 t ⊆ I {\displaystyle t\subseteq I} t⊆I,每一个交易都与一个唯一的标识符TID(Transaction ID)对应。关联规则是形如 X ⇒ Y {\displaystyle X\Rightarrow Y} X⇒Y的蕴涵式,其中 X , Y ⊆ I {\displaystyle X,Y\subseteq I} X,Y⊆I且 X ∩ Y = ∅ {\displaystyle X\cap Y=\emptyset } X∩Y=∅, X {\displaystyle X} X和 Y {\displaystyle Y} Y分别称为关联规则的先导(antecedent或left-hand-side, LHS)和后继(consequent或right-hand-side, RHS) 。关联规则 X ⇒ Y {\displaystyle X\Rightarrow Y} X⇒Y在 D D D中的支持度(support)是 D D D中事务包含 X ∪ Y {\displaystyle X\cup Y} X∪Y的百分比,即概率 P ( X ∪ Y ) {\displaystyle P(X\cup Y)} P(X∪Y);置信度(confidence)是包含 X X X的事务中同时包含 Y Y Y的百分比,即条件概率 P ( Y ∣ X ) {\displaystyle P\left(Y|X\right)} P(Y∣X)。如果同时满足最小支持度阈值和最小置信度阈值,则认为关联规则是有趣的。这些阈值由用户或者专家设定。(引自wikipedia)
为了说明概念,我们以购物篮分析为例,即假设我们的数据是由若干购物清单构成的列表,每个购物清单由若干商品组成:
d a t a = [ [ i t e m 11 , i t e m 12 , . . . ] , [ i t e m 21 , i t e m 22 , . . . ] , [ i t e m 31 , i t e m 32 , . . . ] , . . . ] data = [[item_{11}, item_{12}, ...], [item_{21}, item_{22}, ...], [item_{31}, item_{32}, ...], ...] data=[[item11,item12,...],[item21,item22,...],[item31,item32,...],...]
先验算法用于搜索数据库中的频繁项集,其核心思想为:如果一个项集是非频繁项集,那么它的所有超集也是非频繁项集,从而达到剪枝的目的。算法流程:
参考刘建平Pinard的博客
mlxtend包已经封装了以上算法,我们只要安装这个包就可以对数据进行关联分析了
命令行执行pip install mlxtend
这个类用于对我们的数据进行编码;由于源数据一般是字符串列表,我们需要转换为multi-hot的编码形式才能进一步处理,用法见示例
Apriori算法,它有以下参数:
min_support
:最小支持度,默认0.5use_colnames
:是否显示项的原始名称,默认为False,此时输出的项是编码后的数字max_len
:频繁项集最大长度,默认为False ,即生成所有频繁项集verbose
:控制迭代过程中的输出,默认为0low_memory
:是否以低内存占用的模式运行算法,默认为False;若设为True将导致算法耗时变长,慎用FP-growth算法,它有以下参数:
min_support
:最小支持度,默认0.5use_colnames
:是否显示项的原始名称,默认为False,此时输出的项是编码后的数字max_len
:频繁项集最大长度,默认为False ,即生成所有频繁项集verbose
:控制迭代过程中的输出,默认为0from mlxtend.frequent_patterns import association_rules
from mlxtend.frequent_patterns import apriori
import pandas as pd
from mlxtend.preprocessing import TransactionEncoder
purchases = [['Milk', 'Broccoli', 'Sauce', 'Beef', 'Eggs', 'Yogurt'],
['Wine', 'Broccoli', 'Sauce', 'Beef', 'Eggs', 'Yogurt'],
['Milk', 'Apple', 'Beef', 'Eggs'],
['Milk', 'Fish', 'Corn', 'Beef', 'Yogurt'],
['Corn', 'Broccoli', 'Broccoli', 'Beef', 'Banana', 'Eggs']]
te = TransactionEncoder()
te_array = te.fit(purchases).transform(purchases)
df = pd.DataFrame(te_array, columns=te.columns_)
print(df)
# 采用apriori算法生成频繁项集
frequent_itemsets = apriori(df, min_support=0.6, use_colnames=True)
print(frequent_itemsets)
frequent_itemsets['length'] = frequent_itemsets['itemsets'].apply(lambda x: len(x))
rules = association_rules(frequent_itemsets, metric='lift', min_threshold=1)
# 选取提升度大于1且置信度大于0.5的关联规则
print(rules[(rules['lift'] > 1) & (rules['confidence'] > 0.5)])
当数据集中商品种类很多而交易很少时,可以使用稀疏矩阵存储交易信息以节省内存:
import pandas as pd
from mlxtend.preprocessing import TransactionEncoder
from mlxtend.frequent_patterns import apriori
te = TransactionEncoder()
oht_ary = te.fit(dataset).transform(dataset, sparse=True)
sparse_df = pd.DataFrame.sparse.from_spmatrix(oht_ary, columns=te.columns_)
apriori(sparse_df, min_support=0.6, use_colnames=True, verbose=1)