Apriori算法-java

package com.yang;

import java.util.*;

public class Apriori {

private double minsup = 0.2;// 最小支持度
    private double minconf = 0.2;// 最小置信度

// 注意使用IdentityHashMap,否则由于关联规则产生存在键值相同的会出现覆盖
    private IdentityHashMap ruleMap = new IdentityHashMap();

//private String[] transSet = { "abc", "abc", "acde", "bcdf", "abcd", "abcdf" };// 事务集合
                                                                                    // ,
                                                                                    // 可以根据需要从构造函数里传入
    private String[] transSet = { "abe", "bd", "bc", "abd", "ac", "bc","ac","abce","abc" };// 事务集合
    private int itemCounts = 0;// 候选1项目集大小,即字母的个数
    private TreeSet[] frequencySet = new TreeSet[40];// 频繁项集数组,[0]:代表1频繁集...,TreeSet()使用元素的自然顺序对元素进行排序
    private TreeSet maxFrequency = new TreeSet();// 最大频繁集[所有频繁的]
    private TreeSet candidate = new TreeSet();
    private TreeSet candidateSet[] = new TreeSet[40];// 候选集数组[0]:代表1候选集
    private int frequencyIndex;

public Apriori() {

maxFrequency = new TreeSet();
        itemCounts = counts();// 初始化1候选集的大小6个
        System.out.printf("1项集的大小"+itemCounts);
        // 初始化其他两个
        for (int i = 0; i < itemCounts; i++) {
            frequencySet[i] = new TreeSet();//初始化频繁项集数组
            candidateSet[i] = new TreeSet();//初始化候选集数组
        }
        candidateSet[0] = candidate;// 1候选集
    }

//主函数入口
    public static void main(String[] args) {
        Apriori ap = new Apriori();
        ap.run();
    }
    
    //方法运行
    public void run() {
        int k = 1;
        item1_gen();

do {
            k++;
            canditate_gen(k);
            frequent_gen(k);
        } while (!is_frequent_empty(k));
        frequencyIndex = k - 1;
        print_canditate();
        maxfrequent_gen();
        print_maxfrequent();
        ruleGen();
        rulePrint();
    }
    //记录每个事务中的元素出现次数,x在事务中出现的总次数。
    public double count_sup(String x) {
        int temp = 0;
        for (int i = 0; i < transSet.length; i++) {
            for (int j = 0; j < x.length(); j++) {
                if (transSet[i].indexOf(x.charAt(j)) == -1)//返回指定字符在此字符串中第一次出现处的索引,如果不作为一个字符串,返回-1
                    break;
                else if (j == (x.length() - 1))
                    temp++;
            }
        }
        return temp;
    }
    
    //统计1候选集的个数a,b,c,d,e,f,return值为6
    public int counts() {

String temp1 = null;
        char temp2 = ‘a‘;
        // 遍历所有事务集String 加入集合,set自动去重了
        for (int i = 0; i < transSet.length; i++) {
            temp1 = transSet[i];
            for (int j = 0; j < temp1.length(); j++) {
                temp2 = temp1.charAt(j);//返回位置为j的temp1的值a
                candidate.add(String.valueOf(temp2));//treeSet添加会去掉重复的值
            }
        }
        return candidate.size();//中元素个数不重复,且递增排序
    }

//求1频繁集
    public void item1_gen() {
        String temp1 = "";
        double m = 0;

Iterator temp = candidateSet[0].iterator();//使用方法iterator()要求容器返回一个Iterator。
        while (temp.hasNext()) {//遍历temp(1候选集)
            temp1 = (String) temp.next();
            m = count_sup(temp1);//调用下面的方法,统计1候选集中每个元素个数,计算支持度时,用此m/transSet.length

// 符合条件的加入 1候选集
            if (m >= minsup * transSet.length) {//minsup * transSet.length的值为记录每个事务中的元素出现次数,判断是否1频繁集
                frequencySet[0].add(temp1);//1频繁集加入频繁项集数组,自动出去重复的集合
            }
        }
    }
    //求K候选集
    public void canditate_gen(int k) {
        String y = "", z = "", m = "";
        char c1 ,c2 ;

Iterator temp1 = frequencySet[k - 2].iterator();//iterator迭代器,用于数组遍历
        Iterator temp2 = frequencySet[0].iterator();//遍历频繁项集数组,[0]:代表1频繁集
        TreeSet h = new TreeSet();

while (temp1.hasNext()) {
            y = (String) temp1.next();//
            c1 = y.charAt(y.length() - 1);//返回指定y.length() - 1(数组的最后一个)的char值

while (temp2.hasNext()) {
                z = (String) temp2.next();

c2 = z.charAt(0);//c2=a,b,c,d,e,f
                if (c1 >= c2)
                    continue;//大于最后一个字符才拼上。abd,而无adb
                else {
                    m = y + z;//m为字符串组合yz
                    h.add(m);//m加入TreeSet
                }
            }
            temp2 = frequencySet[0].iterator();
        }
        candidateSet[k - 1] = h;
    }

// k候选集=>k频繁集
    public void frequent_gen(int k) {
        String s1 = "";

Iterator ix = candidateSet[k - 1].iterator();//遍历K候选集ix
        while (ix.hasNext()) {
            s1 = (String) ix.next();//ix中的值s1
            if (count_sup(s1) >= (minsup * transSet.length)) {//s1项集支持度大于最小支持度
                frequencySet[k - 1].add(s1);//s1加入K频繁集中
            }
        }
    }
    //判断频繁集为空
    public boolean is_frequent_empty(int k) {
        if (frequencySet[k - 1].isEmpty())
            return true;
        else
            return false;
    }
    //打印候选集 频繁集
    public void print_canditate() {

for (int i = 0; i < frequencySet[0].size(); i++) {
            Iterator ix = candidateSet[i].iterator();
            Iterator iy = frequencySet[i].iterator();
            System.out.print("候选集" + (i + 1) + ":");
            while (ix.hasNext()) {
                System.out.print((String) ix.next() + "\t");
            }
            System.out.print("\n" + "频繁集" + (i + 1) + ":");
            while (iy.hasNext()) {
                System.out.print((String) iy.next() + "\t");
            }
            System.out.println();
        }
    }

//求关联项集合
    public void maxfrequent_gen() {
        int i;
        for (i = 1; i < frequencyIndex; i++) {
            maxFrequency.addAll(frequencySet[i]);
        }
    }
    //打印频繁项集
    public void print_maxfrequent() {
        Iterator iterator = maxFrequency.iterator();
        System.out.print("频繁项集:");
        while (iterator.hasNext()) {
            System.out.print(((String) iterator.next()) + "\t");
        }
        System.out.println();
        System.out.println();
    }
    //关联规则项集
    public void ruleGen() {
        String s;
        Iterator iterator = maxFrequency.iterator();
        while (iterator.hasNext()) {
            s = (String) iterator.next();
            subGen(s);
        }
    }

//求关联规则
    //将1左移多少位,将s分成不重叠的两部分。生成所有关联规则。再判断支持度
    public void subGen(String s) {
        String x = "", y = "";
        for (int i = 1; i < (1 << s.length()) - 1; i++) {
            for (int j = 0; j < s.length(); j++) {
                if (((1 << j) & i) != 0) {
                    x += s.charAt(j);
                }
            }

for (int j = 0; j < s.length(); j++) {
                if (((1 << j) & (~i)) != 0) {

y += s.charAt(j);

}
            }
            if (count_sup(x + y) / count_sup(x) >= minconf) {
                ruleMap.put(x, y);
            }
            x = "";
            y = "";

}
    }

//打印关联规则
    public void rulePrint() {
        String x, y;
        float temp = 0;

Set hs = ruleMap.keySet();//迭代后只能用get取key,Set不包含重复元素的collection
        Iterator iterator = hs.iterator();
        System.out.println("关联规则:");
        while (iterator.hasNext()) {
            x = (String) iterator.next();

y = (String) ruleMap.get(x);

temp = (float) (count_sup(x + y) / count_sup(x));

System.out.println(x + (x.length() < 5 ? "\t" : "") + "-->" + y+ "\t" + "置信度: " + temp);
            
        }
    }
}
学习点:1.TreeSet.add自动去重

2.TreeSet[] frequencySet; TreeSet frequencySet[];两种方法定义的都是数组,似乎是相同的。

3.canditate_gen中,大于最后一个字符的时候才拼上,adb即abd,所以不存在adb这种。

4.生成关联规则时,是将1左移多少位。能够将所有的组合都生成。x与y不会重叠。

效果图:

时间: 2024-08-30 14:25:31

Apriori算法-java的相关文章

Java实现Apriori算法

Apriori算法的Java实现,源码放在github上,大家有兴趣可以下下来看看, 源码地址: https://github.com/l294265421/algorithm-apriori 实现该算法主要阅读的书籍是: <Web数据挖掘>第二版,作者:Bing Liu,译者:俞勇 版权声明:本文为博主原创文章,未经博主允许不得转载.

Apriori算法学习和java实现

关联规则挖掘可以发现大量数据中项集之间有趣的关联或相关联系.一个典型的关联规则挖掘例子是购物篮分析,即通过发现顾客放入其购物篮中的不同商品之间的联系,分析顾客的购物习惯,从而可以帮助零售商指定营销策略,引导销售等.国外有"啤酒与尿布"的故事,国内有泡面和火腿的故事.本文以Apriori算法为例介绍关联规则挖掘并以java实现. 什么是关联规则: 对于记录的集合D和记录A,记录B,A,B属于D:  A--->B  [support(A->B)=p(AUB) ,confiden

Apriori算法的java实现

介绍 Apriori算法是一个经典的数据挖掘算法,Apriori的单词的意思是"先验的",说明这个算法是具有先验性质的,就是说要通过上一次的结果推导出下一次的结果,这个如何体现将会在下面的分析中会慢慢的体现出来.Apriori算法的用处是挖掘频繁项集的,频繁项集粗俗的理解就是找出经常出现的组合,然后根据这些组合最终推出我们的关联规则. Apriori算法原理 Apriori算法是一种逐层搜索的迭代式算法,其中k项集用于挖掘(k+1)项集,这是依靠他的先验性质的: 频繁项集的所有非空子集

频繁模式挖掘apriori算法介绍及Java实现

频繁模式是频繁地出现在数据集中的模式(如项集.子序列或者子结构).例如,频繁地同时出现在交易数据集中的商品(如牛奶和面包)的集合是频繁项集. 一些基本概念 支持度:support(A=>B)=P(A并B) 置信度:confidence(A=>B)=P(B|A) 频繁k项集:如果项集I的支持度满足预定义的最小支持度阈值,则称I为频繁项集,包含k个项的项集称为k项集. 算法思想 Apriori算法是Agrawal和R. Srikant于1994年提出,为布尔关联规则挖掘频繁项集的原创性算法.通过名

Apriori算法--关联规则挖掘

我的数据挖掘算法代码:https://github.com/linyiqun/DataMiningAlgorithm 介绍 Apriori算法是一个经典的数据挖掘算法,Apriori的单词的意思是"先验的",说明这个算法是具有先验性质的,就是说要通过上一次的结果推导出下一次的结果,这个如何体现将会在下面的分析中会慢慢的体现出来.Apriori算法的用处是挖掘频繁项集的,频繁项集粗俗的理解就是找出经常出现的组合,然后根据这些组合最终推出我们的关联规则. Apriori算法原理 Aprio

玩转大数据:深入浅出大数据挖掘技术(Apriori算法、Tanagra工具、决策树)

一.本课程是怎么样的一门课程(全面介绍) 1.1.课程的背景 “大数据”作为时下最火热的IT行业的词汇,随之而来的数据仓库.数据分析.数据挖掘等等围绕大数据的商业价值的利用逐渐成为行业人士争相追捧的利润焦点. “大数据” 其实离我们的生活并不遥远,大到微博的海量用户信息,小到一个小区超市的月销售清单,都蕴含着大量潜在的商业价值. 正是由于数据量的快速增长,并且已经远远超过了人们的数据分析能力.因此,科学.商用等领域都迫切需要智能化.自动化的数据分析工具.在这样的背景下,数据挖掘技术应用而生,使得

利用Hbase的coprocessor实现增量式Apriori算法

Apriori在数据挖掘中是经典的频繁项集挖掘算法,其主要思想就是如果某个项集不频繁,则任何包含此项集的项集一定不频繁.而今天要实现的增量式的Apriori算法,有点像分布式的Apriori,因为我们可以把已挖掘的事务集和新增的事务集看作两个互相独立的数据集,挖掘新增的事务集,获取所有新增频繁集,然后与已有的频繁集做并集,对于两边都同时频繁的项集肯定全局频繁,而只有一边频繁的项集则需要统计其在两边的频繁计数,这样完成后就能获得所有的全局频繁集,并不需要重新挖掘已有的事务集,效率必然提高. 至于H

Apriori算法例子

1 Apriori介绍 Apriori算法使用频繁项集的先验知识,使用一种称作逐层搜索的迭代方法,k项集用于探索(k+1)项集.首先,通过扫描事务(交易)记录,找出所有的频繁1项集,该集合记做L1,然后利用L1找频繁2项集的集合L2,L2找L3,如此下去,直到不能再找到任何频繁k项集.最后再在所有的频繁集中找出强规则,即产生用户感兴趣的关联规则. 其中,Apriori算法具有这样一条性质:任一频繁项集的所有非空子集也必须是频繁的.因为假如P(I)< 最小支持度阈值,当有元素A添加到I中时,结果项

机器学习(八)—Apriori算法

摘要:本文对Apriori算法进行了简单介绍,并通过Python进行实现,进而结合UCI数据库中的肋形蘑菇数据集对算法进行验证. “啤酒与尿布”的例子相信很多人都听说过吧,故事是这样的:在一家超市中,人们发现了一个特别有趣的现象,尿布与啤酒这两种风马牛不相及的商品居然摆在一起.但这一奇怪的举措居然使尿布和啤酒的销量大幅增加了.这可不是一个笑话,而是一直被商家所津津乐道的发生在美国沃尔玛连锁超市的真实案例.原来,美国的妇女通常在家照顾孩子,所以她们经常会嘱咐丈夫在下班回家的路上为孩子买尿布,而丈夫