码迷,mamicode.com
首页 > 编程语言 > 详细

用关联算法做协同过滤:

时间:2019-07-26 21:30:55      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:合作   相同   二层   限制   评分   col   字母   子集   row   

一般我们可以找出用户购买的所有去拼数据里频繁出现的项集序列,然后做频繁集挖掘,找到满足支持度阈值的关联去拼的频繁N项集或者序列。如果用户购买了频繁项集N项集或者序列里的部分商品,那么我们就可以将频繁序列或频繁项集里的其他物品按移动的评分规则推荐给用户,这个评分规则可以包括支持度、置信度和提升度等。

  • 关联规则常用的算法有:
  1.  Apriori算法
  2.     FP Tree(FP-Growth)算法
  3.   PrefixSpan算法

    

1、Apriori算法

首先,先理解上面提到的评分规则:

支持度:几个关联的数据在数据集中出现的次数占总数据集的比重。

置信度:一个数据出现后,另一个数据出现的概率

提升度:提升度表示含有Y的条件下,同时含有X的概率,与X总体发生的概率之比。

 

对于Apriori算法,我们使用支持度来作为我们判断频繁项集的标准。Apriori算法的目标是找到最大的K项频繁集。这里有两层意思,首先,我们要找到符合支持度标准的频繁集。但是这样的频繁集可能有很多。第二层意思就是我们要找到最大个数的频繁集。

Apriori算法采用了迭代的方法,先搜索出候选1项集及对应的支持度,剪枝去掉低于支持度的1项集,得到频繁1项集。然后对剩下的频繁1项集进行连接,得到候选的频繁2项集,筛选去掉低于支持度的候选频繁2项集,得到真正的频繁二项集,以此类推,迭代下去,直到无法找到频繁k+1项集为止,对应的频繁k项集的集合即为算法的输出结果。

如果某一个项集是频繁项集,那么他的所有子集也是频繁项集,反过来就是说:如果一个项集是非频繁项集那么他的所有超集也是非频繁的。

算法步骤:

输入:数据集合D,支持度阈值αα

输出:最大的频繁k项集

    1)扫描整个数据集,得到所有出现过的数据,作为候选频繁1项集。k=1,频繁0项集为空集。

    2)挖掘频繁k项集   

      a) 扫描数据计算候选频繁k项集的支持度

      b) 去除候选频繁k项集中支持度低于阈值的数据集,得到频繁k项集。如果得到的频繁k项集为空,则直接返回频繁k-1项集的集合作为算法结果,算法结束。如果得到的频繁k项集只有一项,则直接返回频繁k项集的集合作为算法结果,算法结束。

      c) 基于频繁k项集,连接生成候选频繁k+1项集。

    3) 令k=k+1,转入步骤2。

  从算法的步骤可以看出,Aprior算法每轮迭代都要扫描数据集,因此在数据集很大,数据种类很多的时候,算法效率很低。

 

2、FP Tree(FP-Growth)算法

  主要三个部分:

    项头表    里面记录了所有的1项频繁集出现的次数,按照次数降序排列

    FP Tree     将我们的原始数据集映射到了内存中的一颗FP树

    节点链表    所有项头表里的1项频繁集都是一个节点链表的头,它依次指向FP树中该1项频繁集出现的位置。

(1)项表头的建立

我们第一次扫描数据,得到所有频繁一项集的的计数。然后删除支持度低于阈值的项,将1项频繁集放入项头表,并按照支持度降序排列。接着第二次也是最后一次扫描数据,将读到的原始数据剔除非频繁1项集,并按照支持度降序排列。

(2)FP Tree的建立

有了项头表和排序后的数据集,我们就可以开始FP树的建立了。开始时FP树没有数据,建立FP树时我们一条条的读入排序后的数据集,插入FP树,插入时按照排序后的顺序,插入FP树中,排序靠前的节点是祖先节点,而靠后的是子孙节点。如果有共用的祖先,则对应的公用祖先节点计数加1。插入后,如果有新节点出现,则项头表对应的节点会通过节点链表链接上新节点。直到所有的数据都插入到FP树后,FP树的建立完成。

(3) FP Tree的挖掘

得到了FP树和项头表以及节点链表,我们首先要从项头表的底部项依次向上挖掘。对于项头表对应于FP树的每一项,我们要找到它的条件模式基。所谓条件模式基是以我们要挖掘的节点作为叶子节点所对应的FP子树。得到这个FP子树,我们将子树中每个节点的的计数设置为叶子节点的计数,并删除计数低于支持度的节点。从这个条件模式基,我们就可以递归挖掘得到频繁项集了。

FP Tree的步骤:

 

    1)扫描数据,得到所有频繁一项集的的计数。然后删除支持度低于阈值的项,将1项频繁集放入项头表,并按照支持度降序排列。

 

    2)扫描数据,将读到的原始数据剔除非频繁1项集,并按照支持度降序排列。

 

    3)读入排序后的数据集,插入FP树,插入时按照排序后的顺序,插入FP树中,排序靠前的节点是祖先节点,而靠后的是子孙节点。如果有共用的祖先,则对应的公用祖先节点计数加1。插入后,如果有新节点出现,则项头表对应的节点会通过节点链表链接上新节点。直到所有的数据都插入到FP树后,FP树的建立完成。

 

    4)从项头表的底部项依次向上找到项头表项对应的条件模式基。从条件模式基递归挖掘得到项头表项项的频繁项集。

 

    5)如果不限制频繁项集的项数,则返回步骤4所有的频繁项集,否则只返回满足项数要求的频繁项集。

 

 

 

3、PrefixSpan算法

在Apriori和FP Tree算法中我们也已经看到过了,每个项集数据由若干项组成,这些项没有时间上的先后关系。序列数据则不一样,它是由若干数据项集组成的序列。比如第一个序列<a(abc)(ac)d(cf)>,它由a,abc,ac,d,cf共5个项集数据组成,并且这些项有时间上的先后关系。对于多于一个项的项集我们要加上括号,以便和其他的项集分开。同时由于项集内部是不区分先后顺序的,为了方便数据处理,我们一般将序列数据内所有的项集内部按字母顺序排序。

(1)子序列与频繁序列

子序列和我们数学上的子集的概念很类似,也就是说,如果某个序列A所有的项集在序列B中的项集都可以找到,则A就是B的子序列。

频繁序列则和我们的频繁项集很类似,也就是频繁出现的子序列。

 

(2)PrefixSpan的一些概念

PrefixSpan算法的全称是Prefix-Projected Pattern Growth,即前缀投影的模式挖掘。里面有前缀和投影两个词。那么我们首先看看什么是PrefixSpan算法中的前缀prefix。

在PrefixSpan算法中的前缀prefix通俗意义讲就是序列数据前面部分的子序列。比如对于序列数据B=<a(abc)(ac)d(cf)>,而A=<a(abc)a>,则A是B的前缀。当然B的前缀不止一个,比如<a>, <aa>, <a(ab)> 也都是B的前缀。

看了前缀,我们再来看前缀投影,其实前缀投影这儿就是我们的后缀,有前缀就有后缀嘛。前缀加上后缀就可以构成一个我们的序列。下面给出前缀和后缀的例子。对于某一个前缀,序列里前缀后面剩下的子序列即为我们的后缀。如果前缀最后的项是项集的一部分,则用一个“_”来占位表示。

下面这个例子展示了序列<a(abc)(ac)d(cf)>的一些前缀和后缀,还是比较直观的。要注意的是,如果前缀的末尾不是一个完全的项集,则需要加一个占位符。

在PrefixSpan算法中,相同前缀对应的所有后缀的结合我们称为前缀对应的投影数据库。

(3)PrefixSpan算法思想

现在我们来看看PrefixSpan算法的思想,PrefixSpan算法的目标是挖掘出满足最小支持度的频繁序列。那么怎么去挖掘出所有满足要求的频繁序列呢。回忆Aprior算法,它是从频繁1项集出发,一步步的挖掘2项集,直到最大的K项集。PrefixSpan算法也类似,它从长度为1的前缀开始挖掘序列模式,搜索对应的投影数据库得到长度为1的前缀对应的频繁序列,然后递归的挖掘长度为2的前缀所对应的频繁序列,。。。以此类推,一直递归到不能挖掘到更长的前缀挖掘为止。

(4)算法步骤

    输入:序列数据集S和支持度阈值αα

    输出:所有满足支持度要求的频繁序列集

    1)找出所有长度为1的前缀和对应的投影数据库

    2)对长度为1的前缀进行计数,将支持度低于阈值αα的前缀对应的项从数据集S删除,同时得到所有的频繁1项序列,i=1.

    3)对于每个长度为i满足支持度要求的前缀进行递归挖掘:

      a) 找出前缀所对应的投影数据库。如果投影数据库为空,则递归返回。

      b) 统计对应投影数据库中各项的支持度计数。如果所有项的支持度计数都低于阈值αα,则递归返回。

      c) 将满足支持度计数的各个单项和当前的前缀进行合并,得到若干新的前缀。

      d) 令i=i+1,前缀为合并单项后的各个前缀,分别递归执行第3步。

 

 

参考:https://www.cnblogs.com/pinard/p/6349233.html

 

用关联算法做协同过滤:

标签:合作   相同   二层   限制   评分   col   字母   子集   row   

原文地址:https://www.cnblogs.com/spp666/p/11252866.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!