设全集U = {a, b, c, d, e},其元素a,b, c, d, e称为项.

数据集:

D = [
    {a, b},
    {b, c, d},
    {d, e},
    {b, c, e},
    {a,b, c, d}
]

项的集合如{a,b}称为项集(cell), 包含k个项的集合称为k项集.

数据集D中包含项集A的集合占所有元素集的比例称为A的支持度(support).如{a}的支持度为2/5.

若项集满足人为设定的最小支持度,则称为频繁集.

频繁集的任意子集一定是频繁集, 非频繁集的超集一定为非频繁集.

定义关联规则{a} -> {b}的可信度(confidence)为:support({a} U {b}) / support({a}).

关联分析的目的在于寻找频繁集以及关联规则。

寻找频繁集

非频繁集的超集一定为非频繁集,我们从空集开始根据包含关系构建一棵树:

根据数据集创建单项集:

def createUnit(dataSet):  # create cell with one element
    universe = []
    for cell in dataSet:
        for item in cell:
            if not [item] in universe:
                universe.append([item])
    return map(frozenset, universe)

遍历每一个项集中的每一项,将项添加到全集中, 最后使用map由全集创建单项集.

使用frozenset而非set,是因为frozenset可以在dict中作为键, 而set不能.

从候选集中筛选频繁集:

def filterCandidates(dataSet, candidates, limit):
    cellCount = {}
    for cell in dataSet:
        for candidate in candidates:
            if candidate.issubset(cell):
                if not candidate in cellCount:
                    cellCount[candidate] = 1
                else:
                    cellCount[candidate] += 1
    cellNum = len(dataSet)
    selected = []
    supports = {}
    for cell in cellCount:
        support = float(cellCount[cell]) / cellNum
        if support >= limit:
            selected.insert(0, cell)
        supports[cell] = support
    return selected, supports

该方法接受三个参数, 数据集dataSet, 候选集列表candidates, 和最小支持度limit.

遍历dataSet中的所有项集,统计各候选集超集的个数, 用于计算候选集的支持度.

过滤所有候选集, 返回支持度达到要求的项集(频繁集).

根据k-1项集创建所有k项集:

def createKCell(origins, k):
    cells = []
    originCount = len(origins)
    for i in range(originCount):
        for j in range(i + 1, originCount):
            list1 = list(origins[i])[:k - 2]
            list2 = list(origins[j])[:k - 2]
            list1.sort()
            list2.sort()
            if list1 == list2:  # if first k-2 elements are equal
                cells.append(origins[i] | origins[j])  # set union
    return cells

该方法接受两个参数,k-1项集列表origins和k. 通过并集运算建立k项集.

从单项集开始寻找频繁集:

def apriori(dataMat, limit=0.5):
    units = createUnit(dataMat)
    dataSet = map(set, dataMat)
    origin, supports = filterCandidates(dataSet, units, limit)
    candidates = [origin]
    k = 2
    while (len(candidates[k - 2]) > 0):
        cellK = createKCell(candidates[k - 2], k)
        cellK, supportK = filterCandidates(dataSet, cellK, limit)
        supports.update(supportK)
        candidates.append(cellK)
        k += 1
    return candidates, supports

寻找关联规则

频繁集之间存在着关联规则:

实现filterRules方法获得可信度满足要求的规则, 每条规则用三元组来描述:(A, B, confidence)代表规则A->B的可信度为confidence.

def filterRules(cells, consequences, supports, bigRuleList, limit=0.7):
    prunedConsequences = []
    for consequence in consequences:
        confidence = supports[cells] / supports[cells - consequence]
        if confidence >= limit:
            rule = (cells - consequence, consequence, confidence)
            bigRuleList.append(rule)
            prunedConsequences.append(consequence)
return prunedConsequences

该方法接受5个参数:

  • cells:频繁集列表

  • consequences: 所有可放在规则右侧的元素组成的列表

  • supports: cells中各频繁集的支持度

  • bigRuleList: 已知规则的列表, 该方法会将满足要求的规则添加到该列表中

  • limit: 规则可信度的下限

该方法返回满足条件的规则的右侧元素组成的列表.

当规则右侧的元素的数目大于2时, 尝试对其进行合并:

def rulesFromConseq(cells, consequences, supports, bigRuleList, limit=0.7):
    m = len(consequences[0])
    if len(cells) > (m + 1):  # try further merging
        new_consequences = createKCell(consequences, m + 1)
        new_consequences = filterRules(cells, new_consequences, supports, bigRuleList, limit)
        if len(new_consequences) > 1:  # need at least two sets to merge
            rulesFromConseq(cells, new_consequences, supports, bigRuleList, limit)

该方法的参数与filterRules方法相同, 使用递归来实现.

利用上面两个工具函数来编写寻找关联规则的方法:

def generateRules(cells, supports, limit=0.7):
    bigRuleList = []
    for i in range(1, len(cells)):
        for cell in cells[i]:
            consequences = [frozenset([item]) for item in cell]
            if i > 1:
                rulesFromConseq(cell, consequences, supports, bigRuleList, limit)
            else:
                filterRules(cell, consequences, supports, bigRuleList, limit)
    return bigRuleList

接受频繁集列表及其支持度作为参数, 遍历各频繁集根据给定的可信度范围寻找关联规则.

编写test方法进行测试:

def test():
    dataSet = [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]]
    cells, supports = apriori(dataSet, 0.5)
    # print(cells)
    rules = generateRules(cells, supports)
    print(rules)
    # units = createUnit(dataSet)
    # print(units)
    # cells, supports = filterCandidates(dataSet, units, 0.5)
    # print(cells, supports)
    # cells = createKCell(selected, 2)
    # print(cells)

顺便展示一下各函数的用法, 完整代码可以看这里

Apriori算法进行关联分析的更多相关文章

  1. 机器学习实战 - 读书笔记(11) - 使用Apriori算法进行关联分析

    前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第11章 - 使用Apriori算法进行关联分析. 基本概念 关联分析(associat ...

  2. 【机器学习实战】第11章 使用 Apriori 算法进行关联分析

    第 11 章 使用 Apriori 算法进行关联分析 关联分析 关联分析是一种在大规模数据集中寻找有趣关系的任务. 这些关系可以有两种形式: 频繁项集(frequent item sets): 经常出 ...

  3. 机器学习实战(Machine Learning in Action)学习笔记————07.使用Apriori算法进行关联分析

    机器学习实战(Machine Learning in Action)学习笔记————07.使用Apriori算法进行关联分析 关键字:Apriori.关联规则挖掘.频繁项集作者:米仓山下时间:2018 ...

  4. 机器学习——使用Apriori算法进行关联分析

    从大规模的数据集中寻找隐含关系被称作为关联分析(association analysis)或者关联规则学习(association rule learning). Apriori算法 优点:易编码实现 ...

  5. 使用Apriori算法进行关联分析

    关联分析是一种在大规模数据集中寻找有趣关系的任务.这些关系可以有两种形式:频繁项集或者关联规则.频繁项集是指经常出现在一块的物品的集合,关联规则暗示两种物品之间可能存在很强的关系.一个项集的支持度被定 ...

  6. 第十一章:使用Apriori算法进行关联分析

  7. 使用Apriori算法和FP-growth算法进行关联分析

    系列文章:<机器学习实战>学习笔记 最近看了<机器学习实战>中的第11章(使用Apriori算法进行关联分析)和第12章(使用FP-growth算法来高效发现频繁项集).正如章 ...

  8. 数据挖掘算法:关联分析二(Apriori)

    二.Apriori算法 上文说到,大多数关联规则挖掘算法通常采用的策略是分解为两步: 频繁项集产生,其目标是发现满足具有最小支持度阈值的所有项集,称为频繁项集(frequent itemset). 规 ...

  9. 数据挖掘算法:关联分析二(FP-tree算法)

    三.FP-tree算法 下面介绍一种使用了与Apriori完全不同的方法来发现频繁项集的算法FP-tree.FP-tree算法在过程中没有像Apriori一样产生候选集,而是采用了更为紧凑的数据结构组 ...

随机推荐

  1. 用delegate实现.NET应用程序的同步函数的异步调用-.NET多线程编程实践之一

    在C++中有2种类型的线程:UI Thread和Worker Thread,前者是基于用户界面的有消息循环的线程.后者是没有用户界面的侧重于大时空运算的线程.直接调用Windows相关线程及同步对象的 ...

  2. shell 命令 修改hosts文件

    hosts文件管理http地址和物理ip地址的映射关系. 开发spring cloud 项目时,遇到不能连接服务器部署的zk问题. 排查后发现,是本地的hosts文件没有添加这台机器的ip映射关系. ...

  3. 机器学习实战-ch2-有标签的聚类算法

    本书中的这个聚类算法多少有些让人意外.通常的聚类算法是这样的: 给定一堆点: 给定一个距离计算的算法: 给定一个cluster之间的距离d,或者最小的cluster数目k: 初始化,每个点作为初始集群 ...

  4. CentOS 7配置Let’s Encrypt支持免费泛域名证书

    Let’s Encrypt从2018年开始支持泛域名证书,有效期3个月,目前仅支持acme方式申请,暂不支持certbot. 1.安装acme.sh curl https://get.acme.sh ...

  5. SSO集成方案[随笔]

    看这个方案之前,先说明下为什么要加入SSO,以防对大家产生不好的影响.我们产品使用传统winform+db服务+Db存储方式开发,一群老菜帮子开发,以传统的datatble做数据传递,很多年了未有变化 ...

  6. Aspose Word.Dll库自带的bug导致The document appears to be corrupted and cannot be loaded 问题处理。

    问题的详细描述: C#在开发过程中使用Aspose.word.dll库去实现word套打功能.但是,最近客户反映出现了一个问题,在打印文档的时候,系统报错.经过定位分析发现是Aspose.word.d ...

  7. 多项式&生成函数(~~乱讲~~)

    多项式 多项式乘法 FFT,NTT,MTT不是前置知识吗?随便学一下就好了(虽然我到现在还是不会MTT,exlucas也不会用) FTT总结 NTT总结 泰勒展开 如果一个多项式\(f(x)\)在\( ...

  8. flex定位下overflow失效的问题研究

    概述 这是我在写移动端页面遇到的问题及解决方法,记录下来供以后开发时参考,相信对其他人也有用. 问题 之前写移动端页面,有一个顶条是导航条,需要固定在页面顶部,并且里面的元素需要可以左右滚动. 但是当 ...

  9. [HTML] css3 输入框input类型为number时,去掉上下箭头方式

    <input type="number" ...> <style> input::-webkit-outer-spin-button, input::-we ...

  10. Python小白学习之路(二十三)—【生成器补充】

    生成器的一些补充 接着下鸡蛋和吃包子! 补充一:生成器只能遍历一次 (总是把生成器比喻成母鸡下鸡蛋,需要一个下一个,首先是下出来的鸡蛋不能塞回母鸡肚子里,其次是一个母鸡一生只能下一定数量的鸡蛋,下完了 ...