精华内容
下载资源
问答
  • 数据挖掘课程实验中所编代码,个人原创,很有参考意义
  • Aprior算法

    2012-10-18 11:00:27
    直接拷贝到Visual c++6.0下就能运行,是采用读取文件的方式读入数据,注意文件的格式,较好的实现了Aprior算法,直接打开就能运行
  • 关联分析aprior算法及在灵长类动物DNA序列识别中的应用
  • 数据挖掘Aprior算法

    2015-11-10 13:18:25
    这是数据挖掘中Aprior算法,用到了文件读入 5 100 6 M O N K E Y 200 6 D O N K E Y 300 4 M A K E 400 5 M U C K Y 500 6 C O O K I E
  • aprior.cpp

    2020-03-07 13:03:00
    aprior算法实现!aprior算法实现!aprior算法实现!aprior算法实现!aprior算法实现!aprior算法实现!aprior算法实现!aprior算法实现!
  • aprior算法 aprior算法

    2011-04-30 20:15:24
    aprior算法aprior算法aprior算法
  • aprior算法

    2020-04-30 14:47:48
    1. aprior算法 aprior算法是一种寻找数据之间关联性算法。用它在大数据中可以分析出一些有趣的结论。 2. 老韩家养了鸭没 村口老王和老李在村口聊天,聊天内容讲到村里人养了哪些家禽,清单如下。 人家 家禽 老赵 鸡...

    1. aprior算法

    aprior算法是一种寻找数据之间关联性算法。用它在大数据中可以分析出一些有趣的结论。

    2. 老韩家养了鸭没

    村口老王和老李在村口聊天,聊天内容讲到村里人养了哪些家禽,清单如下。

    人家家禽
    老赵鸡,鸭
    老钱鸡,牛,猪,狗
    老孙牛,猪,猫,鸭
    老李鸭,鸡,牛,猪
    老周鸭,鸡,牛,猫

    问题:住的比较远的老韩,他家养了鸡,他还会养什么呢?

    老王观察到一个现象:村里大部分人养了鸡都会养鸭,于是老王说:“老韩家也会养鸭”。

    上述老王的说法,可以用更为科学的aprior算法分析。

    3. 概念

    1. 频繁项集:经常出现在一起的两个元素的集合。例如:{鸡,鸭}就是一个频繁项集。
    2. 关联规则:两个元素之间可能存在很强的关联关系。例如:养鸡和养鸭可能就存在很强的关联关系。我们记做规则:{鸡}-> {鸭}
    3. 支持度:一个项集的支持度被定义为数据集中包含该项集的记录所占的比例。例如:{鸡}的支持度就是 4 / 5, {鸡, 鸭}的支持度就是3 / 5。
    4. 置信度: 置信度是表明抽样指标和总体指标的误差不超过一定范围的概率保证度。置信度是基于关联规则的,例如:关联规则为:{鸡}-> {鸭},那么:置信度 = {鸡,鸭} 的支持度 / {鸡} 的支持度。 (3/5) / (4/5) = 0.75。这就意味着在养鸡的家庭中75%都适用于这个规则。

    4.aprior原理

    上面分析后,道理大概都已经懂了。如果要在一串清单中找出各元素的关系。那么我们只需要做如下步骤:

    1. 找出包含所有元素的集合S。=>S = {鸡,鸭,牛,猪,狗,猫}
    2. 找出集合S的非空子集,非空子集个数 2^n - 1。 => s1 = {鸡}, s2 = {鸭} …, 总个数为 2^5 -1 = 31
    3. 计算每个子集的支持度。
    4. 找出频繁项集,即为支持度大的集合。
    5. 计算关联规则的置信度。

    如果是这样计算,那么当数据量大的时候,运算量将会超级大。于是我们发现另一个有趣的结论:

    如果某个项集是频繁项集,那么它所有的子集也是频繁的。即如果 {鸡,鸭} 是频繁的,那么 {鸡}, {鸭} 也一定是频繁的。

    这结论用我们上面例子来讲:养{鸡,鸭}的人家多,那养{鸡}和养{鸭}的人家肯定也多。

    这个结论有啥用?仔细一看确实没啥用,但是我们把它的逆否命题写出来就有用了。

    如果一个集合不频繁,那么它的父集也一定不频繁。

    道理很简单:养{牛}的人家少,那养{鸡,牛}的人家肯定也少。

    5.aprior算法过程

    看这个例子:

    item
    1 3 4
    2 3 5
    1 2 3 5
    2 5

    扫描出1项集:

    setsup
    {1}2
    {2}3
    {3}3
    {4}1
    {5}3

    减除 sup < 50%的项集

    setsup
    {1}2
    {2}3
    {3}3
    {5}3

    扫描出2项集

    setsup
    {1, 2}1
    {1, 3}2
    {1, 5}1
    {2, 3}2
    {2, 5}3
    {3, 5}2

    减除 sup < 50%的项集

    setsup
    {1, 3}2
    {2, 3}2
    {2, 5}3
    {3, 5}2

    扫描出3项集

    setsup
    {2,3,5}2

    所以最终的结果为频繁3项集为{2, 3, 5}

    展开全文
  • 一、Aprior算法 1.对A→B: (1)支持度:support(A→B)=P(A∪B) 可信度:confidence(A→B)=P(B|A) 期望可信度:P(B) 作用度:PB|A)/P(B) (2)候选k项集→(用最小支持度进行过滤)→频繁k项集 某一频繁集生成的所有...

    1.对A→B:
    (1)支持度:support(A→B)=P(A∪B)
    可信度:confidence(A→B)=P(B|A)
    期望可信度:P(B)
    作用度:P(B|A)/P(B)
    (2)候选k项集→(用最小支持度进行过滤)→频繁k项集
    某一频繁集生成的所有规则→(用最小置信度进行过滤)→强规则集合

    2.Matlab代码如下:
    (1)计算支持度的函数compute_sup

    function sup=compute_sup(X,D)
    [m,n]=size(D);
    sup=0;
    for i=1:m
        if all(D(i,:)-X>=0)==true  %结果大于等于零说明D的此项集包含了X,X个数加一
            sup=sup+1;
        end
    end
    sup=sup/m;
    

    (2)计算置信度的函数compute_conf

    function C=compute_conf(D,R) %R为关联规则矩阵,其中条件为-1,结果为1,其余为0 
    x=(R==-1); 
    y=(R==1);
    C=compute_sup(x|y,D)/compute_sup(x,D); %(x|y)可直接用(abs(R))
    

    (3)Aprior函数:

    function R=Aprior(D,min_sup,min_conf)
    [m,n]=size(D);%m为D的行数,n为D的列数
    X=[];
    C=eye(n);%eye单位矩阵
    for i=1:n
        L=[];
        [c,d]=size(C);
        for i=1:c
        if compute_sup(C(i,:),D)>=min_sup
            L=[L;C(i,:)];%符合条件则加入矩阵L
        end
    end
    X=[X;L];%把频繁项集放入X矩阵,再把C矩阵清空作为下一个候选项集
        C=[];
        [a,b]=size(L);
        for i=1:a
            for j=i+1:a
                 indi=find(L(i,:)==1);
            indj=find(L(j,:)==1);
            if all(indi(1:end-1)==indj(1:end-1))&&(indi(end)~=indj(end))%前n-1项相同,最后一项不同,才能合并
                C=[C;L(i,:)|L(j,:)];
            end
        end
    end
    if isempty(C)
        break;
    end
    end
    
    [e,f]=size(X);%已经得到频繁项集了,下面开始求强规则 
    R=[];
    for i=1:e
        ind=find(X(i,:)==1);
        if length(ind)<=1%所有频繁项集里有只有一个元素的,把它排除,因它生成不了规则
            continue;
        end
        for j=1:length(ind)-1
            indd=nchoosek(ind,j);%从ind中选j个数进行组合 
            [g,h]=size(indd);
            for k=1:g
                Rk=X(i,:);
                Rk(indd(k,:))=-1;
                if(compute_conf(D,Rk))>=min_conf
                    R=[R;Rk];
                end
            end
        end
    end
    
    展开全文
  • 本程序是数据挖掘中的关联规则模型中著名的Aprior算法的VC实现程序,可用于知识发现、数据挖掘、人工智能、模式识别等领域
  • Aprior算法和FP Group算法

    千次阅读 2018-01-23 15:35:28
    分别详细介绍了Aprior算法和FP Group算法。他们的区别就是Apriori算法多次扫描交易数据库,每次利用候选频繁集产生频繁集,而FP则利用树形结构,不用产生候选频繁集而是直接得到频繁集,大大减少了扫描的次数,从而...

    转自 http://blog.sina.com.cn/s/articlelist_1761593252_1_1.html
    分别详细介绍了Aprior算法和FP Group算法。他们的区别就是Apriori算法多次扫描交易数据库,每次利用候选频繁集产生频繁集,而FP则利用树形结构,不用产生候选频繁集而是直接得到频繁集,大大减少了扫描的次数,从而算法效率提高,但是apriori的扩展性好,可以用于并行计算等领域。

    数据挖掘中有一个很重要的应用,就是Frequent Pattern挖掘,翻译成中文就是频繁模式挖掘。这篇博客就想谈谈频繁模式挖掘相关的一些算法。

    定义

    何谓频繁模式挖掘呢?所谓频繁模式指的是在样本数据集中频繁出现的模式。举个例子,比如在超市的交易系统中,记载了很多次交易,每一次交易的信息包括用户购买的商品清单。如果超市主管是个有心人的话,他会发现尿不湿,啤酒这两样商品在许多用户的购物清单上都出现了,而且频率非常高。尿不湿,啤酒同时出现在一张购物单上就可以称之为一种频繁模式,这样的发掘就可以称之为频繁模式挖掘。这样的挖掘是非常有意义的,上述的例子就是在沃尔玛超市发生的真实例子,至今为工业界所津津乐道。

    Aprior挖掘算法:

    那么接下来的问题就很自然了,用户该如何有效的挖掘出所有这样的模式呢?下面我们就来讨论一下最简单,最自然的一种方法。在谈到这个算法之前,我们先声明一个在频繁模式挖掘中的一个特性-Aprior特性。

    Aprior特性:

    这个特性是指如果一个Item set(项目集合)不是frequent item set(频繁集合),那么任何包含它的项目集合一定也不是频繁集合.这里的集合就是模式.这个特性很自然,也很容易理解.比如还是看上面沃尔玛超市的例子,如果啤酒这个商品在所有的购物清单中只出现过1次,那么任何包含啤酒这个商品的购物商品组合,比如(啤酒,尿不湿)最多也只出现了一次,如果我们认定出现次数多于2次的项目集合才能称之为频繁集合的话,那么这些包含了啤酒的购物组合肯定都不是频繁集合.反之,如果一个项目集合是频繁集合,那么它的任意非空子集也是频繁集合.

    有了这个特性,那么就可以在挖掘过程中对一些不可能的项目集合进行排除,避免造成不必要的计算浪费.这个方法主要包含两个操作:product(叉积)和prune(剪枝).这两种操作是整个方法的核心.

    首先是product(不少地方也称此步骤为合并吧):

    先有几个定义,L(k)-候选项目队列,该队列中包含一系列的项目集合(k也就是一个规则中项目/物品的数目),这些项目集合的长度都是一样的,都为k,这个长度我们称之为秩,这些长度相同的集合称之为k-集合。
    那么就有L(k+1)=L(k) product L(k).也就是说通过product操作(自叉积),秩为k的候选队列可以生成秩为k+1的候选队列。需要注意的是,这里所有的候选队列中的k-集合都按照字母顺序(或者是另外的某种事先定义好的顺序)排好序了。
    好,下面关键来了,product该如何执行?product操作是针对候选队列中的k-集合的,实际上就是候选队列中的k-集合两两进行执行join操作。K-集合l1,l2之间能够进行join有一个前提,那就是两个k-集合的前k-1个项目是相同的,并且l1(k)的顺序大于l2(k)(这个顺序的要求是为了排除重复结果)。用公式表示这个前提就是

    (l1[1]=l2[1])and(l1[2]=l2[2])andand(l1[k1]=l2[k1])and(l1[k]<l2[k])

    那么join的结果就形成了一个k+1长度的集合l1[1],l1[2],…,l1[k-1],l1[k],l2[k]。如果L(k)队列中的所有k-集合两两之间都完成了join操作,那么这些形成的k+1长度的集合就构成了一个新的秩为k+1的候选项目队列L(k+1)。

    比如说,候选频繁2项集{啤酒,尿布},{啤酒,花生}就可以被合并成3项集{啤酒,尿布,花生}

    剪枝操作:

    这个操作是针对候选队列的,它对候选队列中的所有k-集合进行一次筛选,筛选过程会对数据库进行一次扫描,把那些不是频繁项目集合的k-集合从L(k)候选队列中去掉。为什么这么做呢?还记得前面提到的Aprior特性么?因为这些不是频繁集合的k-集合通过product操作无法生成频繁集合,它对product操作产生频繁集合没有任何贡献,把它保留在候选队列中除了增加复杂度没有任何其他优点,因此就把它从队列中去掉。

    这两个操作就构成了算法的核心,用户从秩为1的项目候选队列开始,通过product操作,剪枝操作生成秩为2的候选队列,再通过同样的2步操作生成秩为3的候选队列,一直循环操作,直到候选队列中所有的k-集合的出现此为等于support count.

    下面给出一个具体的例子,可以很好得阐述上面的算法思想:

    这里写图片描述

    这里写图片描述

    这种算法思路比较清晰直接,实施起来比较简单。但是缺点就是代价很大,每一次剪枝操作都会对数据库进行扫描,每一次product操作需要对队列中的k-集合两两进行join操作,其复杂度为C(sizeof(L(k)),2)。

    为了提高算法效率,Han Jiawei提出了FP Growth算法,使得频繁模式的挖掘效率又提升了一个数量级。

    FP树构造

    FP Growth算法利用了巧妙的数据结构,大大降低了Aproir挖掘算法的代价,他不需要不断得生成候选项目队列和不断得扫描整个数据库进行比对。为了达到这样的效果,它采用了一种简洁的数据结构,叫做frequent-pattern tree(频繁模式树)。下面就详细谈谈如何构造这个树,举例是最好的方法。请看下面这个例子:

    这里写图片描述

    这张表描述了一张商品交易清单,abcdefg代表商品,(ordered)frequent items这一列是把商品按照降序重新进行了排列,这个排序很重要,我们操作的所有项目必须按照这个顺序来,这个顺序的确定非常简单,只要对数据库进行一次扫描就可以得到这个顺序。由于那些非频繁的项目在整个挖掘中不起任何作用,因此在这一列中排除了这些非频繁项目。我们在这个例子中设置最小支持阈值(minimum support threshold)为3。

    我们的目标是为整个商品交易清单构造一颗树。我们首先定义这颗树的根节点为null,然后我们开始扫描整个数据库的每一条记录开始构造FP树。

    第一步:扫描数据库的第一个交易,也就是TID为100的交易。那么就会得到这颗树的第一个分支< (f:1),(c:1),(a:1),(m:1),(p:1)>。注意这个分支一定是要按照降频排列的。

    这里写图片描述

    第二步:扫描第二条交易记录(TID=200),我们会有这么一个频繁项目集合 < f,c,a,b,m> 。仔细观察这个队列,你会发现这个集合的前3项< f,c,a>与第一步产生的路径< f,c,a,m,p>的前三项是相同的,也就是说他们可以共享一个前缀。于是我们在第一步产生的路径的基础上,把< f,c,a>三个节点的数目加1,然后将< (b:1),(m:1)>作为一个分支加在(a:2)节点的后面,成为它的子节点。看下图

    这里写图片描述

    第三步:接着扫描第三条交易记录(TID=300),你会看到这条记录的集合是< f, b>,与已存在的路径相比,只有f是共有的前缀,那么f节点加1,同时再为f节点生成一个新的字节点(b:1).就会有下图:

    这里写图片描述

    第四步:继续看第四条交易记录,它的集合是< c,b,p>,哦,这回不一样了。你会发现这个集合的第一个元素是c,与现存的已知路径的第一个节点f不一样,那就不用往下比了,没有任何公共前缀。直接将该集合作为根节点的子路径附加上去。就得到了下图(图1):
    这里写图片描述

    第五步:最后一条交易记录来了,你看到了一条集合< f,c,a,m,p>。你惊喜得发现这条路径和树现有最左边的路径竟然完全一样。那么,这整条路径都是公共前缀,那么这条路径上的所有点都加1好了。就得到了最终的图(图2)。
    这里写图片描述

    好了,一颗FP树就已经基本构建完成了。等等,还差一点。上述的树还差一点点就可以称之为一个完整的FP树啦。为了便于后边的树的遍历,我们为这棵树又增加了一个结构-头表,头表保存了所有的频繁项目,并且按照频率的降序排列,表中的每个项目包含一个节点链表,指向树中和它同名的节点。罗嗦了半天,可能还是不清楚,好吧直接上图,一看你就明白:

    这里写图片描述

    以上就是整个FP树构造的完整过程。聪明的读者一定不难根据上述例子归纳总结出FP树的构造算法。这里就不再赘述。详细的算法参考文献1。

    FP树的挖掘

    下面就是最关键的了。我们已经有了一个非常简洁的数据结构,下一步的任务就是从这棵树里挖掘出我们所需要的频繁项目集合而不需要再访问数据库了。还是看上面的例子。

    第一步:我们的挖掘从头表的最后一项p开始,那么一个明显的直接频繁集是(p:3)了。根据p的节点链表,它的2个节点存在于2条路径当中:路径< f:4,c:3,a:3,m:2,p:2>和路径< c:1,b:1,p:1>.从路径< f:4,c:3,a:3,m:2,p:2>我们可以看出包含p的路径< f,c,a,m,p>出现了2次,同时也会有< f,c,a>出现了3次,< f>出现了4次。但是我们只关注< f,c,a,m,p>,因为我们的目的是找出包含p的所有频繁集合。同样的道理我们可以得出< c,b,p>在数据库中出现了1次。于是,p就有2个前缀路径{(fcam:2),(cb:1)}。这两条前缀路径称之为p的子模式基(subpattern-base),也叫做p的条件模式基(之所以称之为条件模式基是因为这个子模式基是在p存在的前提条件下)。接下来我们再为这个条件子模式基构造一个p的条件FP树。再回忆一下上面FP树的构造算法,很容易得到下面这棵树:

    这里写图片描述

    但是由于频繁集的阈值是3。那么实际上这棵树经过剪枝之后只剩下一个分支(c:3),所以从这棵条件FP树上只能派生出一个频繁项目集{cp:3}.加上直接频繁集(p:3)就是最后的结果.

    第二步:我们接下来开始挖掘头表中的倒数第二项m,同第一步一样,显然有一个直接的频繁集(m:3).再查看它在FP树中存在的两条路径< f:4,c:3,a:3,m:2>和< f:4,c:3,a:3,b1,m:1>.那么它的频繁条件子模式基就是{ (fca:2),(fcab:1)}.为这个子模式基构造FP树,同时舍弃不满足最小频繁阈值的分支b,那么其实在这棵FP树中只存在唯一的一个频繁路径< f:3,c:3,a:3>.既然这颗子FP树是存在的,并且不是一颗只有一个节点的特殊的树,我们就继续递归得挖掘这棵树.这棵子树是单路径的子树,我们可以简化写成mine(FP tree|m)=mine(< f:3,c:3,a:3>|m:3).

    下面来阐述如何挖掘这颗FP子树,我们需要递归.递归子树也需要这么几个步骤:

    1这颗FP子树的头表最后一个节点是a,结合递归前的节点m,那么我们就得到am的条件子模式基{(fc:3)},那么此子模式基构造的FP树(我们称之为m的子子树)实际上也是一颗单路径的树< f:3,c:3>,接下也继续继续递归挖掘子子树mine(< f:3,c:3>|am:3). (子子树的递归分析暂时打住.因为再分析子子树的递归的话文字就会显得太混乱)

    2同样,FP子树头表的倒数第二个节点是c,结合递归前节点m,就有我们需要递归挖掘mine(< f:3>|cm:3).

    3 FP子树的倒数第三个节点也是最后一个节点是f,结合递归前的m节点,实际上需要递归挖掘mine(null|fm:3),实际上呢这种情况下的递归就可以终止了,因为子树已经为空了.因此此情况下就可以返回频繁集合< fm:3>

    注意:这三步其实还包含了它们直接的频繁子模式< am:3>,< cm:3>,< fm:3>,这在每一步递归调用mine< FPtree>都是一样的,就不再罗嗦得一一重新指明了.

    实际上这就是一个很简单的递归过程,就不继续往下分析了,聪明的读者一定会根据上面的分析继续往下推导递归,就会得到下面的结果.

    mine(< f:3,c:3>|am:3)=>< cam:3>,< fam:3>,< fcam:3>

    mine(< f:3>|cm:3)=>< fcm:3>

    mine(null|fm:3)=>< fm:3>

    这三步还都包含了各自直接的频繁子模式< am:3>,< cm:3>,< fm:3>.

    最后再加上m的直接频繁子模式< m:3>,就是整个第二步挖掘m的最后的结果。请看下图

    这里写图片描述

    第三步:来看看头表倒数第三位< b:3>的挖掘,它有三条路径< f:4,c:3,a:3,b:1>,< f:4,b:1>,< c:1,b:1>,形成的频繁条件子模式基为{(fca:1),(f:1),(c:1)},构建成的FP树中的所有节点的频率均小于3,那么FP树为空,结束递归.这一步得到的频繁集就只有直接频繁集合< b:3>

    第四步:头表倒数第四位< a:3>,它有一条路径< f:4,c:3>,频繁条件子模式基为{(fc:3)},构成一个单路径的FP树.实际上可能有人早已经发现了,这种单路径的FP树挖掘其实根本不用递归这么麻烦,只要进行排列组合就可以直接组成最后的结果.实际上也确实如此.那么这一步最后的结果根据排列组合就有:{(fa:3),(ca:3),(fca:3),(a:3)}

    第五步:头表的倒数第五位< c:4>,它只有一条路径< f:4>,频繁条件子模式基为{(f:3)},那么这一步的频繁集也就很明显了:{(fc:3),(c:4)}

    第六步:头表的最后一位< f:4>,没有条件子模式基,那么只有一个直接频繁集{(f:4)}

    这6步的结果加在一起,就得到我们所需要的所有频繁集.下图给出了每一步频繁条件模式基.

    这里写图片描述

    其实,通过上面的例子,估计早有人看出来了,这种单路径的FP树挖掘其实是有规律的,根本不用递归这么复杂的方法,通过排列组合可以直接生成.的确如此,Han Jiawei针对这种单路径的情况作了优化.如果一颗FP树有一个很长的单路径,我们将这棵FP树分成两个子树:一个子树是由原FP树的单路径部分组成,另外一颗子树由原FP树的除单路径之外的其余部分组成.对这两个子树分别进行FP Growth算法,然后对最后的结果进行组合就可可以了.

    通过上面博主不厌其烦,孜孜不倦,略显罗嗦的分析,相信大家已经知道FP Growth算法的最终奥义.实际上该算法的背后的思想很简单,用一个简洁的数据结构把整个数据库进行FP挖掘所需要的信息都包含了进去,通过对数据结构的递归就可以完成整个频繁模式的挖掘.由于这个数据结构的size远远小于数据库,因此可以保存在内存中,那么挖掘速度就可以大大提高.

    也许有人会问?如果这个数据库足够大,以至于构造的FP树大到无法完全保存在内存中,这该如何是好.这的确是个问题. Han Jiawei在论文中也给出了一种思路,就是通过将原来的大的数据库分区成几个小的数据库(这种小的数据库称之为投射数据库),对这几个小的数据库分别进行FP Growth算法.

    还是拿上面的例子来说事,我们把包含p的所有数据库记录都单独存成一个数据库,我们称之为p-投射数据库,类似的m,b,a,c,f我们都可以生成相应的投射数据库,这些投射数据库构成的FP树相对而言大小就小得多,完全可以放在内存里.

    在现代数据挖掘任务中,数据量越来越大,因此并行化的需求越来越大,上面提出的问题也越来越迫切.下一篇博客,博主将分析一下,FP Growth如何在MapReduce的框架下并行化.

    展开全文
  • 已经进行简单数据挖掘,提供完整建模内容 方便上手
  • 源代码 # -*- coding: utf-8 -*- """ @Time : 2020/12/7 @Author : lxc @File : Aprior算法 @Description : """ transaction = { 'T100': ['M', 'O', 'N', 'K', 'E', 'Y'], 'T200': ['D', 'O', 'N', 'K', 'E', 'Y']...

    算法实现思路

    首先,获取事务集和最小支持度。事务集可以采用手动输入,也可以预定义,我在这里使用字典结构预定义事务集,并使用input()方法获取用户输入的最小支持度;
    其次,根据事务集,通过遍历事务集中的每项,获取所有单项集的支持度即C1,同样以字典的方式存储,其中的键为项组成的元组,值为项集的支持度,同时为了保证后续遍历时的前n个项的顺序一致,在遍历C1时,根据排序后的键来进行遍历,筛选出符合最小支持度的频繁单项集L1,同时将不频繁的项集添加至全局变量非频繁项集的集合中;
    接着,编写根据Lk-1生成Ck的函数。如果Lk-1中的键都只由一项组成,那么两两自由组合,如果Lk-1中的键都至少由两项组成,那么将前k-2项相同的两项集组合,生成一个k项集,将所有可能的项集组合完毕就生成了初始的Ck,接着通过遍历全局变量非频繁项集的集合,如果其中某一项是Ck中一项集的子集,那么将该项集从Ck中删除,最终得到的便是Ck;
    再次,编写根据Ck生成Lk的函数。遍历Ck,遍历事务集,如果Ck中的项集是事务集中某事务的子集,那么其支持度+1,得到所有Ck中所有项集的支持度,接着删除不满足最小支持度的项集同时将不满足最小支持度的项集添加至全局变量不频繁项集的集合中;
    最后,编写主函数。设置全局变量,最终频繁项集、不频繁项集和第几层,调用函数获取初始频繁项集L1,更新不频繁项集的集合,获取C2(赋值给C),当C不为空时,不断获取频繁项集Lk和Ck(赋值给C),更新最终频繁项集,直至C为空时,打印最终频繁项集。

    源代码

    # -*- coding: utf-8 -*-
    
    """
    @Time        : 2020/12/7
    @Author      : lixinci
    @File        : Aprior算法
    @Description :
    """
    
    
    transaction = {
        'T100': ['M', 'O', 'N', 'K', 'E', 'Y'],
        'T200': ['D', 'O', 'N', 'K', 'E', 'Y'],
        'T300': ['M', 'A', 'K', 'E'],
        'T400': ['M', 'U', 'C', 'K', 'Y'],
        'T500': ['C', 'O', 'K', 'I', 'E']
    }
    
    
    def find_frequent_one_itemsets(dataset, min_support=1):
        """
        获取L1,及不频繁项集
        """
        C1 = {}
        L1 = {}
        infrequent_item_sets = []
        # 获取C1
        for transaction in dataset.values():
            for item in transaction:
                C1[item] = C1.get(item, 0) + 1
        print("C1:{}".format(C1))
        # 遍历C1,筛选满足最小支持度的项集,生成L1
        for key in sorted(list(C1.keys())):
            if C1[key] >= min_support:
                L1[(key,)] = C1[key]
            else:
                infrequent_item_sets.append((key,))
        return L1, infrequent_item_sets
    
    
    def itemsets_gen(L, infrequent_item_sets=[]):
        """
        根据频繁项集Lk-1生成项集Ck
        """
        C = []
        del_list_index = []
        keys = list(L.keys())
        if len(keys[0]) == 1:
            for i in range(len(keys) - 1):
                for j in range(i + 1, len(keys)):
                    C.append(keys[i] + keys[j])
        else:
            for i in range(len(keys) - 1):
                for j in range(i + 1, len(keys)):
                    if keys[i][:-1].__eq__(keys[j][:-1]):
                        C.append(keys[i] + (keys[j][-1],))
        if infrequent_item_sets:
            for item in infrequent_item_sets:
                for c in C:
                    if set(item).issubset(c):
                        del_list_index.append(C.index(c))
            del_list_index.sort(reverse=True)
            for count in range(len(del_list_index)):
                del C[del_list_index[count]]
        return C
    
    
    def frequent_itemsets_gen(dataset, C, min_support=1):
        """
        根据项集Ck,生成频繁项集Lk和不频繁项集的集合
        """
        L = {}
        tmp_L = {}
        infrequent_item_sets = []
        # 获取所有项集的最持度
        for c in C:
            for transaction in dataset.values():
                if set(c).issubset(transaction):
                    tmp_L[c] = tmp_L.get(c, 0) + 1
                else:
                    tmp_L[c] = tmp_L.setdefault(c, 0)
        # 去除不满足最小支持度的项集
        for key in tmp_L:
            if tmp_L[key] >= min_support:
                L[key] = tmp_L[key]
            else:
                infrequent_item_sets.append(tuple(key))
        return L, infrequent_item_sets
    
    
    # 主函数
    def main():
        global frequent_itemsets, infrequent_item_sets, count
        infrequent_item_sets = []  # 不频繁项集
        frequent_itemsets = []  # 频繁项集
        count = 1  # 第几次遍历
        min_support = eval(input("请输入最小支持度计数:"))
    
        # 获取初始频繁项集
        L1, infrequent_item_sets_part = find_frequent_one_itemsets(
            transaction, min_support)
        print("L{}:{}".format(count, L1))
        # 设置初始频繁项集为L1
        frequent_itemsets = L1
        # 更新初不频繁项集
        infrequent_item_sets += infrequent_item_sets_part
    
        count += 1
        # 获取第二个项集
        C = itemsets_gen(L1, infrequent_item_sets)
        print("C{}:{}".format(count, C))
        # 遍历获取频繁项集
        while C:
            # 获取频繁项集和不频繁项集
            L, infrequent_item_sets_part = frequent_itemsets_gen(
                transaction, C, min_support)
            print("L{}:{}".format(count, L))
            # 更新不频繁项集库
            infrequent_item_sets += infrequent_item_sets_part
            frequent_itemsets = L
            count += 1
            C = itemsets_gen(frequent_itemsets, infrequent_item_sets)
            print("C{}:{}".format(count, C))
        print("最终频繁项集:", end='')
        print(frequent_itemsets)
    
    
    if __name__ == '__main__':
        main()
    
    
    展开全文
  • aprior源代码及实现

    2010-09-05 22:01:31
    aprior算法,是经典的数据挖掘算法,在关联规则数据挖掘中是最基本的算法。
  • 寻找最大K项频繁集的Aprior算法

    千次阅读 2019-08-09 14:45:51
    这些算法利用了Aprior算法的思想,但是对算法做了改进,数据挖掘效率更好一些,因此现在一般很少直接用Aprior算法来挖掘数据了,但是理解Aprior算法是理解其它Aprior类算法的前提,同时算法本身也不复杂,因此值得...
  • Aprior原理 当商品数量大的时候,如果要遍历每一种可能集合的支持度,计算时间是不允许的。为了降低所需的计算时间,我们可以采用Apriori 原理来帮我们减少可能感兴趣的项集。Aprori原理是说,如果某个项集是...
  • Aprior算法–菜单支持度与置信度 刚开始学习数据挖掘,有很多不明白的地方,还希望各位大佬指点迷津。最近我们学到了挖掘建模里的关联规则,老师布置了一个题目用Apriori算法计算菜单的支持度与置信度,从而推出...
  • 基于Hadoop的Aprior算法改进及其在动车组运维的应用.pdf
  • Aprior算法主要有两个操作,扫描数据库+统计。计算每一阶频繁项集都要扫描一次数据库并且统计出满足支持度的n阶项集。 【算法主要步骤】 一、频繁一项集 算法开始第一步,通过扫描数据库,统计出每条记录中出现的...
  • 在谈到这个算法之前,我们先声明一个在频繁模式挖掘中的一个特性-Aprior特性。 Aprior特性: 这个特性是指如果一个Item set(项目集合)不是frequent item set(频繁集合),那么任何包含它的项目集合一定也...
  • 关联规则算法-Aprior

    万次阅读 2017-04-17 09:41:52
    所以Aprior算法提出了一个逐层搜索的方法,如何逐层搜索呢?包含两个步骤: 1.自连接获取候选集。第一轮的候选集就是数据集D中的项,而其他轮次的候选集则是由前一轮次频繁集自连接得到(频繁集由候选集剪枝得到...
  • 这是一个关于数据挖掘中关联规则之Aprior算法的实现。这是从网上找到的一个别人写好的程序,本人只是对这个程序进行了轻微的修改;本人忘记了这个程序是由谁写的,所以如果您发现这个程序的原创作者,可以联系本人,...
  • 这是C++写的Aprior寻找频繁项集的程序 在输入输出流中更改一下后就可以 完成老师的字符数组例子,但是 要注意输入的格式。这里还附带老师的例子的运行
  • Aprior算法的实现

    2018-12-15 21:16:11
    那么对于离散值的3*7*5的一百多中可能的组合,每一种组合和另外的0-1变量相组合,来进行一次Aprior算法的调用,然后把这一百多个计算结果进行合并和排序,得到最终的频繁项集的计算结果。其实,在每一种组合中,数据...
  • 关联规则挖掘是数据挖掘中十分基础的一部分东西,而aprior算法一般作为关联规则挖掘算法学习的敲门砖。具体的算法细节网上有许多的文章博客可供参考,这里推荐一篇:...
  • 西电数据挖掘作业——关联规则aprior算法python实现,我自己在python3.6已经能够成功实现,没有问题
  • 数据挖掘系列(1)关联规则挖掘基本概念与Aprior算法 原文URL:http://www.cnblogs.com/fengfenggirl/p/associate_apriori.html#2752667  我计划整理数据挖掘的基本概念和算法,包括关联规则挖掘、分类、...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 775
精华内容 310
关键字:

Aprior