GSP序列模式分析算法
来源:互联网 发布:手机淘宝还用装旺信吗 编辑:程序博客网 时间:2024/05/17 02:46
参考资料:http://blog.csdn.net/zone_programming/article/details/42032309
更多数据挖掘代码:https://github.com/linyiqun/DataMiningAlgorithm
介绍
GSP算法是序列模式挖掘算法的一种,他是一种类Apriori的一种,整个过程与Apriori算法比较类似,不过在细节上会略有不同,在下面的描述中,将会有所描述。GSP在原有的频繁模式定义的概念下,增加了3个的概念。1、加入时间约束min_gap,max_gap,要求原来的连续变为只要满足在规定的min_gap到max_gap之间即可。
2、加入time_windows_size,只要在windows_size内的item,都可以被认为是同一ItemSet。
3、加入分类标准。
以上3点新的中的第一条特征将会在后面的算法中着重展现。
算法原理
1、根据所输入的序列,找出所有的单项集,即1频繁模式,这里会经过最小支持度阈值的判断。
2、根据1频繁模式进行连接运算,产生2频繁模式,这里会有进行最小阈值的判断。
3、根据2频繁模式连接产生3频繁模式,会经过最小支持度判断和剪枝操作,剪枝操作的原理在于判断他的所有子集是否也全是频繁模式。
4、3频繁模式不断的挖掘知道不能够产生出候选集为止。
连接操作的原理
2个序列,全部变为item列表的形式,如果a序列去掉第1个元素后,b序列去掉最后1个序列,2个序列的item完全一致,则代表可以连接,由b的最后一个元素加入到a中,至于是以独立项集的身份加入还是加入到a中最后1个项集中取决于b中的最后一个元素所属项集是否为单项项集。
时间约束计算
这个是用在支持度计数使用的,GSP算法的支持度计算不是那么简单,比如序列判断<2, <3, 4>>是否在序列<(1,5), 2 , <3, 4>, 2>,这就不能仅仅判断序列中是否只包含2,<3, 4>就行了,还要满足时间间隔约束,这就要把2,和<3,4>的所有出现时间都找出来,然后再里面找出一条满足时间约束的路径就算包含。时间的定义是从左往右起1.2,3...继续,以1个项集为单位,所有2的时间有2个分别为t=2和t=4,然后同理,因为<3,4>在序列中只有1次,所以时间为t=3,所以问题就变为了下面一个数组的问题
2 4
3
从时间数组的上往下,通过对多个时间的组合,找出1条满足时间约束的方案,这里的方案只有2-3,4-3,然后判断时间间隔,如果存在这样的方式,则代表此序列支持所给定序列,支持度值加1,这个算法在程序的实现中是比较复杂的。
算法的代码实现
测试数据输入(格式:事务ID item数 item1 item2.....):
- 1 2 1 5
- 1 1 2
- 1 1 3
- 1 1 4
- 2 1 1
- 2 1 3
- 2 1 4
- 2 2 3 5
- 3 1 1
- 3 1 2
- 3 1 3
- 3 1 4
- 3 1 5
- 4 1 1
- 4 1 3
- 4 1 5
- 5 1 4
- 5 1 5
<(1,5) 2 3 4>
<1 3 4 (3,5)>
<1 2 3 4 5>
<1 3 5>
<4 5>
也就是说同一序列都是同事务的。下面是关键的类
Sequence.java:
- package DataMining_GSP;
- import java.util.ArrayList;
- /**
- * 序列,每个序列内部包含多组ItemSet项集
- *
- * @author lyq
- *
- */
- public class Sequence implements Comparable<Sequence>, Cloneable {
- // 序列所属事务ID
- private int trsanctionID;
- // 项集列表
- private ArrayList<ItemSet> itemSetList;
- public Sequence(int trsanctionID) {
- this.trsanctionID = trsanctionID;
- this.itemSetList = new ArrayList<>();
- }
- public Sequence() {
- this.itemSetList = new ArrayList<>();
- }
- public int getTrsanctionID() {
- return trsanctionID;
- }
- public void setTrsanctionID(int trsanctionID) {
- this.trsanctionID = trsanctionID;
- }
- public ArrayList<ItemSet> getItemSetList() {
- return itemSetList;
- }
- public void setItemSetList(ArrayList<ItemSet> itemSetList) {
- this.itemSetList = itemSetList;
- }
- /**
- * 取出序列中第一个项集的第一个元素
- *
- * @return
- */
- public Integer getFirstItemSetNum() {
- return this.getItemSetList().get(0).getItems().get(0);
- }
- /**
- * 获取序列中最后一个项集
- *
- * @return
- */
- public ItemSet getLastItemSet() {
- return getItemSetList().get(getItemSetList().size() - 1);
- }
- /**
- * 获取序列中最后一个项集的最后一个一个元素
- *
- * @return
- */
- public Integer getLastItemSetNum() {
- ItemSet lastItemSet = getItemSetList().get(getItemSetList().size() - 1);
- int lastItemNum = lastItemSet.getItems().get(
- lastItemSet.getItems().size() - 1);
- return lastItemNum;
- }
- /**
- * 判断序列中最后一个项集是否为单一的值
- *
- * @return
- */
- public boolean isLastItemSetSingleNum() {
- ItemSet lastItemSet = getItemSetList().get(getItemSetList().size() - 1);
- int size = lastItemSet.getItems().size();
- return size == 1 ? true : false;
- }
- @Override
- public int compareTo(Sequence o) {
- // TODO Auto-generated method stub
- return this.getFirstItemSetNum().compareTo(o.getFirstItemSetNum());
- }
- @Override
- protected Object clone() throws CloneNotSupportedException {
- // TODO Auto-generated method stub
- return super.clone();
- }
- /**
- * 拷贝一份一模一样的序列
- */
- public Sequence copySeqence(){
- Sequence copySeq = new Sequence();
- for(ItemSet itemSet: this.itemSetList){
- copySeq.getItemSetList().add(new ItemSet(itemSet.copyItems()));
- }
- return copySeq;
- }
- /**
- * 比较2个序列是否相等,需要判断内部的每个项集是否完全一致
- *
- * @param seq
- * 比较的序列对象
- * @return
- */
- public boolean compareIsSame(Sequence seq) {
- boolean result = true;
- ArrayList<ItemSet> itemSetList2 = seq.getItemSetList();
- ItemSet tempItemSet1;
- ItemSet tempItemSet2;
- if (itemSetList2.size() != this.itemSetList.size()) {
- return false;
- }
- for (int i = 0; i < itemSetList2.size(); i++) {
- tempItemSet1 = this.itemSetList.get(i);
- tempItemSet2 = itemSetList2.get(i);
- if (!tempItemSet1.compareIsSame(tempItemSet2)) {
- // 只要不相等,直接退出函数
- result = false;
- break;
- }
- }
- return result;
- }
- /**
- * 生成此序列的所有子序列
- *
- * @return
- */
- public ArrayList<Sequence> createChildSeqs() {
- ArrayList<Sequence> childSeqs = new ArrayList<>();
- ArrayList<Integer> tempItems;
- Sequence tempSeq = null;
- ItemSet tempItemSet;
- for (int i = 0; i < this.itemSetList.size(); i++) {
- tempItemSet = itemSetList.get(i);
- if (tempItemSet.getItems().size() == 1) {
- tempSeq = this.copySeqence();
- // 如果只有项集中只有1个元素,则直接移除
- tempSeq.itemSetList.remove(i);
- childSeqs.add(tempSeq);
- } else {
- tempItems = tempItemSet.getItems();
- for (int j = 0; j < tempItems.size(); j++) {
- tempSeq = this.copySeqence();
- // 在拷贝的序列中移除一个数字
- tempSeq.getItemSetList().get(i).getItems().remove(j);
- childSeqs.add(tempSeq);
- }
- }
- }
- return childSeqs;
- }
- }
- package DataMining_GSP;
- import java.util.ArrayList;
- /**
- * 序列中的子项集
- *
- * @author lyq
- *
- */
- public class ItemSet {
- /**
- * 项集中保存的是数字项数组
- */
- private ArrayList<Integer> items;
- public ItemSet(String[] itemStr) {
- items = new ArrayList<>();
- for (String s : itemStr) {
- items.add(Integer.parseInt(s));
- }
- }
- public ItemSet(int[] itemNum) {
- items = new ArrayList<>();
- for (int num : itemNum) {
- items.add(num);
- }
- }
- public ItemSet(ArrayList<Integer> itemNum) {
- this.items = itemNum;
- }
- public ArrayList<Integer> getItems() {
- return items;
- }
- public void setItems(ArrayList<Integer> items) {
- this.items = items;
- }
- /**
- * 判断2个项集是否相等
- *
- * @param itemSet
- * 比较对象
- * @return
- */
- public boolean compareIsSame(ItemSet itemSet) {
- boolean result = true;
- if (this.items.size() != itemSet.items.size()) {
- return false;
- }
- for (int i = 0; i < itemSet.items.size(); i++) {
- if (this.items.get(i) != itemSet.items.get(i)) {
- // 只要有值不相等,直接算作不相等
- result = false;
- break;
- }
- }
- return result;
- }
- /**
- * 拷贝项集中同样的数据一份
- *
- * @return
- */
- public ArrayList<Integer> copyItems() {
- ArrayList<Integer> copyItems = new ArrayList<>();
- for (int num : this.items) {
- copyItems.add(num);
- }
- return copyItems;
- }
- }
- package DataMining_GSP;
- import java.io.BufferedReader;
- import java.io.File;
- import java.io.FileReader;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.Map;
- /**
- * GSP序列模式分析算法
- *
- * @author lyq
- *
- */
- public class GSPTool {
- // 测试数据文件地址
- private String filePath;
- // 最小支持度阈值
- private int minSupportCount;
- // 时间最小间隔
- private int min_gap;
- // 时间最大间隔
- private int max_gap;
- // 原始数据序列
- private ArrayList<Sequence> totalSequences;
- // GSP算法中产生的所有的频繁项集序列
- private ArrayList<Sequence> totalFrequencySeqs;
- // 序列项数字对时间的映射图容器
- private ArrayList<ArrayList<HashMap<Integer, Integer>>> itemNum2Time;
- public GSPTool(String filePath, int minSupportCount, int min_gap,
- int max_gap) {
- this.filePath = filePath;
- this.minSupportCount = minSupportCount;
- this.min_gap = min_gap;
- this.max_gap = max_gap;
- totalFrequencySeqs = new ArrayList<>();
- readDataFile();
- }
- /**
- * 从文件中读取数据
- */
- private void readDataFile() {
- File file = new File(filePath);
- ArrayList<String[]> dataArray = new ArrayList<String[]>();
- try {
- BufferedReader in = new BufferedReader(new FileReader(file));
- String str;
- String[] tempArray;
- while ((str = in.readLine()) != null) {
- tempArray = str.split(" ");
- dataArray.add(tempArray);
- }
- in.close();
- } catch (IOException e) {
- e.getStackTrace();
- }
- HashMap<Integer, Sequence> mapSeq = new HashMap<>();
- Sequence seq;
- ItemSet itemSet;
- int tID;
- String[] itemStr;
- for (String[] str : dataArray) {
- tID = Integer.parseInt(str[0]);
- itemStr = new String[Integer.parseInt(str[1])];
- System.arraycopy(str, 2, itemStr, 0, itemStr.length);
- itemSet = new ItemSet(itemStr);
- if (mapSeq.containsKey(tID)) {
- seq = mapSeq.get(tID);
- } else {
- seq = new Sequence(tID);
- }
- seq.getItemSetList().add(itemSet);
- mapSeq.put(tID, seq);
- }
- // 将序列图加入到序列List中
- totalSequences = new ArrayList<>();
- for (Map.Entry entry : mapSeq.entrySet()) {
- totalSequences.add((Sequence) entry.getValue());
- }
- }
- /**
- * 生成1频繁项集
- *
- * @return
- */
- private ArrayList<Sequence> generateOneFrequencyItem() {
- int count = 0;
- int currentTransanctionID = 0;
- Sequence tempSeq;
- ItemSet tempItemSet;
- HashMap<Integer, Integer> itemNumMap = new HashMap<>();
- ArrayList<Sequence> seqList = new ArrayList<>();
- for (Sequence seq : totalSequences) {
- for (ItemSet itemSet : seq.getItemSetList()) {
- for (int num : itemSet.getItems()) {
- // 如果没有此种类型项,则进行添加操作
- if (!itemNumMap.containsKey(num)) {
- itemNumMap.put(num, 1);
- }
- }
- }
- }
- boolean isContain = false;
- int number = 0;
- for (Map.Entry entry : itemNumMap.entrySet()) {
- count = 0;
- number = (int) entry.getKey();
- for (Sequence seq : totalSequences) {
- isContain = false;
- for (ItemSet itemSet : seq.getItemSetList()) {
- for (int num : itemSet.getItems()) {
- if (num == number) {
- isContain = true;
- break;
- }
- }
- if(isContain){
- break;
- }
- }
- if(isContain){
- count++;
- }
- }
- itemNumMap.put(number, count);
- }
- for (Map.Entry entry : itemNumMap.entrySet()) {
- count = (int) entry.getValue();
- if (count >= minSupportCount) {
- tempSeq = new Sequence();
- tempItemSet = new ItemSet(new int[] { (int) entry.getKey() });
- tempSeq.getItemSetList().add(tempItemSet);
- seqList.add(tempSeq);
- }
- }
- // 将序列升序排列
- Collections.sort(seqList);
- // 将频繁1项集加入总频繁项集列表中
- totalFrequencySeqs.addAll(seqList);
- return seqList;
- }
- /**
- * 通过1频繁项集连接产生2频繁项集
- *
- * @param oneSeq
- * 1频繁项集序列
- * @return
- */
- private ArrayList<Sequence> generateTwoFrequencyItem(
- ArrayList<Sequence> oneSeq) {
- Sequence tempSeq;
- ArrayList<Sequence> resultSeq = new ArrayList<>();
- ItemSet tempItemSet;
- int num1;
- int num2;
- // 假如将<a>,<b>2个1频繁项集做连接组合,可以分为<a a>,<a b>,<b a>,<b b>4个序列模式
- // 注意此时的每个序列中包含2个独立项集
- for (int i = 0; i < oneSeq.size(); i++) {
- num1 = oneSeq.get(i).getFirstItemSetNum();
- for (int j = 0; j < oneSeq.size(); j++) {
- num2 = oneSeq.get(j).getFirstItemSetNum();
- tempSeq = new Sequence();
- tempItemSet = new ItemSet(new int[] { num1 });
- tempSeq.getItemSetList().add(tempItemSet);
- tempItemSet = new ItemSet(new int[] { num2 });
- tempSeq.getItemSetList().add(tempItemSet);
- if (countSupport(tempSeq) >= minSupportCount) {
- resultSeq.add(tempSeq);
- }
- }
- }
- // 上面连接还有1种情况是每个序列中只包含有一个项集的情况,此时a,b的划分则是<(a,a)> <(a,b)> <(b,b)>
- for (int i = 0; i < oneSeq.size(); i++) {
- num1 = oneSeq.get(i).getFirstItemSetNum();
- for (int j = i; j < oneSeq.size(); j++) {
- num2 = oneSeq.get(j).getFirstItemSetNum();
- tempSeq = new Sequence();
- tempItemSet = new ItemSet(new int[] { num1, num2 });
- tempSeq.getItemSetList().add(tempItemSet);
- if (countSupport(tempSeq) >= minSupportCount) {
- resultSeq.add(tempSeq);
- }
- }
- }
- // 同样将2频繁项集加入到总频繁项集中
- totalFrequencySeqs.addAll(resultSeq);
- return resultSeq;
- }
- /**
- * 根据上次的频繁集连接产生新的侯选集
- *
- * @param seqList
- * 上次产生的候选集
- * @return
- */
- private ArrayList<Sequence> generateCandidateItem(
- ArrayList<Sequence> seqList) {
- Sequence tempSeq;
- ArrayList<Integer> tempNumArray;
- ArrayList<Sequence> resultSeq = new ArrayList<>();
- // 序列数字项列表
- ArrayList<ArrayList<Integer>> seqNums = new ArrayList<>();
- for (int i = 0; i < seqList.size(); i++) {
- tempNumArray = new ArrayList<>();
- tempSeq = seqList.get(i);
- for (ItemSet itemSet : tempSeq.getItemSetList()) {
- tempNumArray.addAll(itemSet.copyItems());
- }
- seqNums.add(tempNumArray);
- }
- ArrayList<Integer> array1;
- ArrayList<Integer> array2;
- // 序列i,j的拷贝
- Sequence seqi = null;
- Sequence seqj = null;
- // 判断是否能够连接,默认能连接
- boolean canConnect = true;
- // 进行连接运算,包括自己与自己连接
- for (int i = 0; i < seqNums.size(); i++) {
- for (int j = 0; j < seqNums.size(); j++) {
- array1 = (ArrayList<Integer>) seqNums.get(i).clone();
- array2 = (ArrayList<Integer>) seqNums.get(j).clone();
- // 将第一个数字组去掉第一个,第二个数字组去掉最后一个,如果剩下的部分相等,则可以连接
- array1.remove(0);
- array2.remove(array2.size() - 1);
- canConnect = true;
- for (int k = 0; k < array1.size(); k++) {
- if (array1.get(k) != array2.get(k)) {
- canConnect = false;
- break;
- }
- }
- if (canConnect) {
- seqi = seqList.get(i).copySeqence();
- seqj = seqList.get(j).copySeqence();
- int lastItemNum = seqj.getLastItemSetNum();
- if (seqj.isLastItemSetSingleNum()) {
- // 如果j序列的最后项集为单一值,则最后一个数字以独立项集加入i序列
- ItemSet itemSet = new ItemSet(new int[] { lastItemNum });
- seqi.getItemSetList().add(itemSet);
- } else {
- // 如果j序列的最后项集为非单一值,则最后一个数字加入i序列最后一个项集中
- ItemSet itemSet = seqi.getLastItemSet();
- itemSet.getItems().add(lastItemNum);
- }
- // 判断是否超过最小支持度阈值
- if (isChildSeqContained(seqi)
- && countSupport(seqi) >= minSupportCount) {
- resultSeq.add(seqi);
- }
- }
- }
- }
- totalFrequencySeqs.addAll(resultSeq);
- return resultSeq;
- }
- /**
- * 判断此序列的所有子序列是否也是频繁序列
- *
- * @param seq
- * 待比较序列
- * @return
- */
- private boolean isChildSeqContained(Sequence seq) {
- boolean isContained = false;
- ArrayList<Sequence> childSeqs;
- childSeqs = seq.createChildSeqs();
- for (Sequence tempSeq : childSeqs) {
- isContained = false;
- for (Sequence frequencySeq : totalFrequencySeqs) {
- if (tempSeq.compareIsSame(frequencySeq)) {
- isContained = true;
- break;
- }
- }
- if (!isContained) {
- break;
- }
- }
- return isContained;
- }
- /**
- * 候选集判断支持度的值
- *
- * @param seq
- * 待判断序列
- * @return
- */
- private int countSupport(Sequence seq) {
- int count = 0;
- int matchNum = 0;
- Sequence tempSeq;
- ItemSet tempItemSet;
- HashMap<Integer, Integer> timeMap;
- ArrayList<ItemSet> itemSetList;
- ArrayList<ArrayList<Integer>> numArray = new ArrayList<>();
- // 每项集对应的时间链表
- ArrayList<ArrayList<Integer>> timeArray = new ArrayList<>();
- for (ItemSet itemSet : seq.getItemSetList()) {
- numArray.add(itemSet.getItems());
- }
- for (int i = 0; i < totalSequences.size(); i++) {
- timeArray = new ArrayList<>();
- for (int s = 0; s < numArray.size(); s++) {
- ArrayList<Integer> childNum = numArray.get(s);
- ArrayList<Integer> localTime = new ArrayList<>();
- tempSeq = totalSequences.get(i);
- itemSetList = tempSeq.getItemSetList();
- for (int j = 0; j < itemSetList.size(); j++) {
- tempItemSet = itemSetList.get(j);
- matchNum = 0;
- int t = 0;
- if (tempItemSet.getItems().size() == childNum.size()) {
- timeMap = itemNum2Time.get(i).get(j);
- // 只有当项集长度匹配时才匹配
- for (int k = 0; k < childNum.size(); k++) {
- if (timeMap.containsKey(childNum.get(k))) {
- matchNum++;
- t = timeMap.get(childNum.get(k));
- }
- }
- // 如果完全匹配,则记录时间
- if (matchNum == childNum.size()) {
- localTime.add(t);
- }
- }
- }
- if (localTime.size() > 0) {
- timeArray.add(localTime);
- }
- }
- // 判断时间是否满足时间最大最小约束,如果满足,则此条事务包含候选事务
- if (timeArray.size() == numArray.size()
- && judgeTimeInGap(timeArray)) {
- count++;
- }
- }
- return count;
- }
- /**
- * 判断事务是否满足时间约束
- *
- * @param timeArray
- * 时间数组,每行代表各项集的在事务中的发生时间链表
- * @return
- */
- private boolean judgeTimeInGap(ArrayList<ArrayList<Integer>> timeArray) {
- boolean result = false;
- int preTime = 0;
- ArrayList<Integer> firstTimes = timeArray.get(0);
- timeArray.remove(0);
- if (timeArray.size() == 0) {
- return false;
- }
- for (int i = 0; i < firstTimes.size(); i++) {
- preTime = firstTimes.get(i);
- if (dfsJudgeTime(preTime, timeArray)) {
- result = true;
- break;
- }
- }
- return result;
- }
- /**
- * 深度优先遍历时间,判断是否有符合条件的时间间隔
- *
- * @param preTime
- * @param timeArray
- * @return
- */
- private boolean dfsJudgeTime(int preTime,
- ArrayList<ArrayList<Integer>> timeArray) {
- boolean result = false;
- ArrayList<ArrayList<Integer>> timeArrayClone = (ArrayList<ArrayList<Integer>>) timeArray
- .clone();
- ArrayList<Integer> firstItemItem = timeArrayClone.get(0);
- for (int i = 0; i < firstItemItem.size(); i++) {
- if (firstItemItem.get(i) - preTime >= min_gap
- && firstItemItem.get(i) - preTime <= max_gap) {
- // 如果此2项间隔时间满足时间约束,则继续往下递归
- preTime = firstItemItem.get(i);
- timeArrayClone.remove(0);
- if (timeArrayClone.size() == 0) {
- return true;
- } else {
- result = dfsJudgeTime(preTime, timeArrayClone);
- if (result) {
- return true;
- }
- }
- }
- }
- return result;
- }
- /**
- * 初始化序列项到时间的序列图,为了后面的时间约束计算
- */
- private void initItemNumToTimeMap() {
- Sequence seq;
- itemNum2Time = new ArrayList<>();
- HashMap<Integer, Integer> tempMap;
- ArrayList<HashMap<Integer, Integer>> tempMapList;
- for (int i = 0; i < totalSequences.size(); i++) {
- seq = totalSequences.get(i);
- tempMapList = new ArrayList<>();
- for (int j = 0; j < seq.getItemSetList().size(); j++) {
- ItemSet itemSet = seq.getItemSetList().get(j);
- tempMap = new HashMap<>();
- for (int itemNum : itemSet.getItems()) {
- tempMap.put(itemNum, j + 1);
- }
- tempMapList.add(tempMap);
- }
- itemNum2Time.add(tempMapList);
- }
- }
- /**
- * 进行GSP算法计算
- */
- public void gspCalculate() {
- ArrayList<Sequence> oneSeq;
- ArrayList<Sequence> twoSeq;
- ArrayList<Sequence> candidateSeq;
- initItemNumToTimeMap();
- oneSeq = generateOneFrequencyItem();
- twoSeq = generateTwoFrequencyItem(oneSeq);
- candidateSeq = twoSeq;
- // 不断连接生产候选集,直到没有产生出侯选集
- for (;;) {
- candidateSeq = generateCandidateItem(candidateSeq);
- if (candidateSeq.size() == 0) {
- break;
- }
- }
- outputSeqence(totalFrequencySeqs);
- }
- /**
- * 输出序列列表信息
- *
- * @param outputSeqList
- * 待输出序列列表
- */
- private void outputSeqence(ArrayList<Sequence> outputSeqList) {
- for (Sequence seq : outputSeqList) {
- System.out.print("<");
- for (ItemSet itemSet : seq.getItemSetList()) {
- System.out.print("(");
- for (int num : itemSet.getItems()) {
- System.out.print(num + ",");
- }
- System.out.print("), ");
- }
- System.out.println(">");
- }
- }
- }
- package DataMining_GSP;
- /**
- * GSP序列模式分析算法
- * @author lyq
- *
- */
- public class Client {
- public static void main(String[] args){
- String filePath = "C:\\Users\\lyq\\Desktop\\icon\\testInput.txt";
- //最小支持度阈值
- int minSupportCount = 2;
- //时间最小间隔
- int min_gap = 1;
- //施加最大间隔
- int max_gap = 5;
- GSPTool tool = new GSPTool(filePath, minSupportCount, min_gap, max_gap);
- tool.gspCalculate();
- }
- }
- <(1,), >
- <(2,), >
- <(3,), >
- <(4,), >
- <(5,), >
- <(1,), (3,), >
- <(1,), (4,), >
- <(1,), (5,), >
- <(2,), (3,), >
- <(2,), (4,), >
- <(3,), (4,), >
- <(3,), (5,), >
- <(4,), (5,), >
- <(1,), (3,), (4,), >
- <(1,), (3,), (5,), >
- <(2,), (3,), (4,), >
算法实现的难点
1、算法花费了几天的时间,难点首先在于对算法原理本身的理解,网上对于此算法的资料特别少,而且不同的人所表达的意思 都有少许的不同,讲的也不是很详细,于是就通过阅读别人的代码理解GSP算法的原理,我的代码实现也是参考了参考资料的C语言的实现。
2、在实现时间约束的支持度计数统计的时候,调试了一段时间,做时间统计容易出错,因为层级实在太多容易搞晕。
3、还有1个是Sequence和ItemSet的拷贝时的引用问题,在产生新的序列时一定要深拷贝1个否则导致同一引用会把原数据给改掉的。
GSP算法和Apriori算法的比较
我是都实现过了GSP算法和Apriori算法的,后者是被称为关联规则挖掘算法,偏向于挖掘关联规则的,2个算法在连接的操作上有不一样的地方,还有在数据的构成方式上,Apriori的数据会简单一点,都是单项单项构成的,而且在做支持度统计的时候只需判断存在与否即可。不需要考虑时间约束。Apriori算法给定K项集,连接到K-1项集算法就停止了,而GSP算法是直到不能够产生候选集为止。
- GSP序列模式分析算法
- GSP序列模式分析算法
- 序列模式分析算法GSP的实现
- 序列模式挖掘——GSP算法
- 数据挖掘进阶之序列模式分析算法GSP的实现
- 时间序列频繁模式挖掘:GSP算法、SPADE算法
- 数据挖掘进阶之序列模式挖掘GSP算法
- GSP算法
- 数据挖掘中的模式发现(七)GSP算法、SPADE算法、PrefixSpan算法
- GSP
- 4种序列模式挖掘算法的比较分析
- 序列模式PrefixSpan算法
- 【广告算法工程师入门 19】机制设计-GFP和GSP下的策略行为与均衡分析
- 关联分析之序列模式
- 时序模式--时间序列分析
- 算法分析-最大子序列
- PrefixSpan序列模式挖掘算法
- 序列模式挖掘算法BIDE
- nodejs+mongodb系列教程之(2/5)--认识express4构建的nodes项目
- 网页上传文件,到服务器,再讲数据导入数据库
- Objective-C Block的实现
- 广点通sdk接入 _Banner广告
- 匿名内部类如何同时调用多个方法
- GSP序列模式分析算法
- Java ftp实现文件的上传和下载ftp,sftp sun.net.ftp.FtpProtocolException:Welcome message: SSH-2.0-OpenSSH_5.1
- iOS xib文件引入的两种方式
- Tips for DDIC and Search Help.docx
- Hiredis-redis cplusplus--redis3M
- 决策分类树算法之ID3,C4.5算法系列
- C 语言中的左值和右值。以及对比数组名和指针取数组元素的区别
- 深入理解Android之Gradle
- mybatis之map.xml文件的解读