急需C++实现的Apriori算法代码

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了急需C++实现的Apriori算法代码相关的知识,希望对你有一定的参考价值。

急需C++实现的Apriori算法代码
有的可以发到我邮箱里
annstory@126.com
方便的话留下联系方式,我希望可以和了解的探讨下。

参考技术A 用C++ 实现的 可以 到http://download.csdn.net/down/188143/chanjuanzz下载 不过要注册扣积分的

算法实现

(一)核心类

Apriori算法的核心实现类为AprioriAlgorithm,实现的Java代码如下所示:

package org.shirdrn.datamining.association;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/**
* <B>关联规则挖掘:Apriori算法</B>
*
* <P>该算法基本上按照Apriori算法的基本思想来实现的。
*
* @author shirdrn
* @date 2009/07/22 22:56:23
* @msn shirdrn#hotmail.com(#→@)
* @qq 187071722
*/
public class AprioriAlgorithm

private Map<Integer, Set<String>> txDatabase; // 事务数据库
private Float minSup; // 最小支持度
private Float minConf; // 最小置信度
private Integer txDatabaseCount; // 事务数据库中的事务数

private Map<Integer, Set<Set<String>>> freqItemSet; // 频繁项集集合
private Map<Set<String>, Set<Set<String>>> assiciationRules; // 频繁关联规则集合

public AprioriAlgorithm(
Map<Integer, Set<String>> txDatabase,
Float minSup,
Float minConf)
this.txDatabase = txDatabase;
this.minSup = minSup;
this.minConf = minConf;
this.txDatabaseCount = this.txDatabase.size();
freqItemSet = new TreeMap<Integer, Set<Set<String>>>();
assiciationRules = new HashMap<Set<String>, Set<Set<String>>>();


/**
* 扫描事务数据库,计算频繁1-项集
* @return
*/
public Map<Set<String>, Float> getFreq1ItemSet()
Map<Set<String>, Float> freq1ItemSetMap = new HashMap<Set<String>, Float>();
Map<Set<String>, Integer> candFreq1ItemSet = this.getCandFreq1ItemSet();
Iterator<Map.Entry<Set<String>, Integer>> it = candFreq1ItemSet.entrySet().iterator();
while(it.hasNext())
Map.Entry<Set<String>, Integer> entry = it.next();
// 计算支持度
Float supported = new Float(entry.getValue().toString())/new Float(txDatabaseCount);
if(supported>=minSup)
freq1ItemSetMap.put(entry.getKey(), supported);


return freq1ItemSetMap;


/**
* 计算候选频繁1-项集
* @return
*/
public Map<Set<String>, Integer> getCandFreq1ItemSet()
Map<Set<String>, Integer> candFreq1ItemSetMap = new HashMap<Set<String>, Integer>();
Iterator<Map.Entry<Integer, Set<String>>> it = txDatabase.entrySet().iterator();
// 统计支持数,生成候选频繁1-项集
while(it.hasNext())
Map.Entry<Integer, Set<String>> entry = it.next();
Set<String> itemSet = entry.getValue();
for(String item : itemSet)
Set<String> key = new HashSet<String>();
key.add(item.trim());
if(!candFreq1ItemSetMap.containsKey(key))
Integer value = 1;
candFreq1ItemSetMap.put(key, value);

else
Integer value = 1+candFreq1ItemSetMap.get(key);
candFreq1ItemSetMap.put(key, value);



return candFreq1ItemSetMap;


/**
* 根据频繁(k-1)-项集计算候选频繁k-项集
*
* @param m 其中m=k-1
* @param freqMItemSet 频繁(k-1)-项集
* @return
*/
public Set<Set<String>> aprioriGen(int m, Set<Set<String>> freqMItemSet)
Set<Set<String>> candFreqKItemSet = new HashSet<Set<String>>();
Iterator<Set<String>> it = freqMItemSet.iterator();
Set<String> originalItemSet = null;
while(it.hasNext())
originalItemSet = it.next();
Iterator<Set<String>> itr = this.getIterator(originalItemSet, freqMItemSet);
while(itr.hasNext())
Set<String> identicalSet = new HashSet<String>(); // 两个项集相同元素的集合(集合的交运算)
identicalSet.addAll(originalItemSet);
Set<String> set = itr.next();
identicalSet.retainAll(set); // identicalSet中剩下的元素是identicalSet与set集合中公有的元素
if(identicalSet.size() == m-1) // (k-1)-项集中k-2个相同
Set<String> differentSet = new HashSet<String>(); // 两个项集不同元素的集合(集合的差运算)
differentSet.addAll(originalItemSet);
differentSet.removeAll(set); // 因为有k-2个相同,则differentSet中一定剩下一个元素,即differentSet大小为1
differentSet.addAll(set); // 构造候选k-项集的一个元素(set大小为k-1,differentSet大小为k)
candFreqKItemSet.add(differentSet); // 加入候选k-项集集合



return candFreqKItemSet;


/**
* 根据一个频繁k-项集的元素(集合),获取到频繁k-项集的从该元素开始的迭代器实例
* @param itemSet
* @param freqKItemSet 频繁k-项集
* @return
*/
private Iterator<Set<String>> getIterator(Set<String> itemSet, Set<Set<String>> freqKItemSet)
Iterator<Set<String>> it = freqKItemSet.iterator();
while(it.hasNext())
if(itemSet.equals(it.next()))
break;


return it;


/**
* 根据频繁(k-1)-项集,调用aprioriGen方法,计算频繁k-项集
*
* @param k
* @param freqMItemSet 频繁(k-1)-项集
* @return
*/
public Map<Set<String>, Float> getFreqKItemSet(int k, Set<Set<String>> freqMItemSet)
Map<Set<String>, Integer> candFreqKItemSetMap = new HashMap<Set<String>, Integer>();
// 调用aprioriGen方法,得到候选频繁k-项集
Set<Set<String>> candFreqKItemSet = this.aprioriGen(k-1, freqMItemSet);

// 扫描事务数据库
Iterator<Map.Entry<Integer, Set<String>>> it = txDatabase.entrySet().iterator();
// 统计支持数
while(it.hasNext())
Map.Entry<Integer, Set<String>> entry = it.next();
Iterator<Set<String>> kit = candFreqKItemSet.iterator();
while(kit.hasNext())
Set<String> kSet = kit.next();
Set<String> set = new HashSet<String>();
set.addAll(kSet);
set.removeAll(entry.getValue()); // 候选频繁k-项集与事务数据库中元素做差元算
if(set.isEmpty()) // 如果拷贝set为空,支持数加1
if(candFreqKItemSetMap.get(kSet) == null)
Integer value = 1;
candFreqKItemSetMap.put(kSet, value);

else
Integer value = 1+candFreqKItemSetMap.get(kSet);
candFreqKItemSetMap.put(kSet, value);




// 计算支持度,生成频繁k-项集,并返回
return support(candFreqKItemSetMap);


/**
* 根据候选频繁k-项集,得到频繁k-项集
*
* @param candFreqKItemSetMap 候选k项集(包含支持计数)
*/
public Map<Set<String>, Float> support(Map<Set<String>, Integer> candFreqKItemSetMap)
Map<Set<String>, Float> freqKItemSetMap = new HashMap<Set<String>, Float>();
Iterator<Map.Entry<Set<String>, Integer>> it = candFreqKItemSetMap.entrySet().iterator();
while(it.hasNext())
Map.Entry<Set<String>, Integer> entry = it.next();
// 计算支持度
Float supportRate = new Float(entry.getValue().toString())/new Float(txDatabaseCount);
if(supportRate<minSup) // 如果不满足最小支持度,删除
it.remove();

else
freqKItemSetMap.put(entry.getKey(), supportRate);


return freqKItemSetMap;


/**
* 挖掘全部频繁项集
*/
public void mineFreqItemSet()
// 计算频繁1-项集
Set<Set<String>> freqKItemSet = this.getFreq1ItemSet().keySet();
freqItemSet.put(1, freqKItemSet);
// 计算频繁k-项集(k>1)
int k = 2;
while(true)
Map<Set<String>, Float> freqKItemSetMap = this.getFreqKItemSet(k, freqKItemSet);
if(!freqKItemSetMap.isEmpty())
this.freqItemSet.put(k, freqKItemSetMap.keySet());
freqKItemSet = freqKItemSetMap.keySet();

else
break;

k++;



/**
* <P>挖掘频繁关联规则
* <P>首先挖掘出全部的频繁项集,在此基础上挖掘频繁关联规则
*/
public void mineAssociationRules()
freqItemSet.remove(1); // 删除频繁1-项集
Iterator<Map.Entry<Integer, Set<Set<String>>>> it = freqItemSet.entrySet().iterator();
while(it.hasNext())
Map.Entry<Integer, Set<Set<String>>> entry = it.next();
for(Set<String> itemSet : entry.getValue())
// 对每个频繁项集进行关联规则的挖掘
mine(itemSet);




/**
* 对从频繁项集集合freqItemSet中每迭代出一个频繁项集元素,执行一次关联规则的挖掘
* @param itemSet 频繁项集集合freqItemSet中的一个频繁项集元素
*/
public void mine(Set<String> itemSet)
int n = itemSet.size()/2; // 根据集合的对称性,只需要得到一半的真子集
for(int i=1; i<=n; i++)
// 得到频繁项集元素itemSet的作为条件的真子集集合
Set<Set<String>> properSubset = ProperSubsetCombination.getProperSubset(i, itemSet);
// 对条件的真子集集合中的每个条件项集,获取到对应的结论项集,从而进一步挖掘频繁关联规则
for(Set<String> conditionSet : properSubset)
Set<String> conclusionSet = new HashSet<String>();
conclusionSet.addAll(itemSet);
conclusionSet.removeAll(conditionSet); // 删除条件中存在的频繁项
confide(conditionSet, conclusionSet); // 调用计算置信度的方法,并且挖掘出频繁关联规则




/**
* 对得到的一个条件项集和对应的结论项集,计算该关联规则的支持计数,从而根据置信度判断是否是频繁关联规则
* @param conditionSet 条件频繁项集
* @param conclusionSet 结论频繁项集
*/
public void confide(Set<String> conditionSet, Set<String> conclusionSet)
// 扫描事务数据库
Iterator<Map.Entry<Integer, Set<String>>> it = txDatabase.entrySet().iterator();
// 统计关联规则支持计数
int conditionToConclusionCnt = 0; // 关联规则(条件项集推出结论项集)计数
int conclusionToConditionCnt = 0; // 关联规则(结论项集推出条件项集)计数
int supCnt = 0; // 关联规则支持计数
while(it.hasNext())
Map.Entry<Integer, Set<String>> entry = it.next();
Set<String> txSet = entry.getValue();
Set<String> set1 = new HashSet<String>();
Set<String> set2 = new HashSet<String>();
set1.addAll(conditionSet);

set1.removeAll(txSet); // 集合差运算:set-txSet
if(set1.isEmpty()) // 如果set为空,说明事务数据库中包含条件频繁项conditionSet
// 计数
conditionToConclusionCnt++;

set2.addAll(conclusionSet);
set2.removeAll(txSet); // 集合差运算:set-txSet
if(set2.isEmpty()) // 如果set为空,说明事务数据库中包含结论频繁项conclusionSet
// 计数
conclusionToConditionCnt++;


if(set1.isEmpty() && set2.isEmpty())
supCnt++;


// 计算置信度
Float conditionToConclusionConf = new Float(supCnt)/new Float(conditionToConclusionCnt);
if(conditionToConclusionConf>=minConf)
if(assiciationRules.get(conditionSet) == null) // 如果不存在以该条件频繁项集为条件的关联规则
Set<Set<String>> conclusionSetSet = new HashSet<Set<String>>();
conclusionSetSet.add(conclusionSet);
assiciationRules.put(conditionSet, conclusionSetSet);

else
assiciationRules.get(conditionSet).add(conclusionSet);


Float conclusionToConditionConf = new Float(supCnt)/new Float(conclusionToConditionCnt);
if(conclusionToConditionConf>=minConf)
if(assiciationRules.get(conclusionSet) == null) // 如果不存在以该结论频繁项集为条件的关联规则
Set<Set<String>> conclusionSetSet = new HashSet<Set<String>>();
conclusionSetSet.add(conditionSet);
assiciationRules.put(conclusionSet, conclusionSetSet);

else
assiciationRules.get(conclusionSet).add(conditionSet);




/**
* 经过挖掘得到的频繁项集Map
*
* @return 挖掘得到的频繁项集集合
*/
public Map<Integer, Set<Set<String>>> getFreqItemSet()
return freqItemSet;


/**
* 获取挖掘到的全部的频繁关联规则的集合
* @return 频繁关联规则集合
*/
public Map<Set<String>, Set<Set<String>>> getAssiciationRules()
return assiciationRules;



(二)辅助类

ProperSubsetCombination类是一个辅助类,在挖掘频繁关联规则的过程中,用于生成一个频繁项集元素的非空真子集,实现代码如下:

package org.shirdrn.datamining.association;
import java.util.BitSet;
import java.util.HashSet;
import java.util.Set;

/**
* <B>求频繁项集元素(集合)的非空真子集集合</B>
* <P>从一个集合(大小为n)中取出m(m属于2~n/2的闭区间)个元素的组合实现类,获取非空真子集的集合
*
* @author shirdrn
* @date 2009/07/22 22:56:23
* @msn shirdrn#hotmail.com(#→@)
* @qq 187071722
*/
public class ProperSubsetCombination

private static String[] array;
private static BitSet startBitSet; // 比特集合起始状态
private static BitSet endBitSet; // 比特集合终止状态,用来控制循环
private static Set<Set<String>> properSubset; // 真子集集合

/**
* 计算得到一个集合的非空真子集集合
*
* @param n 真子集的大小
* @param itemSet 一个频繁项集元素
* @return 非空真子集集合
*/
public static Set<Set<String>> getProperSubset(int n, Set<String> itemSet)
String[] array = new String[itemSet.size()];
ProperSubsetCombination.array = itemSet.toArray(array);
properSubset = new HashSet<Set<String>>();
startBitSet = new BitSet();
endBitSet = new BitSet();

// 初始化startBitSet,左侧占满1
for (int i=0; i<n; i++)
startBitSet.set(i, true);


// 初始化endBit,右侧占满1
for (int i=array.length-1; i>=array.length-n; i--)
endBitSet.set(i, true);


// 根据起始startBitSet,将一个组合加入到真子集集合中
get(startBitSet);

while(!startBitSet.equals(endBitSet))
int zeroCount = 0; // 统计遇到10后,左边0的个数
int oneCount = 0; // 统计遇到10后,左边1的个数
int pos = 0; // 记录当前遇到10的索引位置

// 遍历startBitSet来确定10出现的位置
for (int i=0; i<array.length; i++)
if (!startBitSet.get(i))
zeroCount++;

if (startBitSet.get(i) && !startBitSet.get(i+1))
pos = i;
oneCount = i - zeroCount;
// 将10变为01
startBitSet.set(i, false);
startBitSet.set(i+1, true);
break;


// 将遇到10后,左侧的1全部移动到最左侧
int counter = Math.min(zeroCount, oneCount);
int startIndex = 0;
int endIndex = 0;
if(pos>1 && counter>0)
pos--;
endIndex = pos;
for (int i=0; i<counter; i++)
startBitSet.set(startIndex, true);
startBitSet.set(endIndex, false);
startIndex = i+1;
pos--;
if(pos>0)
endIndex = pos;



get(startBitSet);

return properSubset;


/**
* 根据一次移位操作得到的startBitSet,得到一个真子集
* @param bitSet
*/
private static void get(BitSet bitSet)
Set<String> set = new HashSet<String>();
for(int i=0; i<array.length; i++)
if(bitSet.get(i))
set.add(array[i]);


properSubset.add(set);



测试用例

对上述Apriori算法的实现进行了简单的测试,测试用例如下所示:

package org.shirdrn.datamining.association;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.shirdrn.datamining.association.AprioriAlgorithm;

import junit.framework.TestCase;

/**
* <B>Apriori算法测试类</B>
*
* @author shirdrn
* @date 2009/07/22 22:56:23
* @msn shirdrn#hotmail.com(#→@)
* @qq 187071722
*/
public class TestAprioriAlgorithm extends TestCase

private AprioriAlgorithm apriori;
private Map<Integer, Set<String>> txDatabase;
private Float minSup = new Float("0.50");
private Float minConf = new Float("0.70");

@Override
protected void setUp() throws Exception
create(); // 构造事务数据库
apriori = new AprioriAlgorithm(txDatabase, minSup, minConf);


/**
* 构造模拟事务数据库txDatabase
*/
public void create()
txDatabase = new HashMap<Integer, Set<String>>();
Set<String> set1 = new TreeSet<String>();
set1.add("A");
set1.add("B");
set1.add("C");
set1.add("E");
txDatabase.put(1, set1);
Set<String> set2 = new TreeSet<String>();
set2.add("A");
set2.add("B");
set2.add("C");
txDatabase.put(2, set2);
Set<String> set3 = new TreeSet<String>();
set3.add("C");
set3.add("D");
txDatabase.put(3, set3);
Set<String> set4 = new TreeSet<String>();
set4.add("A");
set4.add("B");
set4.add("E");
txDatabase.put(4, set4);


/**
* 测试挖掘频繁1-项集
*/
public void testFreq1ItemSet()
System.out.println("挖掘频繁1-项集 : " + apriori.getFreq1ItemSet());


/**
* 测试aprioriGen方法,生成候选频繁项集
*/
public void testAprioriGen()
System.out.println(
"候选频繁2-项集 : " +
this.apriori.aprioriGen(1, this.apriori.getFreq1ItemSet().keySet())
);


/**
* 测试挖掘频繁2-项集
*/
public void testGetFreq2ItemSet()
System.out.println(
"挖掘频繁2-项集 :" +
this.apriori.getFreqKItemSet(2, this.apriori.getFreq1ItemSet().keySet())
);


/**
* 测试挖掘频繁3-项集
*/
public void testGetFreq3ItemSet()
System.out.println(
"挖掘频繁3-项集 :" +
this.apriori.getFreqKItemSet(
3,
this.apriori.getFreqKItemSet(2, this.apriori.getFreq1ItemSet().keySet()).keySet()
)
);


/**
* 测试挖掘全部频繁项集
*/
public void testGetFreqItemSet()
this.apriori.mineFreqItemSet(); // 挖掘频繁项集
System.out.println("挖掘频繁项集 :" + this.apriori.getFreqItemSet());


/**
* 测试挖掘全部频繁关联规则
*/
public void testMineAssociationRules()
this.apriori.mineFreqItemSet(); // 挖掘频繁项集
this.apriori.mineAssociationRules();
System.out.println("挖掘频繁关联规则 :" + this.apriori.getAssiciationRules());



测试结果:

挖掘频繁1-项集 : [E]=0.5, [A]=0.75, [B]=0.75, [C]=0.75
候选频繁2-项集 : [[E, C], [A, B], [B, C], [A, C], [E, B], [E, A]]
挖掘频繁2-项集 :[A, B]=0.75, [B, C]=0.5, [A, C]=0.5, [E, B]=0.5, [E, A]=0.5
挖掘频繁3-项集 :[E, A, B]=0.5, [A, B, C]=0.5
挖掘频繁项集 :1=[[E], [A], [B], [C]], 2=[[A, B], [B, C], [A, C], [E, B], [E, A]], 3=[[E, A, B], [A, B, C]]
挖掘频繁关联规则 :[E]=[[A], [B], [A, B]], [A]=[[B]], [B]=[[A]], [B, C]=[[A]], [A, C]=[[B]], [E, B]=[[A]], [E, A]=[[B]]

从测试结果看到,使用Apriori算法挖掘得到的全部频繁项集为:

1=[[E], [A], [B], [C]], 2=[[A, B], [B, C], [A, C], [E, B], [E, A]], 3=[[E, A, B], [A, B, C]]

使用Apriori算法挖掘得到的全部频繁关联规则为:

E→A、E→B、E→A,B、A→B、B→A、B,C→A、A,C→B、B,E→A、A,E→B。

参考资料:http://hi.baidu.com/shirdrn/blog/item/2e7ca71f212cbfc1a6866946.html

本回答被提问者采纳

小白向Apriori算法Python实现

  参考博客:http://www.cnblogs.com/llhthinker/p/6719779.html

  

  学习的别人的代码,用Python实现的Apriori算法,算法介绍见https://www.cnblogs.com/1113127139aaa/p/9926507.html

  内容是实现Apriori算法的流程,数据是简单的测试数组,因为自己比较菜所以仅是为了自己复习写了很水的注释,如果有像我一样的小白可以参考,先把完成的部分贴上来,原博客有原来博主的注释

  

def load_data_set():
    """
   加载一个示例集合
    Returns: 
        A data set: 一个购物列表,每个项中有不同的商品item
    """
    data_set = [[\'l1\', \'l2\', \'l5\'], [\'l2\', \'l4\'], [\'l2\', \'l3\'],
            [\'l1\', \'l2\', \'l4\'], [\'l1\', \'l3\'], [\'l2\', \'l3\'],
            [\'l1\', \'l3\'], [\'l1\', \'l2\', \'l3\', \'l5\'], [\'l1\', \'l2\', \'l3\']]
    return data_set


def create_C1(data_set):
    """
    扫描数据集,创建元素个数为1的项集C1,作为频繁项集的候选项集C1
    """
    C1 = set()
    for t in data_set:
        for item in t:
            item_set = frozenset([item])
            """
            由于要使用字典(support_data)记录项集的支持度,需要用项集作为key,
            而可变集合无法作为字典的key,因此在合适时机应将项集转为固定集合frozenset。
            或者另一种用法:
            for item in t:
                C1.append([item])
            C1.sort()
            return map(frozenset,C1)
            """
            C1.add(item_set)
    return C1


def is_apriori(Ck_item, Lksub1):
    """
    进行剪枝,如果满足APriori,即满足支持度,返回True
    否则返回False,删除
    """
    for item in Ck_item:
        sub_Ck = Ck_item - frozenset([item])
        if sub_Ck not in Lksub1:
            return False
    return True


def create_Ck(Lksub1, k):
    """
    由Lk-1生成Ck
    具体实现方法是在Lk-1中,对所有两个项集之间只有最后一项item不同的项集的交集
    """
    Ck = set()
    len_Lksub1 = len(Lksub1)
    list_Lksub1 = list(Lksub1)
    for i in range(len_Lksub1):
        for j in range(1, len_Lksub1):
            l1 = list(list_Lksub1[i])
            l2 = list(list_Lksub1[j])
            l1.sort()
            l2.sort()
            if l1[0:k-2] == l2[0:k-2]:
                Ck_item = list_Lksub1[i] | list_Lksub1[j]           #求并集
                # 剪枝
                if is_apriori(Ck_item, Lksub1):
                    Ck.add(Ck_item)
    return Ck


def generate_Lk_by_Ck(data_set, Ck, min_support, support_data):
    """
    由候选频繁k项集Ck生成频繁k项集Lk
    主要内容是对Ck中的每个项集计算支持度,去掉不满足最低支持度的项集
    返回Lk,记录support_data
    """
    Lk = set()
    item_count = {}
    for t in data_set:                              #扫描所有商品,计算候选频繁项集C中项集的支持度,t为订单
        for item in Ck:                             #item为C中的项集
            if item.issubset(t):                    #如果C中的项集是t订单的子集
                if item not in item_count:          #如果item_count中还没有这个项集,计数为1
                    item_count[item] = 1
                else:                               #如果item_count中已经有了这个项集,计数加1
                    item_count[item] += 1
    t_num = float(len(data_set))                    #t_num,订单总数
    for item in item_count:                         #item_count中已经有了所有的候选项集,计算支持度
        if (item_count[item] / t_num) >= min_support:
            Lk.add(item)                            #满足最小支持度的项集add进频繁项集Lk中
            support_data[item] = item_count[item] / t_num       #记录支持度,返回Lk
    return Lk


def generate_L(data_set, k, min_support):
    """
    生成频繁集Lk,通过调用generate_Lk_by_Ck
    从C1开始共进行k轮迭代,将每次生成的Lk都append到L中,同时记录支持度support_data
    """
    support_data = {}
    C1 = create_C1(data_set)            #生成C1
    L1 = generate_Lk_by_Ck(data_set, C1, min_support, support_data)     #由C1生成L1,调用generate_Lk_by_Ck函数
    Lksub1 = L1.copy()
    L = []
    L.append(Lksub1)
    for i in range(2, k+1):                                             #由k已知进行重复迭代
        Ci = create_Ck(Lksub1, i)                                       #由Lk生成Lk+1,调用create_Ck函数
        Li = generate_Lk_by_Ck(data_set, Ci, min_support, support_data)
        Lksub1 = Li.copy()
        L.append(Lksub1)
    return L, support_data


def generate_big_rules(L, support_data, min_conf):
    """
    Generate big rules from frequent itemsets.
    Args:
        L: The list of Lk.
        support_data: A dictionary. The key is frequent itemset and the value is support.
        min_conf: Minimal confidence.
    Returns:
        big_rule_list: A list which contains all big rules. Each big rule is represented
                       as a 3-tuple.
    """
    big_rule_list = []
    sub_set_list = []
    for i in range(0, len(L)):
        for freq_set in L[i]:
            for sub_set in sub_set_list:
                if sub_set.issubset(freq_set):
                    conf = support_data[freq_set] / support_data[freq_set - sub_set]
                    big_rule = (freq_set - sub_set, sub_set, conf)
                    if conf >= min_conf and big_rule not in big_rule_list:
                        # print freq_set-sub_set, " => ", sub_set, "conf: ", conf
                        big_rule_list.append(big_rule)
            sub_set_list.append(freq_set)
    return big_rule_list


if __name__ == "__main__":                  #主程序入口
    """
    Test
    """
    data_set = load_data_set()              #加载测试数据集
    L, support_data = generate_L(data_set, k=3, min_support=0.2)            #数据集中最大商品数为3,给定默认最低支持度为0.2,调用generate_L函数
    big_rules_list = generate_big_rules(L, support_data, min_conf=0.7)
    for Lk in L:
        print ("="*50)
        print ("frequent " + str(len(list(Lk)[0])) + "-itemsets\\t\\tsupport")
        print ("="*50)
        for freq_set in Lk:
            print (freq_set, support_data[freq_set])                        #print频繁k项集和支持度
    print
    print ("Big Rules")
    for item in big_rules_list:
        print (item[0], "=>", item[1], "conf: ", item[2])

 

以上是关于急需C++实现的Apriori算法代码的主要内容,如果未能解决你的问题,请参考以下文章

机器学习实战精读--------Apriori算法

Aprior算法

数据挖掘算法———常用关联算法总结

Apriori 关联分析算法原理分析与代码实现

小白向Apriori算法Python实现

apriori算法的代码,python实现,参考《机器学习实战》