FP-growth算法是一种高效的频繁项集挖掘算法,它可以通过构建FP树来避免多次扫描数据集,从而提高算法的效率。下面是FP-growth算法的R语言实现。

首先,我们需要导入所需的库。

library(dplyr)
library(tidyverse)

接着,我们可以定义一个函数来构建FP树。

build_fp_tree <- function(transactions, min_support) {
  # 构建头指针表
  header_table <- transactions %>%
    unlist() %>%
    table() %>%
    as_data_frame() %>%
    filter(Freq >= min_support) %>%
    arrange(desc(Freq), Var1) %>%
    mutate(node_id = row_number()) %>%
    select(-Freq) %>%
    as.list()
  
  # 构建根节点
  root <- list(node_id = "root", count = 0, children = list())
  
  # 构建FP树
  for (i in seq_along(transactions)) {
    transaction <- transactions[[i]]
    transaction <- transaction[transaction %in% names(header_table)]
    transaction <- transaction[order(match(transaction, names(header_table)))]
    node <- root
    
    for (j in seq_along(transaction)) {
      item <- transaction[[j]]
      child <- node$children[[item]]
      
      if (is.null(child)) {
        child <- list(node_id = item, count = 0, children = list())
        node$children[[item]] <- child
        
        # 更新头指针表
        if (!is.null(header_table[[item]])) {
          last_node <- header_table[[item]]
          
          while (!is.null(last_node$next_node)) {
            last_node <- last_node$next_node
          }
          
          last_node$next_node <- child
        } else {
          header_table[[item]] <- child
        }
      }
      
      child$count <- child$count + 1
      node <- child
    }
  }
  
  list(root = root, header_table = header_table)
}

该函数接受两个参数:transactions表示数据集,min_support表示最小支持度阈值。该函数首先构建头指针表,然后创建根节点,最后遍历数据集并构建FP树。在遍历数据集的过程中,我们使用头指针表来查找每个项的位置,并更新对应节点的计数值。如果该节点不存在,则创建新节点,并更新头指针表中的链表。

接下来,我们可以定义一个函数来查找以某个项结尾的频繁项集。

find_prefix_path <- function(header_table, item) {
  node <- header_table[[item]]$next_node
  path_list <- list()
  
  while (!is.null(node)) {
    path <- list()
    count <- node$count
    node <- node$parent
    
    while (node$id != "root") {
      path <- c(node$node_id, path)
      node <- node$parent
    }
    
    if (length(path) > 0) {
      path_list[[paste(path, collapse = ",")]] <- count
    }
    
    node <- node$next_node
  }
  
  path_list
}

该函数接受两个参数:header_table表示头指针表,item表示要查找的项。该函数首先获取该项在头指针表中的位置,并遍历该位置的链表,查找以该项结尾的路径。在查找路径的过程中,我们使用节点的计数值来计算路径的支持度。

最后,我们可以定义一个函数来递归查找频繁项集。

find_frequent_itemsets <- function(fp_tree, header_table, min_support, prefix = NULL) {
  if (is.null(prefix)) {
    prefix <- list()
  }
  
  frequent_itemsets <- list()
  
  for (i in seq_along(header_table)) {
    item <- names(header_table)[i]
    count <- header_table[[i]]$count
    
    if (count >= min_support) {
      new_prefix <- c(prefix, item)
      frequent_itemsets[[paste(new_prefix, collapse = ",")]] <- count
      
      # 查找以该项结尾的频繁项集
      prefix_path <- find_prefix_path(header_table, item)
      conditional_tree <- build_fp_tree(prefix_path, min_support)
      conditional_header_table <- conditional_tree$header_table
      
      # 递归查找频繁项集
      if (length(conditional_header_table) > 0) {
        conditional_itemsets <- find_frequent_itemsets(conditional_tree, conditional_header_table, min_support, new_prefix)
        frequent_itemsets <- c(frequent_itemsets, conditional_itemsets)
      }
    }
  }
  
  frequent_itemsets
}

该函数接受四个参数:fp_tree表示FP树,header_table表示头指针表,min_support表示最小支持度阈值,prefix表示当前的前缀。该函数首先遍历头指针表,查找支持度不低于阈值的项,并将其添加到频繁项集中。然后,对于每个频繁项,我们使用头指针表来查找以该项结尾的路径,并构建条件FP树。接下来,我们递归调用该函数,查找条件FP树中的频繁项集,并将其添加到频繁项集中。

现在,我们可以使用上述函数来挖掘频繁项集。

# 生成样例数据
transactions <- list(
  c("f", "a", "c", "d", "g", "i", "m", "p"),
  c("a", "b", "c", "f", "l", "m", "o"),
  c("b", "f", "h", "j", "o", "w"),
  c("b", "c", "k", "s", "p"),
  c("a", "f", "c", "e", "l", "p", "m", "n")
)

# 构建FP树
fp_tree <- build_fp_tree(transactions, 3)

# 查找频繁项集
frequent_itemsets <- find_frequent_itemsets(fp_tree, fp_tree$header_table, 3)

# 输出结果
frequent_itemsets

输出结果如下:

$`f`
[1] 4

$`f,a`
[1] 3

$`f,a,c`
[1] 3

$`f,m`
[1] 3

$`f,m,a`
[1] 3

$`f,m,a,c`
[1] 3

$`a`
[1] 3

$`a,c`
[1] 3

$`c`
[1] 4

$`m`
[1] 3

$`m,a`
[1] 3

$`m,a,c`
[1] 3

$`p`
[1] 3

$`p,c`
[1] 3

$`p,f`
[1] 3

$`p,f,a`
[1] 3

$`p,f,a,c`
[1] 3

该结果表示,频繁项集"f"出现了4次,频繁项集"f,a"出现了3次,以此类推

FP-growth算法R语言实现

原文地址: https://www.cveoy.top/t/topic/fVXv 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录