python 关联规则 实例_利用python进行课程关联(关联规则)

关联规则:在数据集中找出各项之间的关联,例如餐馆点菜,客户点了红烧肉,那么同时也点宫保鸡丁的概率有多大,能否引出一天关联规则,红烧肉=>宫保鸡丁,红烧肉为前项,宫保鸡丁为后项。

关联规则算法:

1.Apriori:关联规则最常用的也是最经典的挖掘频繁项集的算法,其核心思想是通过连接产生候选项及其支持度然后通过剪枝生成频繁项集。

2.FP-Tree:针对Apriori算法的固有的多次扫描事务处理集的缺陷,提出的不产生候选频繁项集的方法,Apriori和TP-Tree都是寻找频繁项集的算法。

3.Ecalt : Ecalt算法是一种深度优先算法,采用垂直数据表示形式,在概念和理论的基础上利用基于前缀的等价关系将搜索空间划分为较小的子空间。

4.灰色关联法:分析和确定各因素之间的影响程度或是若干个子因素(子序列)对主因素(母序列)的贡献度而进行的一种分析方法。

本文主要讲解Apriori算法,其他算法有待更新。。

本文前提:为产品部提供产品关联结果,对用户消费特征进行分析,便于后期产品迭代和促销。

概念

支持度:表示同时购买X、Y的订单数占总订单数(研究关联规则的“长表”中的所有购买的产品的订单数)的比例。如果用P(X)表示购买X的订单比例,其他产品类推,那么

置信度:表示购买X的订单中同时购买Y的比例。公式表达

提升度:提升度反映了关联规则中的X重点内容与Y的相关性;

提升度 >1 且越高表明正相关性越高;

提升度 <1 且越低表明负相关性越高;

提升度 =1 表明没有相关性。

举例理解上面公式,一共有6个人的购买清单,{a,b,c},{b,c,d},{a,b} , {a,c},{c},{d}

support(a->b)=P(ab)=P(a)P(b|a)=3/6*2/3=1/3

Confidence(a->b)=P(b|a)=2/3

Lift(a->b)=Con(a->b)/P(b)=(2/3)/(2/4)=4/3,如若b在a中的占比比b在所有事物中的占比小,说明a对b有抑制作用,及<1(提升度小于1,负相关性,如果样本足够,则可忽略提升度)反之,则大于1。

强规则:最小支持度是用户或专家定义的衡量支持度的一个阈值,表示项目集在统计意义上的最低重要性;最小支持度是用户或专家定义的衡量置信度的一个阈值,表示关联规则的最低可靠性。同时满足最小支持度阈值和最小置信度阈值的规则称作强规则。

项集:项集是项的集合。包含k个项的项集称为k项集,如集合{牛奶,麦片,糖}是一个3项集。项集的出现频率是所有包含项集的事物的计数,又称作绝对支持度或支持度计数。如果项集I的相对支持度满足预定义的最小支持度阈值,则I是频繁项集。频繁k项集通常记作k。

Apriori算法过程

Apriori的性质是“频繁项集的所有非空子集也必须是频繁项集。根据该性质可以得出:向不是频繁项集I的项集中添加事物A,新的项集I U A 一定也不是频繁项集”

具体实现原理:

1.找出所有的频繁项集(支持度必须大于等于给定的最小支持度阈值),在这个过程中连接步和剪枝步相互融合,最终得到最大频繁项集

equation?tex=L_%7Bk%7D

连接步:

连接步的目的是找到K项集。对给定的最小支持度阈值,分别对1项候选集

equation?tex=C_%7B1%7D ,剔除小于该阈值的项集得到1项频繁项集

equation?tex=L_%7B1%7D ;下一步由

equation?tex=L_%7B1%7D 自身连接(意思为

equation?tex=L_%7B1%7D 中各项与各项两两匹配)产生2项候选集

equation?tex=C_%7B2%7D ,保留

equation?tex=C_%7B2%7D 中满足约束条件的项集得到2项频繁项集,记为

equation?tex=L_%7B2%7D ;再下一步由

equation?tex=L_%7B2%7D

equation?tex=L_%7B3%7D 连接产生3项候选集

equation?tex=C_%7B3%7D ,保留

equation?tex=C_%7B2%7D 中满足约束条件的项集得到3项频繁项集,记为

equation?tex=L_%7B3%7D .......这样循环下去,得到最大频繁项集

equation?tex=L_%7Bk%7D

剪枝步:

剪枝步紧接着连接步,在产生候选项

equation?tex=C_%7Bk%7D 的过程中起到减小搜索空间的目的。由于

equation?tex=C_%7Bk%7D

equation?tex=L_%7Bk-1%7D

equation?tex=L_%7B1%7D 连接产生的,根据Apriori的性质频繁项集的所有非空子集也必须是频繁项集,所以不满足该性质的项集不会存在于

equation?tex=C_%7Bk%7D 中,该过程就是剪枝。

实例操作:

目的:为了找出课程的关联规则,查看关联的自带小课,助于产品部的页面排版。

数据源:抽取2万用户的购物订单,(购物订单内的物品购买日期跨度为1个月,不同于其他频繁购买的生活用品,时间跨度可适量加大,每个样本的物品不可重复)部分数据如下:

过程:

1)扫描所有事务(所有样本),事务中的每一项(每一门课程)都在候选的“1项集”

equation?tex=C_%7B1%7D 中,计算每一项的支持度。

2)计算出来的支持度,去掉小于阈值支持度的那一项,得出‘1项频繁项集’

equation?tex=L_%7B1%7D

3)

equation?tex=L_%7B1%7D 再与每一项课程连接,计算每一项集的支持度,去掉小于阈值支持度的那一项集,得‘2项频繁项集’

equation?tex=L_%7B2%7D

4)循环第3步骤直到计算出最大频繁项集(频繁项集的非空子集都为频繁项集)

代码:

1.导入数据源

from __future__ import print_function

import pandas as pd

from apriori import * #导入编写好的函数(网上有相应的模块)

data = pd.read_excel('...../data/数据源.xlsx', header = None)

2.数据做简单变换

ct = lambda x : pd.Series(1, index = x[pd.notnull(x)]) #转换0-1矩阵的过渡函数

b = map(ct, data.as_matrix()) #用map方式执行,map输出的结果为iterators,需要list转换一下输出

data = pd.DataFrame(list(b)).fillna(0) #实现矩阵转换,空值用0填充menu_orders

3.计算支持度和置信度

support = 0.2 #最小支持度

confidence = 0.5 #最小置信度

ms = '---' #连接符,默认'--',用来区分不同元素,如A--B。需要保证原始表格中不含有该字符

find_rule(data, support, confidence, ms).to_excel('...../data/结果.xlsx) #保存结果

以上有何find_rule函数,这部分源代码如下

#-*- coding: utf-8 -*-

from __future__ import print_function

import pandas as pd

#自定义连接函数,用于实现L_{k-1}到C_k的连接

def connect_string(x, ms):

x = list(map(lambda i:sorted(i.split(ms)), x))

l = len(x[0])

r = []

for i in range(len(x)):

for j in range(i,len(x)):

if x[i][:l-1] == x[j][:l-1] and x[i][l-1] != x[j][l-1]:

r.append(x[i][:l-1]+sorted([x[j][l-1],x[i][l-1]]))

return r

#寻找关联规则的函数

def find_rule(d, support, confidence, ms = u'--'):

result = pd.DataFrame(index=['support', 'confidence']) #定义输出结果

support_series = 1.0*d.sum()/len(d) #支持度序列

column = list(support_series[support_series > support].index) #初步根据支持度筛选

k = 0

while len(column) > 1:

k = k+1

print(u'\n正在进行第%s次搜索...' %k)

column = connect_string(column, ms)

print(u'数目:%s...' %len(column))

sf = lambda i: d[i].prod(axis=1, numeric_only = True) #新一批支持度的计算函数

#创建连接数据,这一步耗时、耗内存最严重。当数据集较大时,可以考虑并行运算优化。

d_2 = pd.DataFrame(list(map(sf,column)), index = [ms.join(i) for i in column]).T

support_series_2 = 1.0*d_2[[ms.join(i) for i in column]].sum()/len(d) #计算连接后的支持度

column = list(support_series_2[support_series_2 > support].index) #新一轮支持度筛选

support_series = support_series.append(support_series_2)

column2 = []

for i in column: #遍历可能的推理,如{A,B,C}究竟是A+B-->C还是B+C-->A还是C+A-->B?

i = i.split(ms)

for j in range(len(i)):

column2.append(i[:j]+i[j+1:]+i[j:j+1])

cofidence_series = pd.Series(index=[ms.join(i) for i in column2]) #定义置信度序列

for i in column2: #计算置信度序列

cofidence_series[ms.join(i)] = support_series[ms.join(sorted(i))]/support_series[ms.join(i[:len(i)-1])]

for i in cofidence_series[cofidence_series > confidence].index: #置信度筛选

result[i] = 0.0

result[i]['confidence'] = cofidence_series[i]

result[i]['support'] = support_series[ms.join(sorted(i.split(ms)))]

result = result.T.sort_values(by=['confidence','support'], ascending = False) #结果整理,输出

print(u'\n结果为:')

print(result)

return result

4.部分结果如下

从以上结果可以看出,对于购买学前教育类型的自考专业的用户,更倾向于领取普通话的自带小课和英语能力的自带小课。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值