简单易学的机器学习算法——Apriori算法

本文详细介绍了Apriori算法的工作原理及其在关联分析中的应用,包括频繁项集的生成过程和算法实现步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文转自:http://blog.youkuaiyun.com/google19890102/article/details/41448979

一、关联分析

    最初接触到数据挖掘的朋友肯定都听说过这样的一个案例:啤酒和尿布。大意是将啤酒和尿布放在一起的销售会提高。其实这背后隐含的原理就是关联分析,简单来讲就是啤酒和尿布之间存在着某种关联关系。关联关系时指从大规模的数据集中寻找物品之间的隐含关系,有时关联分析也可以称为关联规则学习。

二、关联分析的重要概念

    关联分析主要要做的工作是在大规模数据集上找到某些关系。主要有两种形式:
  • 频繁项集
  • 关联关系
    对于一个具体的例子:

(摘自《机器学习实战》)

1、频繁项集

    频繁项集是指经常出现在一起的物品的集合。如上面的例子中的是一个项集,要使得这样的项集成为频繁项集,是指该项集在数据集中出现的次数大于某个阈值,便被称为频繁项集。

2、关联关系

    关联关系是指两种物品之间可能存在很强的关系。如上面的例子中的的规则。

3、支持度

    支持度是指数据集中包含某个项集的记录所占的比例。如项集的支持度为

4、可信度

    可信度是针对一条关联规则的,如关联规则的可信度为“支持度/支持度”,即为

三、Apriori算法

1、Apriori算法

        Apriori 算法是关联分析的重要算法, Apriori 算法主要是来寻找频繁项集,采用的方法是查找出所有的可能,如下图:

(摘自《机器学习实战》)
如上图所示,四种物品:0,1,2,3。列出所有的组合:、...、。这里就会出现一个问题,如果物品的数目变大,这种组合是呈现指数级的增长的:,其中为物品的数目,如何避免这样的指数增长对于 Apriori 算法的成功具有很重要的意义。Apriori原理就解释了这样的事情。

2、Apriori原理

    如何避免指数级增长,我们应该尽量去减少一些不必要的结点, Apriori 原理是说如果某个项集是频繁的,那么他的所有子集也是频繁的。其逆否命题为:如果一个项集是非频繁的,那么他的所有超集也是非频繁的。使用这个原理就可以避免指数级增长,原理如下图所示:

(摘自《机器学习实战》)

四、使用Apriori算法发现频繁项集

     在理解了上面的过程后,我们不难发现计算过程就是不断查找项集。首先,定义一个被称为最小支持度的量,当成阈值使用。大于这个阈值便是频繁项集,否则不是。接下来就开始计算,首先生成只含有单项的项集,如上图所示:,并计算每个项集的支持度,与阈值比对。如上图所示都为频繁项集;接着生成含有两个元素的项集,如:等等,结果发现不是频繁项集,则去除掉。继续下去,一直到没有项集为止。上述的过程可以抽象为:其中表示候选集,表示频繁项集。

(实现过程)
五、从频繁项集中挖掘关联规则

六、Matlab实现

1、频繁项集

主函数
[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. %% 主函数  
  2. clear all;  
  3. clc;  
  4.   
  5. %% 导入数据  
  6. % 数据集中的0表示无  
  7. dataSet = load('data.txt');  
  8.   
  9. % %构建第一个候选集C1  
  10. % C1 = createC1(dataSet);  
  11. %   
  12. % %构建第一个频繁项集L1  
  13. % [retList, supportData] = scanD(dataSet, C1, 0.7)  
  14.   
  15. % 调用产生频繁项集  
  16. [L, supportData] = apriori(dataSet, 0.5);  

查找候选集C1
[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. %% 查找候选集C1  
  2. function [ C1 ] = createC1( dataSet )  
  3.     C1 = unique(dataSet);%取得所有相异元素  
  4. end  

生成频繁项集
[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. %% 计算频繁项集L1  
  2. function [ retList, supportData ] = scanD( dataSet, Ck, minSupport )  
  3.     [m,n] = size(Ck);  
  4.     if m==0  
  5.         retList = [];  
  6.         supportData = 0;  
  7.     else  
  8.         if n==1  
  9.             Ck(Ck==0)=[];%将候选集中的0去掉  
  10.             [m,n] = size(Ck);%获得候选集的大小,注意候选集的大小  
  11.             [m_1,n_1] = size(dataSet);%获得整个数据集的大小  
  12.             %% 统计候选集中的元素在dataSet中出现的次数  
  13.             dataNum = zeros(m,1);  
  14.             for i = 1:m%行数为候选集中元素的个数  
  15.                 for j = 1:m_1  
  16.                     if all(ismember(Ck(i,:), dataSet(j,:)))==1  
  17.                         dataNum(i,1) = dataNum(i,1)+1;  
  18.                     end  
  19.                 end  
  20. %           if all(ismember(Ck(i,:), dataSet))==1  
  21. %               dataNum(i,1) = dataNum(i,1)+1;  
  22. %           end  
  23.             end  
  24.         else  
  25.             [m,n] = size(Ck);%获得候选集的大小,注意候选集的大小  
  26.             [m_1,n_1] = size(dataSet);%获得整个数据集的大小  
  27.             %% 统计候选集中的元素在dataSet中出现的次数  
  28.             dataNum = zeros(m,1);  
  29.             for i = 1:m%行数为候选集中元素的个数  
  30.                 tmp = Ck(i,:);  
  31.                 tmp(tmp==0)=[];%将候选集中的0去掉  
  32.                 for j = 1:m_1  
  33.                     if all(ismember(tmp, dataSet(j,:)))==1  
  34.                         dataNum(i,1) = dataNum(i,1)+1;  
  35.                     end  
  36.                 end  
  37. %           if all(ismember(Ck(i,:), dataSet))==1  
  38. %               dataNum(i,1) = dataNum(i,1)+1;  
  39. %           end  
  40.             end  
  41.         end  
  42.         %% 计算每个元素出现的比率  
  43.         numItems = length(dataSet);  
  44.         supportData = zeros(length(dataNum), 1);  
  45.         retListSize = 1;  
  46.         for i = 1:length(dataNum)  
  47.             supportData(i, 1) = dataNum(i, 1)/numItems;  
  48.             if supportData(i ,1) >= minSupport  
  49.                 retList(retListSize, :) = Ck(i, :);  
  50.                 retListSize = retListSize+1;  
  51.             end  
  52.         end  
  53.     end  
  54. end  

生成后续的候选集
[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. function [ retList ] = aprioriGen( Lk )  
  2.     [m,n] = size(Lk);%得到Lk矩阵的大小  
  3.     r = 1;  
  4.     for i = 1:m-1  
  5.         for j = i+1:m  
  6.             retListTmp_1(r,:) = [Lk(i,:),Lk(j,:)];  
  7.             tmp = unique(retListTmp_1(r,:));  
  8.             if length(tmp)<2*n  
  9.                 tmp(1,2*n) = 0;%补0  
  10.             end  
  11.             retListTmp_2(r,:) = tmp;  
  12.             r = r+1;  
  13.         end  
  14.     end  
  15.     if m~=1  
  16.         retList=unique(retListTmp_2,'rows');  
  17.     else  
  18.         retList=[];  
  19.     end  
  20. end  

总的生成频繁项集的模块
[plain]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. %% 控制整个频繁项集的生成  
  2. function [ L, supportData ] = apriori( dataSet, minSupport )  
  3.     C1 = createC1(dataSet)%生成最初的候选集  
  4.     [L1, supportData] = scanD(dataSet, C1, minSupport)%生成最初的频繁项集  
  5.     L = L1;  
  6.     while ~isempty(L)  
  7.         Ck = aprioriGen(L)  
  8.         [Lk, supportData] = scanD(dataSet, Ck, minSupport)  
  9.         L = Lk;  
  10.     end  
  11. end  

实现
第一步:

第二步:

第三步:

第四步:




在维基百科中的图解例子,

假设有一个数据库D,其中有4个事务记录,分别表示为:

TID Items
T1I1,I3,I4
T2I2,I3,I5
T3I1,I2,I3,I5
T4I2,I5

这裡预定最小支持度minSupport=2,下面用图例说明算法运行的过程:

TID Items
T1I1,I3,I4
T2I2,I3,I5
T3I1,I2,I3,I5
T4I2,I5

扫描D,对每个候选项进行支持度计数得到表C1:

项集 支持度计数
{I1}2
{I2}3
{I3}3
{I4}1
{I5}3

比较候选项支持度计数与最小支持度minSupport,产生1维最大项目集L1:

项集 支持度计数
{I1}2
{I2}3
{I3}3
{I5}3

由L1产生候选项集C2:

项集
{I1,I2}
{I1,I3}
{I1,I5}
{I2,I3}
{I2,I5}
{I3,I5}

扫描D,对每个候选项集进行支持度计数:

项集 支持度计数
{I1,I2}1
{I1,I3}2
{I1,I5}1
{I2,I3}2
{I2,I5}3
{I3,I5}2

比较候选项支持度计数与最小支持度minSupport,产生2维最大项目集L2:

项集 支持度计数
{I1,I3}2
{I2,I3}2
{I2,I5}3
{I3,I5}2

由L2产生候选项集C3:

项集
{I2,I3,I5}

扫描D,对每个候选项集进行支持度计数:

项集 支持度计数
{I2,I3,I5}2

比较候选项支持度计数与最小支持度minSupport,产生3维最大项目集L3:

项集 支持度计数
{I2,I3,I5}2

算法终止。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值