数据挖掘之Apriori算法详解和Python实现代码分享


Posted in Python onNovember 07, 2014

关联规则挖掘(Association rule mining)是数据挖掘中最活跃的研究方法之一,可以用来发现事情之间的联系,最早是为了发现超市交易数据库中不同的商品之间的关系。(啤酒与尿布)

基本概念

1、支持度的定义:support(X-->Y) = |X交Y|/N=集合X与集合Y中的项在一条记录中同时出现的次数/数据记录的个数。例如:support({啤酒}-->{尿布}) = 啤酒和尿布同时出现的次数/数据记录数 = 3/5=60%。

2、自信度的定义:confidence(X-->Y) = |X交Y|/|X| = 集合X与集合Y中的项在一条记录中同时出现的次数/集合X出现的个数 。例如:confidence({啤酒}-->{尿布}) = 啤酒和尿布同时出现的次数/啤酒出现的次数=3/3=100%;confidence({尿布}-->{啤酒}) = 啤酒和尿布同时出现的次数/尿布出现的次数 = 3/4 = 75%

同时满足最小支持度阈值(min_sup)和最小置信度阈值(min_conf)的规则称作强规则 ,如果项集满足最小支持度,则称它为频繁项集

“如何由大型数据库挖掘关联规则?”关联规则的挖掘是一个两步的过程:

1、找出所有频繁项集:根据定义,这些项集出现的频繁性至少和预定义的最小支持计数一样。
2、由频繁项集产生强关联规则:根据定义,这些规则必须满足最小支持度和最小置信度。

Apriori定律

为了减少频繁项集的生成时间,我们应该尽早的消除一些完全不可能是频繁项集的集合,Apriori的两条定律就是干这事的。

Apriori定律1:如果一个集合是频繁项集,则它的所有子集都是频繁项集。举例:假设一个集合{A,B}是频繁项集,即A、B同时出现在一条记录的次数大于等于最小支持度min_support,则它的子集{A},{B}出现次数必定大于等于min_support,即它的子集都是频繁项集。

Apriori定律2:如果一个集合不是频繁项集,则它的所有超集都不是频繁项集。举例:假设集合{A}不是频繁项集,即A出现的次数小于min_support,则它的任何超集如{A,B}出现的次数必定小于min_support,因此其超集必定也不是频繁项集。

数据挖掘之Apriori算法详解和Python实现代码分享

上面的图演示了Apriori算法的过程,注意看由二级频繁项集生成三级候选项集时,没有{牛奶,面包,啤酒},那是因为{面包,啤酒}不是二级频繁项集,这里利用了Apriori定理。最后生成三级频繁项集后,没有更高一级的候选项集,因此整个算法结束,{牛奶,面包,尿布}是最大频繁子集。

Python实现代码:

Skip to content

Sign up Sign in This repository

Explore

Features

Enterprise

Blog

 Star 0  Fork 0 taizilongxu/datamining

 branch: master  datamining / apriori / apriori.py

hackerxutaizilongxu 20 days ago backup

1 contributor

156 lines (140 sloc)  6.302 kb RawBlameHistory   

#-*- encoding: UTF-8 -*-

#---------------------------------import------------------------------------

#---------------------------------------------------------------------------

class Apriori(object):
    def __init__(self, filename, min_support, item_start, item_end):

        self.filename = filename

        self.min_support = min_support # 最小支持度

        self.min_confidence = 50

        self.line_num = 0 # item的行数

        self.item_start = item_start #  取哪行的item

        self.item_end = item_end
        self.location = [[i] for i in range(self.item_end - self.item_start + 1)]

        self.support = self.sut(self.location)

        self.num = list(sorted(set([j for i in self.location for j in i])))# 记录item
        self.pre_support = [] # 保存前一个support,location,num

        self.pre_location = []

        self.pre_num = []
        self.item_name = [] # 项目名

        self.find_item_name()

        self.loop()

        self.confidence_sup()
    def deal_line(self, line):

        "提取出需要的项"

        return [i.strip() for i in line.split(' ') if i][self.item_start - 1:self.item_end]
    def find_item_name(self):

        "根据第一行抽取item_name"

        with open(self.filename, 'r') as F:

            for index,line in enumerate(F.readlines()):

                if index == 0:

                    self.item_name = self.deal_line(line)

                    break
    def sut(self, location):

        """

        输入[[1,2,3],[2,3,4],[1,3,5]...]

        输出每个位置集的support [123,435,234...]

        """

        with open(self.filename, 'r') as F:

            support = [0] * len(location)

            for index,line in enumerate(F.readlines()):

                if index == 0: continue

                # 提取每信息

                item_line = self.deal_line(line)

                for index_num,i in enumerate(location):

                    flag = 0

                    for j in i:

                        if item_line[j] != 'T':

                            flag = 1

                            break

                    if not flag:

                        support[index_num] += 1

            self.line_num = index # 一共多少行,出去第一行的item_name

        return support
    def select(self, c):

        "返回位置"

        stack = []

        for i in self.location:

            for j in self.num:

                if j in i:

                    if len(i) == c:

                        stack.append(i)

                else:

                    stack.append([j] + i)

        # 多重列表去重

        import itertools

        s = sorted([sorted(i) for i in stack])

        location = list(s for s,_ in itertools.groupby(s))

        return location
    def del_location(self, support, location):

        "清除不满足条件的候选集"

        # 小于最小支持度的剔除

        for index,i in enumerate(support):

            if i < self.line_num * self.min_support / 100:

                support[index] = 0

        # apriori第二条规则,剔除

        for index,j in enumerate(location):

            sub_location = [j[:index_loc] + j[index_loc+1:]for index_loc in range(len(j))]

            flag = 0

            for k in sub_location:

                if k not in self.location:

                    flag = 1

                    break

            if flag:

                support[index] = 0

        # 删除没用的位置

        location = [i for i,j in zip(location,support) if j != 0]

        support = [i for i in support if i != 0]

        return support, location
    def loop(self):

        "s级频繁项级的迭代"

        s = 2

        while True:

            print '-'*80

            print 'The' ,s - 1,'loop'

            print 'location' , self.location

            print 'support' , self.support

            print 'num' , self.num

            print '-'*80
            # 生成下一级候选集

            location = self.select(s)

            support = self.sut(location)

            support, location = self.del_location(support, location)

            num = list(sorted(set([j for i in location for j in i])))

            s += 1

            if  location and support and num:

                self.pre_num = self.num

                self.pre_location = self.location

                self.pre_support = self.support
                self.num = num

                self.location = location

                self.support = support

            else:

                break
    def confidence_sup(self):

        "计算confidence"

        if sum(self.pre_support) == 0:

            print 'min_support error' # 第一次迭代即失败

        else:

            for index_location,each_location in enumerate(self.location):

                del_num = [each_location[:index] + each_location[index+1:] for index in range(len(each_location))] # 生成上一级频繁项级

                del_num = [i for i in del_num if i in self.pre_location] # 删除不存在上一级频繁项级子集

                del_support = [self.pre_support[self.pre_location.index(i)] for i in del_num if i in self.pre_location] # 从上一级支持度查找

                # print del_num

                # print self.support[index_location]

                # print del_support

                for index,i in enumerate(del_num): # 计算每个关联规则支持度和自信度

                    index_support = 0

                    if len(self.support) != 1:

                        index_support = index

                    support =  float(self.support[index_location])/self.line_num * 100 # 支持度

                    s = [j for index_item,j in enumerate(self.item_name) if index_item in i]

                    if del_support[index]:

                        confidence = float(self.support[index_location])/del_support[index] * 100

                        if confidence > self.min_confidence:

                            print ','.join(s) , '->>' , self.item_name[each_location[index]] , ' min_support: ' , str(support) + '%' , ' min_confidence:' , str(confidence) + '%'
def main():

    c = Apriori('basket.txt', 14, 3, 13)

    d = Apriori('simple.txt', 50, 2, 6)
if __name__ == '__main__':

    main()

############################################################################

Status API Training Shop Blog About

© 2014 GitHub, Inc. Terms Privacy Security Contact

Apriori算法

Apriori(filename, min_support, item_start, item_end)

参数说明

filename:(路径)文件名
min_support:最小支持度
item_start:item起始位置
item_end:item结束位置

使用例子:

import apriori

c = apriori.Apriori('basket.txt', 11, 3, 13)

输出:

--------------------------------------------------------------------------------

The 1 loop

location [[0], [1], [2], [3], [4], [5], [6], [7], [8], [9], [10]]

support [299, 183, 177, 303, 204, 302, 293, 287, 184, 292, 276]

num [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------

The 2 loop

location [[0, 9], [3, 5], [3, 6], [5, 6], [7, 10]]

support [145, 173, 167, 170, 144]

num [0, 3, 5, 6, 7, 9, 10]

--------------------------------------------------------------------------------

--------------------------------------------------------------------------------

The 3 loop

location [[3, 5, 6]]

support [146]

num [3, 5, 6]

--------------------------------------------------------------------------------

frozenmeal,beer ->> cannedveg  min_support:  14.6%  min_confidence: 0.858823529412

cannedveg,beer ->> frozenmeal  min_support:  14.6%  min_confidence: 0.874251497006

cannedveg,frozenmeal ->> beer  min_support:  14.6%  min_confidence: 0.843930635838

--------------------------------------------------------------------------------
Python 相关文章推荐
Django自定义分页效果
Jun 27 Python
Python语言实现百度语音识别API的使用实例
Dec 13 Python
python版本单链表实现代码
Sep 28 Python
Python离线安装PIL 模块的方法
Jan 08 Python
python三引号输出方法
Feb 27 Python
python 初始化一个定长的数组实例
Dec 02 Python
pytorch实现seq2seq时对loss进行mask的方式
Feb 18 Python
django列表筛选功能的实现代码
Mar 27 Python
Django Xadmin多对多字段过滤实例
Apr 07 Python
如何提高python 中for循环的效率
Apr 15 Python
Flask模板引擎Jinja2使用实例
Apr 23 Python
Jupyter Notebook 实现正常显示中文和负号
Apr 24 Python
Python的subprocess模块总结
Nov 07 #Python
Python实现的监测服务器硬盘使用率脚本分享
Nov 07 #Python
Python实现的简单发送邮件脚本分享
Nov 07 #Python
Python获取Linux系统下的本机IP地址代码分享
Nov 07 #Python
零基础写python爬虫之使用Scrapy框架编写爬虫
Nov 07 #Python
零基础写python爬虫之爬虫框架Scrapy安装配置
Nov 06 #Python
零基础写python爬虫之爬虫编写全记录
Nov 06 #Python
You might like
浅析PHP页面局部刷新功能的实现小结
2013/06/21 PHP
php多线程实现方法及用法实例详解
2015/10/26 PHP
php文件缓存方法总结
2016/03/16 PHP
php 浮点数比较方法详解
2017/05/05 PHP
Laravel Intervention/image图片处理扩展包的安装、使用与可能遇到的坑详解
2017/11/14 PHP
PHP如何通过表单直接提交大文件详解
2019/01/08 PHP
HTML-CSS群中单选引发的“事件”
2007/03/05 Javascript
js 操作select相关方法函数
2009/12/06 Javascript
jquery实现table鼠标经过变色代码
2013/09/25 Javascript
各浏览器对document.getElementById等方法的实现差异解析
2013/12/05 Javascript
javascript跨浏览器的属性判断方法
2014/03/16 Javascript
jQuery实现单击按钮遮罩弹出对话框(仿天猫的删除对话框)
2014/04/10 Javascript
javascript使用appendChild追加节点实例
2015/01/12 Javascript
在Web项目中引入Jquery插件报错的完美解决方案(图解)
2016/09/19 Javascript
Bootstrap提示框效果的实例代码
2017/07/12 Javascript
使用Node.js实现RESTful API的示例
2017/08/01 Javascript
react实现菜单权限控制的方法
2017/12/11 Javascript
create-react-app构建项目慢的解决方法
2018/03/14 Javascript
javascript使用正则实现去掉字符串前面的所有0
2018/07/23 Javascript
jQuery超简单遮罩层实现方法示例
2018/09/06 jQuery
vue2.0获取鼠标位置的方法
2018/09/13 Javascript
国内常用的js类库大全(CDN公共库)
2020/06/24 Javascript
element-plus一个vue3.xUI框架(element-ui的3.x 版初体验)
2020/12/02 Vue.js
[01:04:39]OG vs Mineski 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
Python随机生成彩票号码的方法
2015/03/05 Python
python简单实现计算过期时间的方法
2015/06/09 Python
python3.4下django集成使用xadmin后台的方法
2017/08/15 Python
Python使用指定端口进行http请求的例子
2019/07/25 Python
Python面向对象之Web静态服务器
2019/09/03 Python
浅谈pytorch池化maxpool2D注意事项
2020/02/18 Python
500行python代码实现飞机大战
2020/04/24 Python
毕业留言寄语大全
2014/04/10 职场文书
诉讼财产保全担保书
2014/05/20 职场文书
2014年财务科工作总结
2014/11/11 职场文书
干货:如何写好工作总结报告!
2019/05/10 职场文书
教你怎么用Python监控愉客行车程
2021/04/29 Python