关联分析-FP树法python注解

定义树的结构

class treeNode:
    def __init__(self,nameValue,numOccur,parentNode):
        self.name = nameValue #值
        self.count = numOccur #计数
        self.nodeLink = None #横向链
        self.parent = parentNode #父亲节点
        self.children = {}   #儿子节点
    def inc(self,numOccur):
        self.count += numOccur
    def disp(self,ind = 1):   #输出显示
        print ' ' * ind,self.name,' ',self.count
        for child in self.children.values():
            child.disp(ind + 1)

创建树

主要目的是将数据一行一行插入字典树里面,但是先进行了过滤操作,删除了一些不可能出现的项集,并且对记录进行了排序.

#dataSet是记录,minSup是最小支持度
def createTree(dataSet,minSup=1):
    #对每个元素进行计数
    headerTable = {}
    for trans in dataSet 
        for item in trans:
            headerTable[item] = headerTable.get(item,0) + dataSet[trans]

#删除项集大小为1的非频繁项集,根据apriori原则,包含该非频繁项集的项集都不可能是频繁项集
    for k in headerTable.keys():
        if headerTable[k] < minSup:
            del(headerTable[k])
    freqItemSet = set(headerTable.keys())
    if len(freqItemSet) == 0: return None,None
    for k in headerTable:
        headereTable[k] = [headerTable[k],None]
    #创建根节点
    retTree = treeNode('Null Set',1,None)
    #得到删除非频繁k=1的项的 项集,并以字典树的形式插入树里。
    for tranSet, count in dataSet.items():
        localID = {}
        for item in tranSet:
            if item in freqItemSet:
                localD[item] = headerTable[item][0]
        if len(localD) > 0:
            orderedItems = [v[0] for v in sorted(localD.items(),key=lambda p: p[1],reverse = True)]     #按照单个项集的频率进行排序
             updateTree(orderedItems,retTree,headerTable,count)
    return retTree,headerTable

更新树

#items一行记录,inTree FP树的树根,headerTable出现的频繁项集,count这行记录出现的次数
def updateTree(items,inTree,headerTable,count):
    #如果出现了这个节点,就把这个节点的计数增加
    if items[0] in inTree.children:
        inTree.children[items[0]].inc(count)
    else:
    #否则就创建新的节点
        inTree.children[items[0]] = treeNode(items[0],count,inTree)
        #如果这个节点对于的headerTable没有出现就创建.
        if headerTable[items[0]][1] == None:
            headerTable[items[0]][1] = inTree.children[items[0]]
        else:
            updateHeader(headerTable[items[0]][1],inTree.children[items[0]])
    if len(items) > 1:
    #如果要插入字典树的词条还有,那就继续插入剩下的    updateTree(items[1::],inTree.children[items[0]],headerTable,count)
#更新headerLink的链
def updateHeader(nodeToTest,targetNone):
    while(nodeToTest.nodeLink != None):
        nodeToTest = nodeToTest.nodeLink
    nodeToTest.nodeLink = targetNone

制作测试数据

def loadSimpDat():
    simpDat = [['r','z','h','j','p'],
               ['z','y','x','w','v','u','t','s'],
               ['z'],
               ['r','x','n','o','s'],
               ['y','r','x','z','q','t','p'],
               ['y','z','x','e','q','s','t','m']]
    return simpDat
def createInitSet(dataSet):
    retDict = {}
    for trans in dataSet:
        retDict[frozenset(trans)] = 1
    return retDict

输出路径

#leafNode是叶子节点,prefixPath是返回的路径
def ascendTree(leafNode,prefixPath):
    #prefixPath = []
    if leafNode.parent != None:
        prefixPath.append(leafNode.name)
        ascendTree(leafNode.parent,prefixPath)


#返回basePat对于的所有前缀和计数,treeNode是其对应的第一个节点
def findPrefixPath(basePat,treeNode):
    conPats = {}
    while treeNode != None:
        prefixPath = []
        ascendTree(treeNode,prefixPath)
        if len(prefixPath) > 1:
            conPats[frozenset(prefixPaht[1:])]  = treeNode.count
        treeNode = treeNode.nodeLink
    return condPats

总结

  1. 支持度的缺点是在于许多潜在的有意义的模式由于包含比较小的支持度而被删去。
  2. 然后可以使用兴趣因子进行优化。 P(a*b) ? P(a) * P(b)
    如果P(a*b) > P(a) * P(b) 那么就是正相关,如果P(a*b) ==P(a)*P(b)就是独立的.
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: FP-Tree算法是一种高效的频繁项集挖掘算法,适用于大数据集。它通过构建FP-Tree来进行频繁项集挖掘。FP-Tree是一种特殊的树结构,由项和链接组成。 在Python中,可以使用第三方库pyfpgrowth来实现FP-Tree算法。使用方法如下: 1. 安装pyfpgrowth库:pip install pyfpgrowth 2. 导入库:from pyfpgrowth import find_frequent_patterns 3. 使用find_frequent_patterns()函数进行频繁项集挖掘,如:frequent_itemsets = find_frequent_patterns(transactions, min_support) 其中transactions是事务数据集,min_support是最小支持度。 ### 回答2: FP-tree算法是一种用于频繁模式挖掘的算法,它是一种新型的挖掘频繁项集的算法,它挖掘频繁项集时利用了一种基于树结构的压缩存储的方式,能够大大减少挖掘频繁项集的时间和空间开销。它的主要思路是在构建树形结构的同时,对于每个频繁项都记录其支持度计数,这样就可以通过低空间高效的方式挖掘到频繁项集。 在FP-tree算法中,首先需要进行数据预处理,将原始数据转换为FP-tree,在转换过程中需要统计每个元素的支持度计数和元素之间的关联关系,并按照支持度计数从大到小排序,然后剪枝去除支持度计数小于最小支持度的元素。接着,使用FP-tree进行频繁项集挖掘,利用FP-tree的树形结构和每个元素的支持度计数,可以使用分治法来递归地挖掘频繁项集。具体地,FP-tree算法使用递归方式遍历FP-tree,并迭代地将条件模式基转换为新的子问题,在这个过程中可以利用条件的模式基来更新FP-tree,最后根据这些更新后的频繁项集可以得出所有的频繁项集。 在Python中,FP-tree可以通过Python的库plyvel来进行实现,通过代码实现节点的添加,查询,删除,更新等操作,从而实现FP-tree的构建和使用。具体地,对于每个节点,可以用Python中的数据结构字典来进行表示,字典中包括节点的名称,支持度计数,以及指向父节点和子节点的指针。在建树的过程中,可以使用递归方式遍历每个元素,并根据元素的支持度计数来进行排序和剪枝。在挖掘频繁项集的过程中,通过对树进行递归遍历,可以找到每个元素的条件模式基,并使用条件模式基来更新FP-tree,最终可以得到所有的频繁项集。 总而言之,FP-tree算法是一种基于树形结构和压缩存储的频繁项集挖掘算法,在实现上可以通过Python中的字典来进行节点的表示和操作,在具体实现中需要注意剪枝和更新的操作,以及频繁项集的递归遍历。 ### 回答3: FP树算法是一种非常常见的频繁项集挖掘算法,它是由Han等人在2000年提出的。相比传统的Apriori算法,FP树算法的优点在于它可以高效地挖掘频繁项集,大幅提升了算法的效率和准确性。 FP树算法的核心是FP树数据结构,它是一种压缩存储的树形结构,能够高效地存储频繁项集信息。FP树算法的具体步骤如下: 1. 构建项头表:遍历所有的事务,统计每个项出现的频次,并按照频次从大到小排序,构建项头表。 2. 构建FP树:遍历所有的事务,按照事务中项的顺序构建FP树。每个事务中的项要按照项头表中的顺序排序。如果树中已存在该项的节点,则将该节点的计数加1;否则,添加一个新的节点。 3. 抽取频繁项集:根据构建好的FP树和项头表,采用递归的方式,从FP树底部往上挖掘频繁项集。 FP树算法的实现可以使用Python语言,需要用到的库包括numpy和pandas。具体实现步骤如下: 1. 构建项头表:遍历数据集,统计每个项出现的频次,将频繁项保存到一个字典中。 ```python def create_item_dict(data_set): item_dict = {} for trans in data_set: for item in trans: if item in item_dict: item_dict[item] += 1 else: item_dict[item] = 1 return item_dict ``` 2. 构建FP树:遍历数据集,按照项头表中的顺序构建FP树。 ```python class TreeNode: def __init__(self, name_value, num_occurrences, parent_node): self.name = name_value self.count = num_occurrences self.parent = parent_node self.children = {} self.next = None def inc(self, num_occurrences): self.count += num_occurrences def create_tree(data_set, min_sup=1): item_dict = create_item_dict(data_set) freq_items = set([item for item in item_dict.keys() if item_dict[item] >= min_sup]) if len(freq_items) == 0: return None, None for item in item_dict.keys(): if item not in freq_items: del(item_dict[item]) header_table = {item: [item_dict[item], None] for item in freq_items} root_node = TreeNode('Null Set', 1, None) for trans in data_set: local_dict = {} for item in trans: if item in freq_items: local_dict[item] = header_table[item][0] if len(local_dict) > 0: ordered_items = [item[0] for item in sorted(local_dict.items(), key=lambda x: (-x[1], x[0]))] update_tree(ordered_items, root_node, header_table) return root_node, header_table def update_tree(items, cur_node, header_table): if items[0] in cur_node.children: cur_node.children[items[0]].inc(1) else: cur_node.children[items[0]] = TreeNode(items[0], 1, cur_node) if header_table[items[0]][1] is None: header_table[items[0]][1] = cur_node.children[items[0]] else: update_header(header_table[items[0]][1], cur_node.children[items[0]]) if len(items) > 1: update_tree(items[1:], cur_node.children[items[0]], header_table) def update_header(node_to_test, target_node): while node_to_test.next is not None: node_to_test = node_to_test.next node_to_test.next = target_node ``` 3. 抽取频繁项集:采用递归的方式,从FP树底部往上挖掘频繁项集。 ```python def ascend_tree(leaf_node, prefix_path): if leaf_node.parent is not None: prefix_path.append(leaf_node.name) ascend_tree(leaf_node.parent, prefix_path) def find_prefix_path(base_pat, header_table): node = header_table[base_pat][1] pats = [] while node is not None: prefix_path = [] ascend_tree(node, prefix_path) if len(prefix_path) > 1: pats.append(prefix_path[1:]) node = node.next return pats def mine_tree(in_tree, header_table, min_sup, pre_fix, freq_item_list): bigL = [v[0] for v in sorted(header_table.items(), key=lambda x: (-x[1][0], x[0]))] for base_pat in bigL: new_freq_set = pre_fix.copy() new_freq_set.add(base_pat) freq_item_list.append(new_freq_set) cond_patt_bases = find_prefix_path(base_pat, header_table) my_cond_tree, my_head = create_tree(cond_patt_bases, min_sup) if my_head is not None: mine_tree(my_cond_tree, my_head, min_sup, new_freq_set, freq_item_list) ``` 通过以上实现,我们就可以使用FP树算法高效地挖掘频繁项集了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值