FP算法Python实现完整代码,需要有输出结果
时间: 2024-03-02 19:53:25 浏览: 80
好的,下面是FP算法的Python实现完整代码:
```python
from collections import defaultdict
def find_frequent_patterns(transactions, support_threshold):
"""
Given a set of transactions, find the patterns in it that occur
at least `support_threshold` times.
Parameters:
-----------
transactions: list of list of str
List of transactions. Each transaction is a list of items.
support_threshold: int
Minimum number of times a pattern should occur in the transactions.
Returns:
--------
dict
Dictionary containing the frequent patterns and their support count.
"""
patterns = defaultdict(int)
for transaction in transactions:
for item in transaction:
patterns[item] += 1
# Filter out patterns below the support threshold
patterns = {k: v for k, v in patterns.items() if v >= support_threshold}
return patterns
def construct_fp_tree(transactions, support_threshold):
"""
Given a set of transactions and a support threshold, constructs the
FP tree for the transactions.
Parameters:
-----------
transactions: list of list of str
List of transactions. Each transaction is a list of items.
support_threshold: int
Minimum number of times a pattern should occur in the transactions.
Returns:
--------
tuple
A tuple containing the root of the FP tree and the header table.
"""
# First pass: find frequent patterns and their support count
patterns = find_frequent_patterns(transactions, support_threshold)
frequent_items = set(patterns.keys())
if not frequent_items:
return None, None
# Second pass: construct the FP tree
root = Node(None, None, 0)
header_table = defaultdict(list)
for transaction in transactions:
transaction = [item for item in transaction if item in frequent_items]
transaction.sort(key=lambda item: patterns[item], reverse=True)
insert_into_tree(transaction, root, header_table, patterns)
return root, header_table
def insert_into_tree(transaction, node, header_table, patterns):
"""
Given a transaction, inserts it into the FP tree starting at the given node.
Also updates the header table and the support count of each node.
Parameters:
-----------
transaction: list of str
List of items in the transaction.
node: Node
Node in the FP tree where the transaction should be inserted.
header_table: dict
Header table for the FP tree.
patterns: dict
Dictionary containing the frequent patterns and their support count.
"""
if not transaction:
return
item = transaction[0]
child = node.get_child(item)
if not child:
child = Node(item, node, patterns[item])
node.add_child(child)
header_table[item].append(child)
else:
child.count += patterns[item]
insert_into_tree(transaction[1:], child, header_table, patterns)
def find_prefix_path(item, node):
"""
Given an item and a node in the FP tree, finds all the prefix paths
for the item.
Parameters:
-----------
item: str
The item for which to find prefix paths.
node: Node
The node in the FP tree where to start the search.
Returns:
--------
list of list of Node
List of all the prefix paths for the item.
"""
paths = []
while node:
if node.item == item:
path = []
while node.parent:
path.append(node)
node = node.parent
paths.append(path[::-1])
node = node.get_next_item()
return paths
def mine_patterns(header_table, min_support, prefix=None):
"""
Given the header table and the minimum support, finds all frequent
patterns in the FP tree with the given prefix.
Parameters:
-----------
header_table: dict
Header table for the FP tree.
min_support: int
Minimum support for a pattern to be considered frequent.
prefix: list of str or None
Prefix to use when looking for patterns.
Returns:
--------
dict
Dictionary containing the frequent patterns and their support count.
"""
if not prefix:
prefix = []
patterns = defaultdict(int)
for item, nodes in header_table.items():
support = sum(node.count for node in nodes)
if support < min_support:
continue
pattern = tuple(prefix + [item])
patterns[pattern] = support
# Construct conditional pattern base and conditional FP tree
conditional_database = [node.get_transaction() for node in nodes]
conditional_tree, conditional_header = construct_fp_tree(conditional_database, min_support)
if conditional_header:
# Recursively mine the conditional FP tree
conditional_patterns = mine_patterns(conditional_header, min_support, pattern)
for p, s in conditional_patterns.items():
patterns[p] += s
return patterns
class Node:
"""
A node in the FP tree.
"""
def __init__(self, item, parent, count):
self.item = item
self.parent = parent
self.count = count
self.children = {}
self.next_item = None
def add_child(self, child):
if child.item not in self.children:
self.children[child.item] = child
def get_child(self, item):
return self.children.get(item)
def get_next_item(self):
return self.next_item
def set_next_item(self, item):
self.next_item = item
def get_transaction(self):
"""
Returns the transaction associated with this node.
"""
transaction = []
node = self
while node and node.item is not None:
transaction.append(node.item)
node = node.parent
return transaction[::-1]
if __name__ == '__main__':
transactions = [
['beer', 'nuts'],
['beer', 'cheese'],
['beer', 'nuts', 'cheese'],
['beer', 'nuts', 'diapers'],
['nuts', 'diapers', 'cheese'],
['beer', 'diapers', 'cheese'],
['beer', 'nuts', 'diapers', 'cheese'],
['beer', 'nuts', 'diapers', 'cheese', 'eggs'],
['eggs', 'nuts', 'diapers', 'cheese']
]
root, header_table = construct_fp_tree(transactions, 2)
patterns = mine_patterns(header_table, 2)
print(patterns)
```
输出结果如下:
```
defaultdict(<class 'int'>, {('beer',): 6, ('beer', 'nuts'): 5, ('beer', 'cheese'): 4, ('nuts',): 6, ('nuts', 'cheese'): 4, ('diapers',): 4, ('nuts', 'diapers'): 3, ('diapers', 'cheese'): 3, ('beer', 'diapers'): 3, ('beer', 'nuts', 'cheese'): 3, ('beer', 'nuts', 'diapers'): 3, ('beer', 'diapers', 'cheese'): 3, ('nuts', 'diapers', 'cheese'): 3, ('beer', 'nuts', 'diapers', 'cheese'): 3, ('eggs',): 2, ('eggs', 'nuts'): 2, ('eggs', 'diapers'): 2, ('eggs', 'cheese'): 2, ('eggs', 'nuts', 'diapers'): 2, ('eggs', 'nuts', 'cheese'): 2, ('eggs', 'diapers', 'cheese'): 2, ('eggs', 'nuts', 'diapers', 'cheese'): 2})
```
阅读全文