数据挖掘之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 相关文章推荐
python利用hook技术破解https的实例代码
Mar 25 Python
Android 兼容性问题:java.lang.UnsupportedOperationException解决办法
Mar 19 Python
python自动化脚本安装指定版本python环境详解
Sep 14 Python
python3.5 tkinter实现页面跳转
Jan 30 Python
python矩阵的转置和逆转实例
Dec 12 Python
使用pycharm设置控制台不换行的操作方法
Jan 19 Python
pandas 层次化索引的实现方法
Jul 06 Python
Python使用Tkinter实现转盘抽奖器的步骤详解
Jan 06 Python
Python3实现发送邮件和发送短信验证码功能
Jan 07 Python
利用Python函数实现一个万历表完整示例
Jan 23 Python
教你利用python实现企业微信发送消息
May 23 Python
ROS系统将python包编译为可执行文件的简单步骤
Jul 25 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
漫威DC御用漫画家去世 他的表情包曾走红网络
2020/04/09 欧美动漫
锁定年轻人的双倍活力 星巴克推出星倍醇即饮浓咖啡
2021/03/03 咖啡文化
增加反向链接的101个方法 站长推荐
2007/01/31 PHP
php-fpm中max_children的配置
2019/03/15 PHP
Mootools 1.2教程 定时器和哈希简介
2009/09/15 Javascript
js几个验证函数代码
2010/03/25 Javascript
jQuery Ajax使用 全解析
2010/12/15 Javascript
JS实现很酷的水波文字特效实例
2015/02/26 Javascript
js中函数声明与函数表达式
2015/06/03 Javascript
jQuery Mobile弹出窗、弹出层知识汇总
2016/01/05 Javascript
浅谈jquery上下滑动的注意事项
2016/10/13 Javascript
JavaScript中访问id对象 属性的方式访问属性(实例代码)
2016/10/28 Javascript
微信小程序 实现tabs选项卡效果实例代码
2016/10/31 Javascript
ES6概念 Symbol.keyFor()方法
2016/12/25 Javascript
详解vue.js2.0父组件点击触发子组件方法
2017/05/10 Javascript
JavaScript的Object.defineProperty详解
2018/07/09 Javascript
vue模块拖拽实现示例代码
2019/03/09 Javascript
详解vue中axios的使用与封装
2019/03/20 Javascript
详解VScode编辑器vue环境搭建所遇问题解决方案
2019/04/26 Javascript
微信小程序实现获取用户信息并存入数据库操作示例
2019/05/07 Javascript
vue实现的请求服务器端API接口示例
2019/05/25 Javascript
node-red File读取好保存实例讲解
2019/09/11 Javascript
JS代码检查工具ESLint介绍与使用方法
2020/02/04 Javascript
webpack5 联邦模块介绍详解
2020/07/08 Javascript
PyMongo安装使用笔记
2015/04/27 Python
Python寻找两个有序数组的中位数实例详解
2018/12/05 Python
详解Python中的测试工具
2019/06/09 Python
Python中一个for循环循环多个变量的示例
2019/07/16 Python
对django 模型 unique together的示例讲解
2019/08/06 Python
python内存管理机制原理详解
2019/08/12 Python
python使用Matplotlib改变坐标轴的默认位置
2019/10/18 Python
为什么需要版本控制?
2013/08/08 面试题
保安自我鉴定范文
2013/12/08 职场文书
本科毕业自我鉴定
2014/03/20 职场文书
关爱留守儿童倡议书
2014/04/15 职场文书
中学生运动会通讯稿大全
2014/09/18 职场文书