您的位置:首页 > 编程语言 > Java开发

Apriori算法的JAVA实现

2016-01-15 09:06 495 查看
最新学习《数据挖掘概念与技术》将书中的Apriori算法用java实现(jdk7+Eclipse4)了,代码如下:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;

public class MyApriori
{
public static int min_sup = 2;

/**
* @author weibin
* @param args
*/
public static void main(String[] args)
{
// TODO Auto-generated method stub
long startTime = System.currentTimeMillis();
// 事务数据库
List<String> data = new ArrayList<String>();
data.add("I1,I2,I5");
data.add("I2,I4");
data.add("I2,I3");
data.add("I1,I2,I4");
data.add("I1,I3");
data.add("I2,I3");
data.add("I1,I3");
data.add("I1,I2,I3,I5");
data.add("I1,I2,I3");
System.out.println("ALLElectronics某分店的事务数据为:");
for (int i = 0; i < data.size(); i++)
{
System.out.println(" " + data.get(i).toString());
}

MyApriori myapr = new MyApriori();

TreeSet<String> Lk_1 = myapr.find_frequent_1_itemsets(data);
System.out.println("第一次扫描事务数据库后L1=" + Lk_1);

TreeSet<String> Ck = new TreeSet<String>();

for (int k = 2; Lk_1.size() != 0; k++)
{

System.out.println("\n通过L" + (k - 1) + " × L" + (k - 1) + "生成C" + k
+ "时:");
Ck = myapr.apriori_gen(Lk_1, k);

if (Ck.size() > 0)
{
System.out.println("\n通过L" + (k - 1) + " 生成L" + k + "为:");
Iterator<String> it1 = Ck.iterator();
while (it1.hasNext())
{
System.out.println(" " + it1.next());

}
System.out.println("\n");
}

HashMap<String, Integer> hm = new MyApriori().TreeSet2HashMap(Ck);

ArrayList<String> al = new MyApriori().TreeSet2ArrayList(Ck);

for (int j = 0; j < al.size(); j++)
{
TreeSet<String> set_al = new MyApriori().String2TreeSet(al
.get(j));
// System.out.println("set_al="+set_al);
for (int i = 0; i < data.size(); i++)
{

TreeSet<String> set_data = new MyApriori()
.String2TreeSet(data.get(i));
// System.out.println(" set_data="+set_data);
int size_o = set_data.size();
set_data.addAll(set_al);
int size_n = set_data.size();

if (size_n == size_o)
{
// System.out.println(" "+al.get(j)+" 出现次数="+((hm.get(al.get(j)).intValue())
// + 1));
hm.put(al.get(j), hm.get(al.get(j)) + 1);

}

}
}

Lk_1 = new MyApriori().compareMinSup(hm);
if (Lk_1.size() > 0)
{
System.out.println("\n将候选集C" + (k - 1) + "不满足最小支持度的元素删除后L" + k
+ "为:");
Iterator<String> it1 = Lk_1.iterator();
while (it1.hasNext())
{
System.out.println(" " + it1.next());

}
System.out.println("\n");
}
}
long endTime = System.currentTimeMillis();
System.out.println("执行程序一共花费了" + (endTime - startTime) + "毫秒");
}

/*
* apriori_gen 将L(k-1)*L(k-1)得到Lk
*/
public TreeSet<String> apriori_gen(TreeSet<String> Lk_1, int k)
{

TreeSet<String> Ck = new TreeSet<String>();
ArrayList<String> l1 = new MyApriori().TreeSet2ArrayList(Lk_1);
ArrayList<String> l2 = new MyApriori().TreeSet2ArrayList(Lk_1);
String c = new String();

for (int i = 0; i < l2.size(); i++)
{
for (int j = i + 1; j < l2.size(); j++)
{

String str_l1 = l1.get(i).toString();
String str_l2 = l2.get(j).toString();

int lastSplit = str_l1.lastIndexOf(",");
if (lastSplit == -1)// 如果为1项集,则通过1项集连接生成2项集
{
c = str_l1 + "," + l2.get(j).toString();
// System.out.println("c=" + c);
if (!has_infrequent_subset(c, Lk_1, k - 1))
{
Ck.add(c);
}
} else
{

if (str_l1.substring(0, lastSplit).equals(
str_l2.substring(0, lastSplit))
&& str_l1.substring(lastSplit).compareTo(
str_l2.substring(lastSplit)) < 0)
{
c = str_l1 + str_l2.substring(lastSplit);
// System.out.println("c=" + c);
if (!has_infrequent_subset(c, Lk_1, k - 1))
{
Ck.add(c);
}
}
}
}

}

return Ck;
}

/*
* 第一次扫描数据库,找到一项集
*
* 库为: "I1,I2,I5" "I2,I4" "I2,I3" "I1,I2,I4" "I1,I3" "I2,I3" "I1,I3"
* "I1,I2,I3,I5" "I1,I2,I3"
*
* 扫描库后分别对一项集进行计数: 项集为I3 支持度计数为6 项集为I4 支持度计数为2 项集为I1 支持度计数为6 项集为I2 支持度计数为7
* 项集为I5 支持度计数为2
*
* 则返回一项集:Lk_1=[I1, I2, I3, I4, I5]
*/
public TreeSet<String> find_frequent_1_itemsets(List<String> data)
{

String str[] = data.toString().replace(" ", "").replace("[", "")
.replace("]", "").split(",");

HashMap<String, Integer> hm = new HashMap<String, Integer>();
TreeSet<String> set = new TreeSet<String>();
for (int i = 0; i < str.length; i++)
{
// set.add(str[i]);
if (hm.get(str[i]) == null)
{
hm.put(str[i], 1);
} else
{
hm.put(str[i], hm.get(str[i]) + 1);
}

}
set = new MyApriori().compareMinSup(hm);
return set;
}

/*
* 判断参数HashMap hm中键值对,值与 min_sup比较,当小于min_sup时,删除此键值对,最后返回候选集 项集为I3 支持度计数为6
* 项集为I4 支持度计数为2 项集为I1 支持度计数为6 项集为I2 支持度计数为7 项集为I5 支持度计数为2
*
* 则返回一项集:Lk_1=[I1, I2, I3, I4, I5]
*/
public TreeSet<String> compareMinSup(HashMap<String, Integer> hm)
{
TreeSet<String> set = new TreeSet<String>();
Iterator iter = hm.entrySet().iterator();
if (hm.size() > 0)
{
System.out.println("----项集----|----支持度----l");
}
while (iter.hasNext())
{
Map.Entry<String, Integer> entry = (Map.Entry) iter.next();
String key = (String) (entry.getKey());
int val = (Integer) (entry.getValue()).intValue();

System.out.println(" " + key + " | " + val);

if (val >= min_sup)
set.add(key);
}
return set;

}

/*
* 将TreeSet<String>转为ArrayList
*/
public ArrayList<String> TreeSet2ArrayList(TreeSet<String> Lk_1)
{
ArrayList<String> al = new ArrayList<String>();
Iterator<String> iterator = Lk_1.iterator();

while (iterator.hasNext())
{
al.add(iterator.next().toString());
// iterator.next();
}
return al;
}

/*
* 查询以分号分隔的字符串形成集合后,取其中K为元素作为子集,当其中存在子集不属于Lk_1中,返回真,都属于Lk_1中返回假
*/
public boolean has_infrequent_subset(String c, TreeSet<String> Lk_1, int k)
{
TreeSet<String> ts = new MyApriori().String2TreeSet(c);
TreeSet<String> zh = new MyApriori().zh(ts, k);
Iterator<String> it1 = zh.iterator();

while (it1.hasNext())
{
String temp = it1.next();
if (!Lk_1.contains(temp))
{
System.out.println(" {" + c + "} 的" + k + "项子集 { " + temp
+ "} 不是L" + k + "的元素,根据先验性质剪技,删除!");
return true;
}
}
return false;
}

/*
* 将TreeSet<String>转为ArrayList
*/
public TreeSet<String> String2TreeSet(String c)
{
TreeSet<String> ts = new TreeSet<String>();
String[] str = c.split(",");
for (int i = 0; i < str.length; i++)
{
ts.add(str[i]);
}
return ts;
}

/*
* 返回集合data中所有元素不重复的n个组合
*/
public TreeSet<String> zh(TreeSet<String> data, int n)
{
TreeSet<String> result = new TreeSet<String>();
if (n == 1)
{
result = data;
} else
{
Iterator<String> it1 = zh(data, n - 1).iterator();
Iterator<String> it2 = data.iterator();
ArrayList<String> sal1 = new ArrayList<String>();
ArrayList<String> sal2 = new ArrayList<String>();

while (it1.hasNext())
{
sal1.add(it1.next());
// iterator.next();
}

while (it2.hasNext())
{
sal2.add(it2.next());
// iterator.next();
}

// System.out.println("sal1=" + sal1);
// System.out.println("sal2=" + sal2);

for (int i = 0; i < sal1.size() - 1; i++)
{

for (int j = 0; j < sal2.size(); j++)
{
if (sal1.get(i).compareTo(sal2.get(j)) < 0)
{
if (n == 2)
{
result.add(sal1.get(i) + "," + sal2.get(j));
} else
{
// System.out.println("sal1.get("+i+")="+sal1.get(i));
// System.out.println("sal2.get("+j+")="+sal2.get(j));

String[] temp = sal1.get(i).split(",");

// System.out.println("temp[temp.length-1]="+temp[temp.length-1]);
if (temp[temp.length - 1].compareTo(sal2.get(j)) < 0)
{
result.add(sal1.get(i) + "," + sal2.get(j));
}

}
}
}

}
}

return result;

}

/*
* 给定一个TreeSet 生成与一个HashMap<String, Integer>,其中String为TreeSet,Integer为0
*/
public HashMap<String, Integer> TreeSet2HashMap(TreeSet<String> set)
{
HashMap<String, Integer> hm = new HashMap<String, Integer>();

Iterator<String> it1 = set.iterator();

while (it1.hasNext())
{
hm.put(it1.next(), 0);

}

return hm;
}
}

程序运行结果如下所示:

ALLElectronics某分店的事务数据为:

    I1,I2,I5

    I2,I4

    I2,I3

    I1,I2,I4

    I1,I3

    I2,I3

    I1,I3

    I1,I2,I3,I5

    I1,I2,I3

----项集----|----支持度----l

     I3     |      6

     I4     |      2

     I1     |      6

     I2     |      7

     I5     |      2

第一次扫描事务数据库后L1=[I1, I2, I3, I4, I5]

通过L1 × L1生成C2时:

通过L1 生成L2为:

    I1,I2

    I1,I3

    I1,I4

    I1,I5

    I2,I3

    I2,I4

    I2,I5

    I3,I4

    I3,I5

    I4,I5

----项集----|----支持度----l

     I3,I4     |      0

     I3,I5     |      1

     I2,I4     |      2

     I1,I5     |      2

     I2,I5     |      2

     I2,I3     |      4

     I4,I5     |      0

     I1,I2     |      4

     I1,I4     |      1

     I1,I3     |      4

将候选集C1不满足最小支持度的元素删除后L2为:

    I1,I2

    I1,I3

    I1,I5

    I2,I3

    I2,I4

    I2,I5

通过L2 × L2生成C3时:

   {I1,I3,I5} 的2项子集 { I3,I5} 不是L2的元素,根据先验性质剪技,删除!

   {I2,I3,I4} 的2项子集 { I3,I4} 不是L2的元素,根据先验性质剪技,删除!

   {I2,I3,I5} 的2项子集 { I3,I5} 不是L2的元素,根据先验性质剪技,删除!

   {I2,I4,I5} 的2项子集 { I4,I5} 不是L2的元素,根据先验性质剪技,删除!

通过L2 生成L3为:

    I1,I2,I3

    I1,I2,I5

----项集----|----支持度----l

     I1,I2,I5     |      2

     I1,I2,I3     |      2

将候选集C2不满足最小支持度的元素删除后L3为:

    I1,I2,I3

    I1,I2,I5

通过L3 × L3生成C4时:

   {I1,I2,I3,I5} 的3项子集 { I1,I3,I5} 不是L3的元素,根据先验性质剪技,删除!

执行程序一共花费了11毫秒
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息