자바 가 FP-Growth 알고리즘 을 어떻게 실현 하 는 지 상세 하 게 설명 합 니 다.

FP-growth 알고리즘 자바 구현
이 글 은 실현 에 중점 을 두 었 다.FP 트 리 를 구축 하기 위해 서 는 두 번 의 스 캔 이 필요 합 니 다.
첫 번 째 스 캔
첫 번 째 스 캔 은 최소 지지 도 에 만족 하지 않 는 모든 항목 을 걸 러 냅 니 다.최소 지원 도 를 만족 시 키 는 항목 에 대해 서 는 전역 지원 도 내림차 순 으로 정렬 합 니 다.
이 수요 에 따라 전역 지원 도 에 따라 모든 업무 의 item 을 정렬 하 는 것 이 어 려 울 수 있 습 니 다.
나의 실현 사고.
4
  • 원본 데이터 세트 를 스 캔 하여 2 차원 목록 sourceData 에 저장 합 니 다
  • 하나의 Table 을 유지 하고 모든 item 의 전역 지원 도 를 저장 합 니 다 Total Sup
  • Table 에서 한도 값 minSup 보다 낮은 항목 을 걸 러 냅 니 다
  • Table 을 List 로 변환 하고 Total Sup 내림차 순 으로 정렬 합 니 다
  • 4.567917.2 차원 목록 free qSource 를 새로 만 듭 니 다.sourceData 의 빈번 한 항목 을 보류 하고 모든 사 무 를 전체 지원 도 에 따라 정렬 합 니 다코드
    
    /**
         *       ,     
         * @param path      
         * @throws IOException
         */
    
        private void scanDataSet(String path) throws IOException {
            if(path.equals("")){
                path = filePath;
            }
            FileReader fr = new FileReader(path);
            BufferedReader bufferedReader = new BufferedReader(fr);
            String str;
    //        int maxLength = 0;
            while ( (str = bufferedReader.readLine())!=null){
                ArrayList<Integer> transaction = new ArrayList<>();
                String[] tempEntry ;
                tempEntry = str.split(" ");
                for(int i =0;i< tempEntry.length;i++){
                    if(!tempEntry[i].equals("")){
                        int itemValue = Integer.parseInt(tempEntry[i]);
                        transaction.add(itemValue);
                        if(!similarSingleItemLinkedListHeadsTable.containsKey(itemValue)){
                            similarSingleItemLinkedListHeadsTable.put(itemValue, new SimilarSingleItemLinkedListHead(itemValue,null,1));
                        }else{
                            //         +1
                            similarSingleItemLinkedListHeadsTable.get(itemValue).addSupTotal();
                        }
                    }
                }
    //            if(tempEntry.length>maxLength){
    //                maxLength = tempEntry.length;
    //            }
    
                sourceDataSet.add(transaction);
    
            }
    //        System.out.println(maxLength);
            deleteNonFreqInSSILLHTAndSort();
            deleteNonFreqInSDSAndSort();
            bufferedReader.close();
            fr.close();
        }
            /**
         *       (similarSingleItemLinkedListHeadsTable)     ,        similarSingleItemLinkedListHeads    
         */
        private void deleteNonFreqInSSILLHTAndSort() {
            Hashtable<Integer,SimilarSingleItemLinkedListHead> copyOfSSILLHT =
                    (Hashtable<Integer, SimilarSingleItemLinkedListHead>) similarSingleItemLinkedListHeadsTable.clone();
            Set<Integer> keySet = copyOfSSILLHT.keySet();
            //      
            for(int key: keySet){
                if(similarSingleItemLinkedListHeadsTable.get(key).getSupTotal()<minSupCnt){//       
                    similarSingleItemLinkedListHeadsTable.remove(key);
                }
            }
            //        
            similarSingleItemLinkedListHeadList = new ArrayList<>(similarSingleItemLinkedListHeadsTable.values());
            similarSingleItemLinkedListHeadList.sort(new Comparator<SimilarSingleItemLinkedListHead>() {
                @Override
                public int compare(SimilarSingleItemLinkedListHead o1, SimilarSingleItemLinkedListHead o2) {
                    return o2.getSupTotal() - o1.getSupTotal();
                }
            });
    
        }
            /**
         *      (sourceDataSet)     ,              item      
         *       freqSourceSortedDataSet
         */
        private void deleteNonFreqInSDSAndSort(){
            freqSourceSortedDataSet = (ArrayList<ArrayList<Integer>>) sourceDataSet.clone();
            for(int i =0;i<sourceDataSet.size();i++){
                for(int j = 0;j<sourceDataSet.get(i).size();j++){
                    int item = sourceDataSet.get(i).get(j);
                    //     SSILLHT        ,     item         ,       .
                    if(visitSupTotal(item)==-1){
                        //             
                        freqSourceSortedDataSet.get(i).set(j,Integer.MIN_VALUE);
                    }
                }
                //       .
                freqSourceSortedDataSet.get(i).removeIf(e->e == Integer.MIN_VALUE);
                insertSort(freqSourceSortedDataSet.get(i));
            }
            freqSourceSortedDataSet.removeIf(e->e.size() == 0);
    
        }
    
    이차 주사
    두 번 째 스 캔,구조 FP 트 리.
    스 캔 에 참여 한 것 은 필터 후의 데이터 입 니 다.만약 에 데이터 항목 이 처음 만나면 이 노드 를 만 들 고 헤드 테이블 에 이 노드 를 가리 키 는 지침 을 추가 합 니 다.그렇지 않 으 면 경로 에 따라 해당 하 는 노드 를 찾 아 노드 정 보 를 수정 합 니 다.
    여 기 는 필터,정렬 된 데이터 가 있 기 때문에 간단 합 니 다.우 리 는 단지
  • freqSourceSortedDataSet 의 모든 사무 trans 를 옮 겨 다 니 며 trans 의 모든 item 을 옮 겨 다 니 며 FP 트 리 와 비슷 한 목걸이 표를 구축 합 니 다
  • 4.567917.만약 에 어떤 아 이 템 이 처음 만나면 이 노드 를 만 들 고 비슷 한 목걸이 표 에서 연결 해 야 합 니 다4.567917.체인 시 계 는 더 말 할 필요 가 없다4.567917.이곳 의 FP 나무의 서브 노드 는 개 수 를 정 하지 않 고 특수 한 데이터 구 조 를 사용 해 야 한다.저 는 HashTable 을 사 용 했 습 니 다
    
      /**
         *   FP 
         */
        private void buildFPTree(){
            for(ArrayList<Integer>trans:freqSourceSortedDataSet){
                Node curTreeNode = fpTree.root;
                for(int item :trans){
                    if(!curTreeNode.children.containsKey(item)){
                        Node node = new Node(item,1);
                        curTreeNode.children.put(item,node);
                        node.father = curTreeNode;
                        buildSimilarSingleItemLinkedList(item,curTreeNode);
                    }else{
                        curTreeNode.children.get(item).sup++;
                    }
                    curTreeNode=curTreeNode.children.get(item);
                }
            }
        }
        /**
         *        
         */
        private void buildSimilarSingleItemLinkedList(int item,Node curTreeNode){
            //   item          
    
            int index = searchForItemInHeadsList(item,
                    (ArrayList<SimilarSingleItemLinkedListHead>) similarSingleItemLinkedListHeadList);
            if(similarSingleItemLinkedListHeadList.get(index).next == null){
                similarSingleItemLinkedListHeadList.get(index).next = curTreeNode.children.get(item);
            }else{
                Node visitNode = similarSingleItemLinkedListHeadList.get(index).next;
                while (visitNode.nextSimilar!=null){
    
                    visitNode = visitNode.nextSimilar;
                }
                if(visitNode != curTreeNode.children.get(item))
                    visitNode.nextSimilar = curTreeNode.children.get(item);
            }
        }
        /**
         *  HeadList        
         * @param item  
         * @param similarSingleItemLinkedListHeads      
         * @return   ,-1     
         */
        private int searchForItemInHeadsList(int item, ArrayList<SimilarSingleItemLinkedListHead> similarSingleItemLinkedListHeads) {
            for(int i =0;i<similarSingleItemLinkedListHeads.size();i++){
                if(similarSingleItemLinkedListHeads.get(i).getItemValue() == item){
                    return i;
                }
            }
            return -1;
        }
        
    
    빈번 한 항목 집합 발굴
    이 부분 은 개인 적 으로 실현 에 있어 서 가장 어 려 운 부분 이 라 고 생각한다.하지만 나 는 B 역 이나 다른 곳 에서 이곳 과 관련 되면 모두 빨리 말한다.그리고 서로 다른 개념 도 있다.예 를 들 어 흑 피 책 에서 말 하 는 것 은 접두사 경로 이 고 다른 곳 에서 조건 부 모델 기반 등 개념 이 있다.다음 코드 는 모두 접두사 경로 에 따라 이 루어 집 니 다.
    잦 은 항목 집 을 발굴 하려 면 무엇 을 해 야 할 지 생각 을 정리 해 보 자.
    우선 비슷 한 목걸이 목록 을 뒤에서 옮 겨 다 녀 야 합 니 다.
    각 항목 의 귀속 지 에 대해 다음 과 같은 절 차 를 진행한다.
    ① 접두사 경 로 를 기록한다.내 가 사용 하 는 방법 은 접두사 경로 에 나타 난 모든 노드 를 HashSet 로 기록 하 는 것 이다.
    ② 이 FP 트 리 의 항목 별 지지 도 를 기록 합 니 다.앞의 첫 번 째 스 캔 과 유사 합 니 다.
    ③ 기록 의 지지 도 에 따라 item 이 잦 으 면 이 item 과 현재 접 두 사 는 빈번 한 항목 집합 입 니 다.
    ④ record 에 따라 이 FP 트 리 의 비슷 한 목걸이 목록 을 구축 하여 비 빈번 항목(첫 번 째 스 캔 과 유사)과 현재 아 이 템 구성 조건 인 FP 트 리 를 제거 합 니 다.조건 FP 트 리 를 구성 하기 위해 서 는 FP 트 리 의 구 조 를 다시 만 들 필요 가 없습니다.접두사 경 로 를 기록 하려 면 비슷 한 항목 과 부모 항목 에 만 접근 해 야 하기 때 문 입 니 다.
    ⑤ 비슷 한 목걸이 목록 의 나머지 항목 을 ① 절 차 를 거 쳐 비슷 한 목걸이 목록 에 항목 이 없 을 때 까지 종료 한다.
    
    /**
         *       
         * @param minSupCnt        
         * @param path     
         * @param pT            
         */
        public void run(int minSupCnt,String path,int pT) throws IOException {
            this.printThreshold = pT;
            this.minSupCnt = minSupCnt;
            scanDataSet(path);
            buildFPTree();
            for(int i = similarSingleItemLinkedListHeadList.size()-1;i>=0;i--){
                genFreqItemSet(similarSingleItemLinkedListHeadList.get(i).getItemValue()
                        ,fpTree,similarSingleItemLinkedListHeadList,new TreeSet<>());
            }
            //genFreqItemSet(14,fpTree,similarSingleItemLinkedListHeadList,new TreeSet<>());
            System.out.println("      :\t"+cntOfFreqSet);
        }
    /**
         *       
         * @param last    
         * @param fPTree   FP 
         * @param fatherSimilarSingleItemLinkedListHeads            
         * @param freqItemSet     
         */
        private void genFreqItemSet(int last,FPTree fPTree,
                                    List<SimilarSingleItemLinkedListHead>fatherSimilarSingleItemLinkedListHeads,TreeSet<Integer>freqItemSet) {
    
            FPTree conditionalFPTree = new FPTree();
            List<SimilarSingleItemLinkedListHead>similarSingleItemLinkedListHeads = new ArrayList<>();
    
            TreeSet<Integer>localFreqItemSet = (TreeSet<Integer>) freqItemSet.clone();
            int index ;
            index = searchForItemInHeadsList(last,
                    (ArrayList<SimilarSingleItemLinkedListHead>) fatherSimilarSingleItemLinkedListHeads);
    
            Node firstNode = fatherSimilarSingleItemLinkedListHeads.get(index).next;
            HashSet<Node>record = new HashSet<>();  //              
            //      
            if(firstNode!=null){
                record.add(firstNode);
                Node nodeToVisitFather = firstNode;
                Node nodeToVisitSimilar = firstNode;
                while (nodeToVisitSimilar!=null){
                    nodeToVisitSimilar.supInCFP = nodeToVisitSimilar.sup;
                    nodeToVisitFather = nodeToVisitSimilar;
                    while (nodeToVisitFather!=null){
                        //   supInCFT
                        if(nodeToVisitFather!=nodeToVisitSimilar)
                            nodeToVisitFather.supInCFP += nodeToVisitSimilar.supInCFP;
                        record.add(nodeToVisitFather);
                        nodeToVisitFather = nodeToVisitFather.father;
                    }
                    nodeToVisitSimilar = nodeToVisitSimilar.nextSimilar;
                }
    
                //          
                Hashtable<Integer,Integer> supRecord = new Hashtable<>();
                record.forEach(new Consumer<Node>() {
                    @Override
                    public void accept(Node node) {
                        int item = node.item;
                        if(item == -1 ){    //   
                            return;
                        }
                        if(supRecord.containsKey(item)){
                            supRecord.put(item,supRecord.get(item)+ node.supInCFP);
                        }else{
                            supRecord.put(item,node.supInCFP);
                        }
    
                    }
                });
                //    
                if(supRecord.get(last)>=minSupCnt){
                    localFreqItemSet.add(last);
                    if(localFreqItemSet.size()>=printThreshold && !result.contains(localFreqItemSet)){
                        cntOfFreqSet++;
    //                    for(int i = localFreqItemSet.size()-1;i>=0;i--){
    //                        System.out.print(localFreqItemSet.get(i)+" ");
    //                    }
                        localFreqItemSet.forEach(new Consumer<Integer>() {
                            @Override
                            public void accept(Integer integer) {
                                System.out.print(integer+" ");
                            }
                        });
                        result.add(localFreqItemSet);
    
                        System.out.println("");
                    }
                }
    
                //       
                record.forEach(new Consumer<Node>() {
                    @Override
                    public void accept(Node node) {
                        if(node.item == -1){    //   
                            Node visitNode = node;
                            buildConditionalFPTree(conditionalFPTree.root, visitNode,record,
                                    (ArrayList<SimilarSingleItemLinkedListHead>) similarSingleItemLinkedListHeads,supRecord,last);
                        }
                    }
                });
                //        
                similarSingleItemLinkedListHeads.sort(new Comparator<SimilarSingleItemLinkedListHead>() {
                    @Override
                    public int compare(SimilarSingleItemLinkedListHead o1, SimilarSingleItemLinkedListHead o2) {
                        return o2.getSupTotal() - o1.getSupTotal();
                    }
                });
    
                if(similarSingleItemLinkedListHeads.size()>=1){
                    //       
                    for(int i =similarSingleItemLinkedListHeads.size()-1;i>=0;i--){
                        genFreqItemSet(similarSingleItemLinkedListHeads.get(i).getItemValue(),
                                conditionalFPTree,similarSingleItemLinkedListHeads,localFreqItemSet);
                        // similarSingleItemLinkedListHeads.remove(i);
                    }
                }
            }
        }
    /**
         *       FP 
         * @param rootNode             FP 
         * @param originalNode  rootNode         
         * @param record        
         * @param similarSingleItemLinkedListHeads         
         * @param supRecord         
         * @param last    
         */
        private void buildConditionalFPTree(Node rootNode,Node originalNode,HashSet<Node>record
                ,ArrayList<SimilarSingleItemLinkedListHead>similarSingleItemLinkedListHeads,Hashtable<Integer,Integer>supRecord,int last){
            if(originalNode.children!=null){
                for(int key:originalNode.children.keySet()){    //  originalNode       ,           
                    Node tempNode = originalNode.children.get(key);
                    if(record.contains(tempNode)){
                        Node addedNode = new Node(tempNode.item, tempNode.supInCFP);
                        if(last == key){    //  last     
                            tempNode.supInCFP = 0;
                            continue;
                        }
                        if(supRecord.get(key)>=minSupCnt){
                            //addedNode    tempNode         
                            addedNode.supInCFP = tempNode.supInCFP;
                            rootNode.children.put(tempNode.item, addedNode);
                            addedNode.father = rootNode;
                            //      
                            int i = searchForItemInHeadsList(tempNode.item,similarSingleItemLinkedListHeads);
                            if(i==-1){
                                similarSingleItemLinkedListHeads.add(new SimilarSingleItemLinkedListHead(key,addedNode, addedNode.supInCFP));
                            }else{
                                similarSingleItemLinkedListHeads.get(i).setSupTotal(similarSingleItemLinkedListHeads.get(i).getSupTotal()+addedNode.supInCFP);
                                Node visitNode = similarSingleItemLinkedListHeads.get(i).next;
                                 while (visitNode.nextSimilar!=null){
                                    visitNode = visitNode.nextSimilar;
                                }
                                if(visitNode!=addedNode){
                                    visitNode.nextSimilar= addedNode;
                                }
                            }
                            buildConditionalFPTree(addedNode,originalNode.children.get(key),record,similarSingleItemLinkedListHeads,supRecord,last);
                            addedNode.supInCFP = 0; // supInCFP   0;
                        }else{
                            buildConditionalFPTree(rootNode,originalNode.children.get(key),record,similarSingleItemLinkedListHeads,supRecord,last);
                        }
    
                    }
                }
            }
        }
    
    전체 코드
    FP-Growth
    자바 가 FP-Growth 알고리즘 을 어떻게 실현 하 는 지 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 자바 가 FP-growth 알고리즘 을 실현 하 는 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!

    좋은 웹페이지 즐겨찾기