关联规则挖掘算法--Apriori算法

这篇具有很好参考价值的文章主要介绍了关联规则挖掘算法--Apriori算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、Apriori算法

  1. 简介

关联规则分析是数据挖掘中最活跃的研究方法之一,目的是在一个数据集中找到各项之间的关联关系,而这种关系并没有在数据中直接体现出来。Apriori算法 关联规则学习的经典算法之一,是R.Agrawal和R.Srikartt于1944年提出的一种具有影响力的挖掘布尔关联规则挖掘频繁项集的算法。
  1. 基本原理

关联规则的一般定义如下:

(1)项集:定义关联规则apriori算法,算法,算法,数据挖掘,人工智能,机器学习,Powered by 金山文档表示一个项集。

(2)事务集:设任务相关的数据D是数据库事务的集合,即D是事务的集合;每个事务T是项的集合,其中关联规则apriori算法,算法,算法,数据挖掘,人工智能,机器学习,Powered by 金山文档 。例如关联规则apriori算法,算法,算法,数据挖掘,人工智能,机器学习,Powered by 金山文档表示一个事务。

(3)关联规则蕴含式:关联规则形如A=>B的蕴含式,关联规则apriori算法,算法,算法,数据挖掘,人工智能,机器学习,Powered by 金山文档,并且关联规则apriori算法,算法,算法,数据挖掘,人工智能,机器学习,Powered by 金山文档

(4)支持度s:D中包含A和 B 的事务数与总的事务数的比值。规则 A=>B 在数据集D中的支持度为s, 其中s 表示D中包含关联规则apriori算法,算法,算法,数据挖掘,人工智能,机器学习,Powered by 金山文档 (即同时包含A和B)的事务的百分率,即概率P( 关联规则apriori算法,算法,算法,数据挖掘,人工智能,机器学习,Powered by 金山文档

关联规则apriori算法,算法,算法,数据挖掘,人工智能,机器学习,Powered by 金山文档

(5)可信度 c :D中同时包含A和B的事务数与只包含A的事务数的比值。规则 A=>B 在数据集D中的可信度为c, 其中c表示D中包含A的事务中也包含B的百分率.即可用条件概率P(B|A)表示:

关联规则apriori算法,算法,算法,数据挖掘,人工智能,机器学习,Powered by 金山文档

其中supportCount表示项集出现的频率,即包含项集的事务数目。

(6)最小支持度 :表示规则中的所有项在事务中出现的频度。

(7)最小可信度 : 表示规则中左边的项(集)的出现暗示着右边的项(集)出现的频度。

关联规则挖掘过程:

(1)根据最小支持度找到数据集D中的所有频繁项集。

(2)由频繁项集产生强关联规则。强关联规则必须满足最小支持度和最小置信度

频繁项集两条重要性质:

(1) 频繁项集的子项集必是频繁项集。

(2)非频繁项集的超集一定是非频繁的。

3.算法过程

Apriori算法使用一种称作逐层搜索的迭代方法,利用k项集用于探索(k+1)项集。主要过程如下:

(1)首先,通过扫描数据库,累积每个项的计数,并收集满足最小支持度的项,找出频繁1项集的集合,该集合称作L1。

(2)然后,L1用于找频繁2项集的集合L2,L2用于寻找L3,如此下去,直到不能再找到新的频繁k项集。找每个 Lk要求对数据库做一次完全扫描。

Apriori算法使用的是产生-测试策略来发现频繁项集。每次迭代后,新的项集由前一次迭代发现的频繁项集产生,然后对每个候选的支持度进行计数,并与最小支持度阈值进行比较。算法需要迭代的总次数是kmax+1,其中kmax是频繁项集的最大长度。

二、Apriori算法举例

  1. 案例说明和数据

找到以下数据的频繁项集,最小支持度阈值是 2。其中每一行数据代表一个事务。

"I1 I2 I5"
"I2 I4"
"I2 I3"
"I1 I2 T4"
"I1 I3"
"I2 I3"
"I1 I3"
"I1 I2 I3 I5"
"I1 I2 I3"
  1. 基于python代码实现

(1)代码

def get_first_item(dataset):
    """
    获取数据集元素
    :param dataset: 数据集(二维数组)
    :return: 元素数组(二维)
    """
    dataset_item = []  # 数据集元素

    for i in dataset:
        for j in i:
            if [j] not in dataset_item:
                dataset_item.append([j])

    dataset_item.sort()

    return dataset_item


def get_freq_item(dataset, cand_list, min_sup):
    """
    获取频繁项集及计数
    :param dataset: 数据集
    :param cand_list: 候选集
    :param min_sup: 最小支持度
    :return: 频繁项集及计数和非频繁项集
    """
    cand_list_num = {}  # 候选集计数
    freq_list = []  # 存储频繁项集
    freq_list_num = {}  # 频繁项集计数
    unfreq_list = []  # 存储非频繁项集

    for i in cand_list:
        for j in dataset:
            if set(i).issubset(set(j)):  # 判断是否为子集
                cand_list_num[tuple(i)] = cand_list_num.get(tuple(i), 0) + 1
                # list 和dict不能作为主键

    for i in cand_list_num:
        if cand_list_num[i] >= min_sup:
            freq_list.append(list(i))
            freq_list_num[i] = cand_list_num[i]
        else:
            unfreq_list.append(list(i))
    return freq_list, freq_list_num, unfreq_list


def get_candiate(freq_list, unfreq_list):
    """
    获得候选集
    :param freq_list: 上一频繁项集
    :param unfreq_list: 上一非频繁项集
    :return: 候选集
    """
    cand_list = []  # 候选集

    length = len(freq_list[0]) + 1  # 记录上一单个频繁项集的长度+1

    for i in freq_list:
        for j in freq_list:
            com_item = list(set(i) | set(j))  # 求和集
            com_item.sort()  # 排个序
            if len(com_item) == length and com_item not in cand_list:
                cand_list.append(com_item)

                # 根据频繁项集的子集是频繁的,去除组合后的不该出现的候选集
    for m in unfreq_list:
        for n in cand_list:
            if set(m).issubset(set(n)):
                cand_list.remove(n)

    return cand_list


def Apriori(dataset, min_sup=2):
    """
    Apriori算法
    :param dataset: 数据集
    :param min_sup: 最小支持度
    :return: 所有频繁集,频繁集计数
    """
    first_can_list = get_first_item(dataset)  # 候选1项集
    freq_list, first_can_list_num, unfreq_list = get_freq_item(dataset, first_can_list, min_sup)  # 频繁1项集和计数字典

    freq_all_list = [freq_list]  # 所有频繁项集
    freq_all_list_num = first_can_list_num  # 所有频繁项集计数

    while True:
        cand_list = get_candiate(freq_list, unfreq_list)
        freq_list, freq_list_num, unfreq_list = get_freq_item(dataset, cand_list, min_sup)

        freq_all_list.append(freq_list)  # 更新频繁集
        freq_all_list_num.update(freq_list_num)  # 更新频繁集计数字典
        if len(freq_list) <= 1:
            break
    freq_all_list = [i for i in freq_all_list if i != []]  # 去除最后可能出现的空列表
    return freq_all_list, freq_all_list_num


if __name__ == '__main__':
    dataset = [['I1', 'I2', 'I5'],
               ['I2', 'I4'],
               ['I2', 'I3'],
               ['I1', 'I2', 'I4'],
               ['I1', 'I3'],
               ['I2', 'I3'],
               ['I1', 'I3'],
               ['I1', 'I2', 'I3', 'I5'],
               ['I1', 'I2', 'I3']]  # 数据集

    freq_list, freq_num = Apriori(dataset, min_sup=2)
    num = 1
    for i in freq_list:
        print(f"频繁{num}项集:{i}")
        num += 1
    for k,v in freq_num.items():
        print(f"频繁项集{k} 的个数:{v}")

(2)运行结果

关联规则apriori算法,算法,算法,数据挖掘,人工智能,机器学习,Powered by 金山文档
  1. 基于java代码实现

(1)代码

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
public class AprioriAlgorithm {
    private int minSup;
    private static List<String> data;
    private static List<Set<String>> dataSet;

    public static void main(String[] args) {

        long startTime = System.currentTimeMillis();
        AprioriAlgorithm apriori = new AprioriAlgorithm();

      
        data = apriori.buildData();

        //设置最小支持度
        apriori.setMinSup(2);
        //构造数据集
        data = apriori.buildData();

        //构造频繁1项集
        List<Set<String>> f1Set = apriori.findF1Item(data);
        apriori.printSet(f1Set, 1);
        List<Set<String>> result = f1Set;

        int i = 2;
        do{
            result = apriori.arioriGen(result);
            apriori.printSet(result, i);
            i++;
        }while(result.size() != 0);
        long endTime = System.currentTimeMillis();
        System.out.println("共用时: " + (endTime - startTime) + "ms");
    }
    public void setMinSup(int minSup){
        this.minSup = minSup;
    }

    /**
     * 构造原始数据集,可以为之提供参数,也可以不提供
     * 如果不提供参数,将按程序默认构造的数据集
     * 如果提供参数为文件名,则使用文件中的数据集
     */
    List<String> buildData(String...fileName){
        List<String> data = new ArrayList<String>();
        if(fileName.length != 0){
            File file = new File(fileName[0]);
            try{
                BufferedReader reader = new BufferedReader(new FileReader(file));
                String line;
                while( ( line = reader.readLine()) != null ){
                    data.add(line);
                }
            }catch (FileNotFoundException e){
                e.printStackTrace();
            }catch (IOException e){
                e.printStackTrace();
            }
        }else{
            data.add("I1 I2 I5");
            data.add("I2 I4");
            data.add("I2 I3");
            data.add("I1 I2 T4");
            data.add("I1 I3");
            data.add("I2 I3");
            data.add("I1 I3");
            data.add("I1 I2 I3 I5");
            data.add("I1 I2 I3");
        }

        dataSet = new ArrayList<Set<String>>();
        Set<String> dSet;
        for(String d : data){
            dSet = new TreeSet<String>();
            String[] dArr = d.split(" ");
            for(String str : dArr){
                dSet.add(str);
            }
            dataSet.add(dSet);
        }
        return data;
    }

    /**
     * 找出候选1项集
     * @param data
     * @return result
     */
    List<Set<String>> findF1Item(List<String> data){
        List<Set<String>> result = new ArrayList<Set<String>>();
        Map<String, Integer> dc = new HashMap<String, Integer>();
        for(String d : data){
            String[] items = d.split(" ");
            for(String item : items){
                if(dc.containsKey(item)) {
                    dc.put(item, dc.get(item)+1);
                }else{
                    dc.put(item, 1);
                }
            }
        }
        Set<String> itemKeys = dc.keySet();
        Set<String> tempKeys = new TreeSet<String>();
        for(String str : itemKeys){
            tempKeys.add(str);
        }

        for(String item : tempKeys){
            if(dc.get(item) >= minSup) {
                Set<String> f1Set = new TreeSet<String>();
                f1Set.add(item);
                result.add(f1Set);
            }
        }
        return result;
    }

    /**
     * 利用arioriGen方法由k-1项集生成k项集
     *@param preSet
     *@return
     *
     */
    List<Set<String>> arioriGen(List<Set<String>> preSet) {

        List<Set<String>> result = new ArrayList<Set<String>>();
        int preSetSize = preSet.size();

        for(int i = 0; i < preSetSize - 1; i++){
            for(int j = i + 1; j < preSetSize; j++ ){
                String[] strA1 = preSet.get(i).toArray(new String[0]);
                String[] strA2 = preSet.get(j).toArray(new String[0]);
                if(isCanLink(strA1, strA2)) {//判断两个k-1项集是否符合连接成K项集的条件
                    Set<String> set = new TreeSet<String>();
                    for(String str : strA1){
                        set.add(str);//将strA1加入set中连成前K-1项集
                    }
                    set.add((String) strA2[strA2.length-1]);//连接成K项集
                    //判断K项集是否需要剪切掉,如果不需要被cut掉,则加入到k项集的列表中
                    if(!isNeedCut(preSet, set)) {
                        result.add(set);
                    }
                }
            }
        }
        return checkSupport(result);//返回的都是频繁K项集
    }

    /**
     * 把set中的项集与数量集比较并进行计算,求出支持度大于要求的项集
     * @return
     */
    List<Set<String>> checkSupport(List<Set<String> > setList){

        List<Set<String>> result = new ArrayList<Set<String>>();
        boolean flag = true;
        int [] counter = new int[setList.size()];
        for(int i = 0; i < setList.size(); i++){

            for(Set<String> dSets : dataSet) {
                if(setList.get(i).size() > dSets.size()){
                    flag = true;
                }else{
                    for(String str : setList.get(i)){
                        if(!dSets.contains(str)){
                            flag = false;
                            break;
                        }
                    }
                    if(flag) {
                        counter[i] += 1;
                    } else{
                        flag = true;
                    }
                }
            }
        }

        for(int i = 0; i < setList.size(); i++){
            if (counter[i] >= minSup) {
                result.add(setList.get(i));
            }
        }
        return result;
    }

    /**
     * 判断两个项集能否执行连接操作
     * @param s1
     * @param s2
     * @return
     */
    boolean isCanLink(String [] s1, String[] s2){
        boolean flag = true;
        if(s1.length == s2.length) {
            for(int i = 0; i < s1.length - 1; i ++){
                if(!s1[i].equals(s2[i])){
                    flag = false;
                    break;
                }
            }
            if(s1[s1.length - 1].equals(s2[s2.length - 1])){
                flag = false;
            }
        }else{
            flag = true;
        }
        return flag;
    }

    /**
     * 判断set是否需要被cut
     *
     * @param setList
     * @param set
     * @return
     */
    boolean isNeedCut(List<Set<String>> setList, Set<String> set) {//setList指频繁K-1项集,set指候选K项集
        boolean flag = false;
        List<Set<String>> subSets = getSubset(set);//获得K项集的所有k-1项集
        for ( Set<String> subSet : subSets) {
            //判断当前的k-1项集set是否在频繁k-1项集中出现,如果出现,则不需要cut
            //若没有出现,则需要被cut
            if( !isContained(setList, subSet)){
                flag = true;
                break;
            }
        }
        return flag;
    }
    /**
     * 功能:判断k项集的某k-1项集是否包含在频繁k-1项集列表中
     *
     * @param setList
     * @param set
     * @return
     */
    boolean isContained(List<Set<String>> setList, Set<String> set){
        boolean flag = false;
        int position = 0;
        for( Set<String> s : setList  ) {
            String [] sArr = s.toArray(new String[0]);
            String [] setArr = set.toArray(new String[0]);
            for(int i = 0; i < sArr.length; i++) {
                if ( sArr[i].equals(setArr[i])){
                    //如果对应位置的元素相同,则position为当前位置的值
                    position = i;
                } else{
                    break;
                }
            }
            //如果position等于数组的长度,说明已经找到某个setList中的集合与
            //set集合相同了,退出循环,返回包含
            //否则,把position置为0进入下一个比较
            if ( position == sArr.length - 1) {
                flag = true;
                break;
            } else {
                flag = false;
                position = 0;
            }
        }
        return flag;
    }

    /**
     * 获得k项集的所有k-1项子集
     *
     * @param set
     * @return
     */
    List<Set<String>> getSubset(Set <String> set){

        List<Set<String>> result = new ArrayList<Set<String>>();
        String [] setArr = set.toArray(new String[0]);

        for( int i = 0; i < setArr.length; i++){
            Set<String> subSet = new TreeSet<String>();
            for(int j = 0; j < setArr.length; j++){
                if( i != j){
                    subSet.add((String) setArr[j]);
                }
            }
            result.add(subSet);
        }
        return result;
    }
    /**
     * 功能:打印频繁项集
     */
    void printSet(List<Set<String>> setList, int i){
        System.out.print("频繁" + i + "项集: 共" + setList.size() + "项: {");
        for(Set<String> set : setList) {
            System.out.print("[");
            for(String str : set) {
                System.out.print(str + " ");
            }
            System.out.print("], ");
        }
        System.out.println("}");
    }
}

(2)运行结果

关联规则apriori算法,算法,算法,数据挖掘,人工智能,机器学习,Powered by 金山文档

三、总结

在日常生活中,利用关联分析能够帮助我们发现大型数据集之间的关联规则,描述数据之间的密切度,同时又有利于我们进行决策等。

参考

数据挖掘十大算法—— Apriori - 知乎 (zhihu.com)

Apriori算法详解 - 知乎 (zhihu.com)

数据挖掘入门系列教程(四点五)之Apriori算法 - 知乎 (zhihu.com)文章来源地址https://www.toymoban.com/news/detail-762588.html

到了这里,关于关联规则挖掘算法--Apriori算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据挖掘|关联分析与Apriori算法详解

    关联规则分析(Association-rules Analysis)是数据挖掘领域的一个重要方法,它是以某种方式分析数据源,从数据样本集中发现一些潜在有用的信息和不同数据样本之间关系的过程。 关联是指在两个或多个变量之间存在某种规律性,但关联并不一定意味着因果关系。 关联规则是寻

    2024年04月10日
    浏览(55)
  • 数据挖掘(一)使用 Apriori 算法进行关联分析

    关联分析是一种在大规模数据集中寻找有趣关系的任务。 这些关系可以有两种形式: 频繁项集(frequent item sets): 经常出现在一块的物品的集合。 关联规则(associational rules): 暗示两种物品之间可能存在很强的关系。 关联分析(关联规则学习): 从大规模数据集中寻找物品间的

    2024年02月09日
    浏览(54)
  • 关联规则挖掘算法--Apriori算法

    关联规则分析是数据挖掘中最活跃的研究方法之一,目的是在一个数据集中找到各项之间的关联关系,而这种关系并没有在数据中直接体现出来。Apriori算法 关联规则 学习的经典算法之一,是R.Agrawal和R.Srikartt于1944年提出的一种具有影响力的挖掘布尔关联规则挖掘频繁项集的

    2024年02月04日
    浏览(54)
  • Apriori关联规则挖掘算法函数

    假设有以下《超市商品购买.txt》数据集,每行代表一个顾客在超市的购买记录: I1: 西红柿、排骨、鸡蛋、毛巾、水果刀 I2: 西红柿、茄子、水果刀、香蕉 I3: 鸡蛋、袜子、毛巾、肥皂、水果刀 I4: 西红柿、排骨、茄子、毛巾、水果刀 I5: 西红柿、排骨、酸奶 I6: 鸡蛋、茄子、酸

    2024年02月09日
    浏览(117)
  • 【商业挖掘】关联规则——Apriori算法(最全~)

    一、关联规则挖掘 二、Apriori-关联规则算法 三、Apriori算法分解—Python大白话式实现 步骤1: 外部库调用❀  步骤2: 数据导入❀ 步骤3: 数据处理❀   步骤4:输出所有Goodlist❀ 步骤5:项集重组❀ 步骤6:支持度扫描与输出 ❀ 步骤7:根据最小支持度阈值进行减枝叶❀ 步骤

    2024年01月25日
    浏览(60)
  • 关联规则挖掘:Apriori算法的深度探讨

    在本文中,我们深入探讨了Apriori算法的理论基础、核心概念及其在实际问题中的应用。文章不仅全面解析了算法的工作机制,还通过Python代码段展示了具体的实战应用。此外,我们还针对算法在大数据环境下的性能局限提出了优化方案和扩展方法,最终以独到的技术洞见进行

    2024年02月05日
    浏览(68)
  • 数据挖掘十大算法之Apriori算法

    国际权威的学术组织the IEEE International Conference on Data Mining (ICDM) 2006年12月评选出了数据挖掘领域的十大经典算法: C4.5 , k-Means , SVM , Apriori , EM , PageRank , AdaBoost , kNN , Naive Bayes , CART 这十个算法涵盖了分类、聚类、统计学习、关联分析和链接分析等重要的数据挖掘研究和发展主题

    2024年02月04日
    浏览(47)
  • 数据挖掘实验——Apriori算法实现

    关联规则分析是数据挖掘中最活跃的研究方法之一,目的是在一个数据集中找出各项之间的关联关系,而这种关系并没有在数据中直接表示出来。本实验主要目的是培养学生能够运用Apriori算法数据挖掘方法进行数据挖掘。 学习掌握数据挖掘方法中的Apriori算法。 就餐饮企业而

    2024年02月06日
    浏览(65)
  • python数据分析 - 关联规则Apriori算法

    关联规则 : 是反映一个事物与其他事物之间的相互依存性和关联性 常用于实体商店或在线电商的推荐系统:通过对顾客的购买记录数据库进行关联规则挖掘,最终目的是发现顾客群体的购买习惯的内在共性,例如购买产品A的同时也连带购买产品B的概率,根据挖掘结果,调

    2024年02月07日
    浏览(70)
  • 数据挖掘实验(Apriori,fpgrowth)

    Apriori:这里做了个小优化,比如 abcde 和 adcef 自连接出的新项集 abcdef ,可以用 abcde 的位置和 f 的位置取交集,这样第 n 项集的计算可以用 n-1 项集的信息和数字本身的位置信息计算出来,只需要保存第 n-1 项集的位置信息就可以提速 Fpgrowth的算法,我没有递归建树,只建了一

    2024年04月23日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包