R语言聚类与关联规则挖掘Apriori算法的频繁项集产生实例及FP-Growth算法的应用实例

时间:2024-01-22 19:23:49

实验8 R语言聚类与关联规则挖掘

任务二关联规则

例一  Apriori算法的频繁项集产生实例

一、实验目的:

1.能够使用简单的Apriori算法地 统计性能指标,理解大数据中的关联规算法。

2.掌握常用的Apriori的算法原理,了解Apriori算法的特点。

3.能够进行实验学会简单应用。

二、实验环境

硬件:PC机1台

软件:R或Rstudio

三、实验内容:

1.探索准备数据。

2.对数据进行处理。

3.数据的可视化展示。

四、实验步骤

[问题描述]

在R语言中,Apriori关联规则算法是借助arules中的一系列函数来实现的,而另一个包arulesViz则可以实现关联规则的可视化,关联规则分析主要包括对频繁数据集的探索、建立关联规则和关联规则查看和分析。在这我们主要通过Apriori关联规则中apriori方法和Eclat方法实现为例。

[基本要求]  

(1)按实验内容编写完整的程序,并上机验证。

(2)实验完成后,提交电子档教师验收程序,并提交填写好的实验报告。

[实验过程]

(1) apriori() 函数简介

函数语法:

apriori(data,parameter = NULL, appearance = NULL, control = NULL)

参数解析:

data-关联分析的数据集。

parameter参数-对支持度(support)、置信度(confidence)、每个项集所含项数的最大值(maxlen)、最小值(minlen),以及输出结果(target)等重要参数进行设置。各参数默认值:(support=0.1,confidence=0.8, maxlen=10, minlen=l, target=“rules”)。

appearance参数-限制先决条件X(lhs)和关联结果Y (rhs)中具体包含的项。如:设置lhs=beer,将仅输出lhs中含有“啤酒”这一项的关联规则,在默认情况下,所有项都将无限制出现。

control参数-用来控制函数性能,如可以设定对项集进行升序(sort=l)还是降序(sort=-l) 排序,是否向使用者报告进程(verbose=TURE/FALSE)等

(2)参考例程

第一步:数据源

我们选择使用arnles软件包中的Groceries数据集进行算法演示,该数据集是某一食品杂货店一个月的真实交易数据,每一行数据记录一个交易,每个交易中记录了当次交易的商品名称。下面以Groceries数据集展示关联分析函数的用法。

代码清单8-1关联规则分析代码

> install.packages("arules")   #下载安装arules包
> library(arules)                        #加载arules软件包
> data("Groceries")                     #获取数据集Groceries
> summary(Groceries)                 #获取Groceries数据集的概括信息

> inspect(Groceries[1:10])           #观测Groceries数据集的前10行数据

R语言聚类与关联规则挖掘Apriori算法的频繁项集产生实例及FP-Growth算法的应用实例_关联规则

R语言聚类与关联规则挖掘Apriori算法的频繁项集产生实例及FP-Growth算法的应用实例_python_02

第二步:探索和准备数据

首先,我们尝试对apriori()函数以最少的限制,来观察它可以反馈给我们哪些信息,再以此决定下一步操作。这里将支持度的最小阈值(minsup)设置为0.001,置信度最小阈值(mincon) 设为0.5,其他参数不进行设定取默认值,并将所得关联规则名记为rules()。

代码清单8-2 关联规则分析代码

> rules0 = apriori(Groceries, parameter = list ( support=0.001, confidence=0.5 ))                     #生成关联规则rule0

R语言聚类与关联规则挖掘Apriori算法的频繁项集产生实例及FP-Growth算法的应用实例_数据集_03

以上输出结果中包括指明支持度、置信度最小值的参数详解(parameterspecification)部分记录算法执行过程中相关参数的算法控制(algorithmic control)部分,以及apriori算法的基本信息和执行细节,如:apriori函数的版本、各步骤的程序运行时间等。

代码清单8-3 关联规则分析代码

> rules0                                 #显示rule0中生成关连规则的条数
> inspect ( rules0 [ 1:10 ] )  #观测rule0中前10条规则及10条规则展示

R语言聚类与关联规则挖掘Apriori算法的频繁项集产生实例及FP-Growth算法的应用实例_频繁项集_04

面对杂乱无章的大量信息,我们无法快速获取如关联性最强的规则等重要信息。因此,可以考虑选择生成其中关联性较强的若干条规则。

第三步 对生成规则进行强度控制

最常用的方法即是通过提高支持度和置信度的比值来实现这一目的

(1) 通过支持度、置信度共同控制

代码清单8-4 通过支持度、置信度共同控制

> rulesl =apriori(Groceries,parameter=list(support=0.005,confidence=0.5))
#将支持度调整为0.005,记为rule1
> rulesl                                    #显示rule1生成关连规则的条数
set of 120 rules
> rules2=apriori(Groceries,parameter=list(support=0.005,confidence=0.60))
#将置信度调整为0.60,记为rule2
> rules2                                    #显示rule2成关连规则的条数
set of 22 rules
> rules3=apriori(Groceries,parameter=list(support=0.005,confidence=0.64))
#将置信度调整为0.64,记为rule3
> rules3                                    #显示rule2成关连规则的条数
set of 4 rules

>inspect(rules3)

R语言聚类与关联规则挖掘Apriori算法的频繁项集产生实例及FP-Growth算法的应用实例_R语言_05

(2) 主要通过支持度控制

代码清单8-5 通过支持度控制

> rules.sorted_sup = sort ( rules0, by="support")
#给定置信度阈值为0.5,按支持度排序记为rules.sorted_sup
> inspect(rules.sorted_sup [1:5] )         
#输出rules.sorted_sup前5条强关联规则

R语言聚类与关联规则挖掘Apriori算法的频繁项集产生实例及FP-Growth算法的应用实例_R语言_06

(3) 主要通过置信度控制

代码清单8-6 通过置信度控制

> rules.sorted_con = sort ( rules0, by="confidence")
#给定支持度阈值为0.001,按置信度排序,记为rules.sorted_con
> inspect ( rules.sorted_con [1:5] )            
#输出rules.sorted_con前5条强关联规则

R语言聚类与关联规则挖掘Apriori算法的频繁项集产生实例及FP-Growth算法的应用实例_R语言_07

(4) 主要通过提升度控制

我们按lift值进行升序排序并输出前5条。

代码清单8-7 通过提升度控制

> rules.sorted_lift=sort(rules0, by="lift")
#给定支持度阈值为0.001,置信度阈值为0.5,按提升度排序,记为rules.sorted_lift
> inspect ( rules.sorted_lift [1:5] )            
#输出rules.sorted_lift前5条强关联规则

如下即是将目标参数(target)设为“frequentitemsets”后的结果。

R语言聚类与关联规则挖掘Apriori算法的频繁项集产生实例及FP-Growth算法的应用实例_关联规则_08

代码清单8-8 改变输出形式

>itemsets_apr=apriori(Groceries,parameter=list(supp=0.001,target="frequent itemsets"),control=list(sort=-1))              
#将apriori()中的目标参数取设为频繁项集

> itemsets_apr                        #显示所生成频繁项集的个数
> inspect(itemsets_apr[1:5])    #观测前5个频繁项集

R语言聚类与关联规则挖掘Apriori算法的频繁项集产生实例及FP-Growth算法的应用实例_R语言_09

R语言聚类与关联规则挖掘Apriori算法的频繁项集产生实例及FP-Growth算法的应用实例_数据集_10

第五步 关联规则的可视化

以下我们尝试用图形的方式更直观地显示出关联分析结果,这里需要用到R的扩展软件包arulesViz®,我们将介绍几个简单应用。

代码清单8-9 关联规则的可视化

> library(arulesViz)                            #加载程序包aruleViz
> rules5<-apriori(Groceries,parameter = list(support=0.002,confidence=0.5))
#生成关联规则rule5

>rules5                             #显示rules5生成关联规则的条数
set of 1098 rules
> plot(rules5)                                 #对rule5作散点图

R语言聚类与关联规则挖掘Apriori算法的频繁项集产生实例及FP-Growth算法的应用实例_关联规则_11

当单击“filter”过滤按钮后,再单击图形右侧lift颜色条中的某处,即可将小于单击处lift值的关联规则点都过滤掉,如图8-3所示即为过滤掉lift值小于4.5的点后的互动散点图。

> plot(rules5,interactive = TRUE)      #绘制互动散点图

R语言聚类与关联规则挖掘Apriori算法的频繁项集产生实例及FP-Growth算法的应用实例_关联规则_12

另外我们还可以将shading参数设置为“order”来绘制出一种特殊的散点图—Two-key图,如图8-4所示。横纵轴依然为支持度和置信度,而关联规则点的颜色深浅则表示其所代表的关联规则中含有商品的多少,商品种类越多,点的颜色越深。

> plot(rules5,shading = "order",control = list(main="Two-key plot"))#绘制Two-key散点图

R语言聚类与关联规则挖掘Apriori算法的频繁项集产生实例及FP-Growth算法的应用实例_python_13

下面我们将图形类型更改为“grouped”来生成图8-5。从图中按照lift参数来看,关联性最强(圆点颜色最深)的两种商品为黄油(butter)与生/酸奶油(whipped/sourcream);而以support参数来看则是热带水果(tropical fruit)与全脂牛奶(whole milk)关联性最强(圆点尺寸最大)。

> plot(rules5,method = "grouped")#对rules5作分组图

R语言聚类与关联规则挖掘Apriori算法的频繁项集产生实例及FP-Growth算法的应用实例_频繁项集_14

R语言聚类与关联规则挖掘Apriori算法的频繁项集产生实例及FP-Growth算法的应用实例_R语言_15

例二  FP-Growth算法的应用实例

一、实验目的

1.能够使用简单FP-Growth算法的统计性能指标,理解大数据中的关联规则算法。

2.掌握常用的FP-Growth的算法原理,了解其算法的特点。

3.能够进行实验学会简单应用

二、实验环境

硬件:PC机1台

软件:Python

三、实验内容

1.FP-tree的构建

2.频繁项集的挖掘

3.对数据进行分析

四、实验步骤

[问题描述]  

在自定义的数据中队算法进行了验证,现在选取实际的数据进行测试。在数据集合中,包含了100万条记录,文件中的每一行包含某个用户浏览过的新闻报道,用来寻找那些至少被10万人浏览过的报道。

[基本要求]  

(1)按实验内容编写完整的程序,并上机验证。

(2)实验完成后,提交电子档教师验收程序,并提交填写好的实验报告。

[实验过程]

下面就采用Python进行实现。

第一步:构建FP-Tree

代码清单8-10构建FP-Tree

#coding:utf-8
from numpy import *

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):#count计算
        self.count += numOccur

    def disp(self, ind=1):#按照等级打印出每个节点
        print ' '*ind, self.name, ' ', self.count
        for child in self.children.values():
            child.disp(ind+1)

rootNode = treeNode('pyramid', 9, None)#节点
rootNode.children['eye'] = treeNode('eye', 13, None)#子节点
a = rootNode.disp()
print a


def createTree(dataSet,minSup = 1):#FP表示的是频繁模式,其通过链接来连接相似元素,被连起来的元素可以看成是一个链表。将事务数据表中的各个事务对应的数据项按照支持度排序后,把每个事务中的数据项按降序依次插入到一棵以 NULL为根节点的树中,同时在每个结点处记录该结点出现的支持度。
headerTable = {}
    for trans in dataSet:
        for item in trans:
            headerTable[item] = headerTable.get(item, 0) + dataSet[trans]#记录每个元素项出现的频度,计数
    for k in headerTable.keys():#key中
        if headerTable[k] < minSup:
            del(headerTable[k])#删除键值
    freqItemSet = set(headerTable.keys())#建立集合
    if len(freqItemSet) == 0:#不满足最小值支持度要求的除去
        return None, None
    for k in headerTable:
        headerTable[k] = [headerTable[k], None]
    retTree = treeNode('Null Set', 1, None)
    for tranSet, count in dataSet.items():
        localD = {}
        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

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)
        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)


def updateHeader(nodeToTest, targetNode):#更新每个节点的链接
    while (nodeToTest.nodeLink != None):
        nodeToTest = nodeToTest.nodeLink
    nodeToTest.nodeLink = targetNode
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

simpDat = loadSimpDat()
initSet = createInitSet(simpDat)
myFPtree, myHeaderTab = createTree(initSet, 3)
a = myFPtree.disp()
print a


第二步:从FP-Tree中挖掘频繁项集

代码清单8-11 FP-Tree中挖掘频繁项集

def ascendTree(leafNode, prefixPath):  # 从叶节点到根节点的提升
    if leafNode.parent != None:
        prefixPath.append(leafNode.name)
        ascendTree(leafNode.parent, prefixPath)

def findPrefixPath(basePat, treeNode):  # 树节点来自树的表
    condPats = {}
    while treeNode != None:
        prefixPath = []
        ascendTree(treeNode, prefixPath)
        if len(prefixPath) > 1:
            condPats[frozenset(prefixPath[1:])] = treeNode.count
        treeNode = treeNode.nodeLink
    return condPats

simpDat = loadSimpDat()
initSet = createInitSet(simpDat)
myFPtree, myHeaderTab = createTree(initSet, 3)
a = myFPtree.disp()
b = findPrefixPath('x', myHeaderTab['x'][1])
print b


#首先构造FP树,然后利用它来挖掘频繁项集。在构造FP树时,需要对数据集扫描两边,第一遍扫描用来统计频率,第二遍扫描至考虑频繁项集。下面举例对FP树加以说明。def mineTree(inTree, headerTable, minSup, preFix, freqItemList):    bigL = [v[0] for v in sorted(headerTable.items(), key=lambda p: p[1])]#(排序表)    for basePat in bigL:        newFreqSet = preFix.copy()        newFreqSet.add(basePat)        freqItemList.append(newFreqSet)        condPattBases = findPrefixPath(basePat, headerTable[basePat][1])        myCondTree, myHead = createTree(condPattBases, minSup)        if myHead != None:            mineTree(myCondTree, myHead, minSup, newFreqSet, freqItemList)#(1)构建FP树;#(2)从FP树中挖掘频繁项集parsedData = [line.split() for line in open('kosarak.dat').readlines()]#读取数据initSet = createInitSet(parsedData)#建立初始数据集合myFPtree, myHeaderTab = createTree(initSet, 100000)#载入FP结构树myFreqList = []#新建列表a = mineTree(myFPtree,myHeaderTab,100000,set([]),myFreqList)b = len(myFreqList)print bprint myFreqList