zoukankan      html  css  js  c++  java
  • 文本挖掘之文本推荐(子集合生成)

    刘 勇   Email:lyssym@sina.com

    简介

      在研究文本推荐算法时,需要挖掘关键字之间的规则,其中比较重要的一步是构建关键字的集合,即需要求取一个集合的所有子集。因此本文根据需求,采用3种方式实现该算法,以期对后续算法研究提供帮助。

      本文下面从二叉树递归、位图和集合3个角度,对该算法进行研究与实现。

     二叉树递归

      为简要描述,采用数据集为:A= {1,2,3}。二叉树递归如下图-1所示。

    图-1 二叉树递归过程

      对图-1采用二叉树递归解释为:集合中每个元素有2中状态,属于某个集合,或者不属于该集合,因此求取子集的过程则为对每个元素进行取舍的过程。如图-1所示,根节点为初始状态,叶子节点为终结状态,除第一层(根节点)为,后续每一层即为对每个元素展开的一次取舍操作。整个过程采用二叉树的先序遍历。

     1 import java.util.List;
     2 import java.util.ArrayList;
     3 
     4 public class SubSet {
     5     private List<List<String>> listList = null; 
     6     
     7     public SubSet(List<String> list)
     8     {
     9         listList = new ArrayList<List<String>>();
    10         int len = list.size();
    11         List<String> dst = new ArrayList<String>();
    12         for (int i = 0; i < len; i++) {
    13             generate(list, 0, i, dst);
    14         }
    15     }
    16     
    17     
    18     public void generate(List<String> list, int index, int number, List<String> dst) {
    19         if (number == -1) {
    20             List<String> strList = new ArrayList<String>();
    21             for (String s : dst) 
    22                 strList.add(s);
    23             listList.add(strList);
    24             return;
    25         }
    26         
    27         if (index == list.size()) {        
    28             return;
    29         }
    30         String element = list.get(index);
    31         dst.add(element);
    32         generate(list, index+1, number-1, dst);
    33         dst.remove(element);
    34         generate(list, index+1, number, dst);
    35     }
    36 
    37 
    38     public void printList()
    39     {
    40         for (List<String> list : listList) {
    41             for (String s : list) {
    42                 System.out.print(s + "	");
    43             }
    44             System.out.println();
    45         }
    46     }
    47 }

    位图

      为描述方便,采用数据集为:A= {1,2,3}。对于任意一个元素,属于某个集合或者不属于该集合。前述集合以“1”为存在于集合,若为“0”则不存在于该集合,采用位图映射为:

      {1,2,3}

      {0,0,0}-->{}

      {0,0,1}-->{3}

      {0,1,0}-->{2}

      {0,1,1}-->{2,3}

      {1,0,0}-->{1}

      {1,0,1}-->{1,3}

      {1,1,0}-->{1,2}

      {1,1,1}-->{1,2,3}

    import java.util.List;
    import java.util.ArrayList;
    
    public class BitSet {
        private List<List<String>> listList= null;
        
        public BitSet(List<String> list) {
            listList = new ArrayList<List<String>>();
            int len = list.size();
            int mark = 0;
            long end = (1<<len) -1;  // 2^len-1
            for (mark = 0; mark <= end; mark++) {
                List<String> dst = new ArrayList<String>();
                for (int i = 0; i < len ; i++) {
                    if ((1<<i & mark) != 0) { // i has one element
                        dst.add((list.get(i)));
                    }
                }
                
                if (dst.size() > 0) {
                    listList.add(dst);
                }
            }
        }
        
        
        public void printList()
        {
            for (List<String> list : listList) {
                for (String s : list) {
                    System.out.print(s + "	");
                }
                System.out.println();
            }
        }
    }

    集合

      为描述方便,采用数据集为:A={1,2,3,4},其根据两个上一级目标集合生成下一级的目标集合,其核心解决方案为通过上一层集合的前K-2个元素相同(K为新集合的元素个数),则将上一层集合元素合并生成新的集合,如A31={1,2,3},A32={1,2,4},则生成新的目标集合A41={1,2,3,4},该方案最大的优点是:使得生成的集合中,元素没有重复。

      1 import java.util.ArrayList;
      2 import java.util.List;
      3 import java.util.Set;
      4 import java.util.TreeSet;
      5 
      6 public class SetSet {
      7     private List<List<Set<String>>> L = null;
      8     
      9     public SetSet(List<String> set) {
     10         List<Set<String>> initSet = createInitSet(set);
     11         L = new ArrayList<List<Set<String>>>();  // contains all the subsets
     12         L.add(initSet);
     13         int k = 2;
     14         while (L.get(k-2).size() > 0) {
     15             List<Set<String>> Ck = aprioriGen(L.get(k-2), k);
     16             L.add(Ck); // add the C(k) and the generate C(k+1)
     17             k += 1;
     18         }
     19     }
     20     
     21     /**
     22      * create one list
     23      * @param set : the data set 
     24      * @return the list generated
     25      */
     26     public List<Set<String>> createInitSet(List<String> set)
     27     {
     28         List<Set<String>> list = new ArrayList<Set<String>>();
     29         for (String element : set) {
     30             Set<String> e = new TreeSet<String>();
     31             e.add(element);
     32             if (!list.contains(e))
     33                 list.add(e);
     34         }
     35         return list;
     36     }
     37     
     38     /**
     39      * generate the number of k items
     40      * @param list : the source list
     41      * @param k : the numbers
     42      * @return the list with set
     43      */
     44     public List<Set<String>> aprioriGen(List<Set<String>> list, int k) 
     45     {
     46         List<Set<String>> retList = new ArrayList<Set<String>>();
     47         int size = list.size();
     48         for (int i = 0; i < size; i++) {
     49             Set<String> set1 = list.get(i);
     50             for (int j = i+1; j < size; j++) {
     51                 Set<String> set2 = list.get(j);
     52                 if (isEquals(getSubclass(list.get(i), k-2), getSubclass(list.get(j), k-2))) { // the 0:k-2 contain the same elements
     53                     retList.add(getUnion(set1, set2));
     54                 }
     55             }
     56         }        
     57         return retList;
     58     }
     59     
     60     /**
     61      * get the union of two sets
     62      * @param src : the source set
     63      * @param dst : destination set
     64      * @return one set
     65      */
     66     public Set<String> getUnion(Set<String> src, Set<String> dst) 
     67     {
     68         Set<String> set = new TreeSet<String>();
     69         for (String element : src)
     70             set.add(element);
     71         
     72         for (String item : dst) 
     73             if (!set.contains(item))
     74                 set.add(item);
     75         
     76         return set;
     77     }
     78     
     79     /** 
     80      * get the top K elements of the set
     81      * @param src : the source set
     82      * @param k : the top K
     83      * @return the top K elements
     84      */
     85     public Set<String> getSubclass(Set<String> src, int k) 
     86     {
     87         Set<String> set = new TreeSet<String>();
     88         int index = 0;
     89         for (String s : src) {
     90             if (index < k)
     91                 set.add(s);
     92             else 
     93                 break;
     94             
     95             index++;
     96         }
     97         return set;
     98     }
     99     
    100     /**
    101      * assert the equals of tow sets
    102      * @param src : the source set
    103      * @param dst : the destination set
    104      * @return if src == dst, return true else return false
    105      */
    106     public boolean isEquals(Set<String> src, Set<String> dst) 
    107     {
    108         boolean ret = false;
    109         if (src.size() == dst.size()) {
    110             if (src.size() == 0)
    111                 ret = true;
    112             else if (src.containsAll(dst))
    113                 ret = true;
    114         }
    115         return ret;
    116     }    
    117 }

      由于本文在研究文本推荐时,参考《机器学习实战》,故此先入为主,采用了第三种方法。但是,本文作者并不认为第三种方法效率较高,在大规模数据时,作者倾向于先用方案二(位图运算)。

    参考

      [1] Peter Harrington, Machine Learning in action, 人民邮电出版社,2015.4.

      [2] http://blog.csdn.net/pony_maggie/article/details/31042651


      作者:志青云集
      出处:http://www.cnblogs.com/lyssym
      如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】。
      如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。
      如果,您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是【志青云集】。
      本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。


  • 相关阅读:
    Android基础学习之context
    [原]C语言实现的快速排序,采用分治策略,递归实现
    [原]动态获取应用的视图实际大小
    [原]此程序专用来说明C++模板的用法
    [原]C++程序示例:涉及到抽象类、继承…
    [原]C++关于运算符重载的程序报错error…
    [原]用C#模拟实现扑克牌发牌、排序程序…
    [原]用C#模拟实现扑克牌发牌、排序程序。
    Come on , Android 常用开发工具
    ADB 常用命令
  • 原文地址:https://www.cnblogs.com/lyssym/p/4950156.html
Copyright © 2011-2022 走看看