机器学习_规则与关联规则模型Apriori、FP-Growth

1. 何时使用规则模型

 机器学习时常遇到一个问题:当数据并不完全可分时,分类器得分不高。真实世界中的数据经常是这样:各种无意义数据和少量有意义数据混在一起,无意义数据又没什么规律,无法统一去除。比如说,对股票外汇市场受各种因素影响,预测次日涨跌一般各算法效果都不好。虽然找不到通用的规则,却能在数据中探索到一些模式,比如十字星,孕线,三只乌鸦等组合还是具有一定的预测性。
 之前使用决策树时,就遇到过这种情况,虽然整体得分不高,但某些叶节点上纯度高(全是正例或全是反例)并且实例多,可以把该分枝拿出来当规则使用。虽然不能用它预测任意数据,但可以作为一个过滤器使用。

2. 规则模型是什么

 规则模型和决策树同属逻辑模型,不同的是决策树对正例反例同样重视,而规则只重视正例/反例其中一项。因此决策树呈现的是互斥关系,而规则模型允许重叠,结果也相对零散的规则列表。规则更像是在大量数据中挑选有意义的数据。
 如果说树是精确模型,规则模型则是启发式策略(虽然经过修改也能覆盖所有实例,但一般不这么用)。它可以找到数据集中的一个子集,相对于全部数据,该子集有明显的意义。
规则模型多用于处理离散数据,如文本中查找频繁单词,提取摘要,分析购物信息等等。

3. 具体实现

 在实现上,我们可以把规则当成树的变种,稍加修改,便是规则模型。具体有两种做法:一种是找规则,使其覆盖同质(全真或全假)的样本集(和树类似);另一种是选定类别,找覆盖该类别实例样本的规则集。

4. 关联规则

 规则是一个用途很多的算法,关于规则模型的文章不多,有的书把它归入逻辑推理中,而非机器学习。我们最常见的是关联规则,比如用Apriori实现的频繁项集挖掘算法。
 最经典的是购物篮分析中啤酒、尿布的故事,即通过对购物清单的分析,发现看似毫无关系的啤酒和尿布经常在用户的购物篮中一起出现,通过挖掘出啤酒、尿布这个频繁项集,则当一个用户买了啤酒的时候可以为他推荐尿布,从而达到组合营销的目的。
 下面将介绍两种基于关联规则的无监督学习算算法Apriori和FP-growth

5. Apriori

(1) 介绍

 Apriori这个单词在拉丁语中的意思是“来自以前”,也可拆开为a priori,即一次先验。算法的目标是找到出现频率高的简单规则。

(2) 原理

 如果某个项是频繁的,那么它的所有子集也是频繁的。反之,如果一个项集是非频繁的,那么它的超集也是非频的。比如啤酒和尿布常常同时出现,则啤酒单独出现的机率也很高;如果这个地区的人极少喝啤酒,啤酒和尿布的组合也不会常常出现。

(3) 算法

 生成单个物品列表,去掉频率低于支持度的,再组合两个物品,去掉低于支持度的,以此类推,求出频繁项集,在频繁项集中抽取关联规则。
 算法的输入是大量可能相关的数据组合,支持度,置信度。输出是频率项集或关联规则。

(4) 优缺点

 Apriori的优点是易于理解,缺点是算得慢,如果共有N件物品,计算量是2^N-1。在属性过多,或属性的状态过多时都会导致大量计算。

(5) 相关概念

 支持度:数据集中包含该项集的记录所占的比例
 置信度:同时支持度/部分支持度(纯度)
 频繁项集:经常同时出现的物品的集合
 关联规则:两种物品间可能存在很强的关系,比如A,B同时出现,如果A->B,则A称为前件,B称为后件。如果A发生概率50%,而AB概率25%,则A不一定引发B,但如果AB发生概率为49%,则说明A->B。

(6) 例程

i. 功能
从多次购物数据中取频率项集,并显示各组合的支持度

ii. 代码

# -*- coding: utf-8 -*-

from numpy import *

def loadDataSet():
    return [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]]

# 建立所有单项的集合,如购物中的物品集合
def createC1(dataSet):
    C1 = []
    for transaction in dataSet:
        for item in transaction:
            if not [item] in C1:
                C1.append([item])                
    C1.sort()
    return list(map(frozenset, C1))

# D是数据,Ck是各个组的集合,返回满足支持率的组
def scanD(D, Ck, minSupport):
    ssCnt = {} # 字典
    for tid in D: # 每条记录
        for can in Ck: # 每个组
            if can.issubset(tid):
                if not can in ssCnt: # 把组放入字典
                    ssCnt[can]=1
                else: 
                    ssCnt[can] += 1
    numItems = float(len(D))
    retList = []
    supportData = {}
    for key in ssCnt:
        support = ssCnt[key]/numItems
        if support >= minSupport:
            retList.insert(0,key) # 把字典中的该项加入list
        supportData[key] = support
    return retList, supportData

# 建立各个层次的组, 只建立不判断, k是组里元素的个数
def aprioriGen(Lk, k): 
    retList = []
    lenLk = len(Lk)
    for i in range(lenLk):
        for j in range(i+1, lenLk): 
            L1 = list(Lk[i])[:k-2]; L2 = list(Lk[j])[:k-2]
            L1.sort(); L2.sort()
            if L1==L2: #if first k-2 elements are equal
                retList.append(Lk[i] | Lk[j]) #set union
    return retList

def apriori(dataSet, minSupport = 0.5):
    C1 = createC1(dataSet)
    D = list(map(set, dataSet))
    L1, supportData = scanD(D, C1, minSupport)
    L = [L1]
    k = 2
    while (len(L[k-2]) > 0):
        Ck = aprioriGen(L[k-2], k) # 建立组
        Lk, supK = scanD(D, Ck, minSupport) # 判断新组是否适合支持率
        supportData.update(supK)
        L.append(Lk) # 将本次结果加入整体
        k += 1
    return L, supportData

if __name__ == '__main__':
    dataSet = loadDataSet() # 数据是二维数组,每项可看作如一次购物
    L,suppData = apriori(dataSet, minSupport = 0.7)
    print(L)
    print(suppData)

iii. 结果

[[frozenset([3]), frozenset([2]), frozenset([5])], [frozenset([2, 5])], []]
{frozenset([5]): 0.75, frozenset([3]): 0.75, frozenset([3, 5]): 0.5, frozenset([4]): 0.25, frozenset([2, 3]): 0.5, frozenset([2, 5]): 0.75, frozenset([1]): 0.5, frozenset([2]): 0.75}

6. FP-growth

(1) 介绍

 FP是Frequent Pattern的缩写,代表频繁模式。FP-growth比Apriori快,性能提高在两个数量级以上,在大数据集上表现更佳。
 和Apriori多次扫描原始数据相比,FP-Growth算法则只需扫描原始数据两遍,把数据存储在FP-Tree结构中。

(2) FP-Tree

 与搜索树不同的是,一个元素项可以在FP树中出现多次,FP树会存储项集的出现频率。每个项集会以路径的方式存储在树中,存在相似元素的集合会共享树的一部分,只当集合之间完全不同时,树才会分叉。
 除了树,还有个索引表(Header table),把所有含相同元素的组织起来(link list),以便查找。

(3) 算法

先构建FP树,然后从FP树中挖掘频繁项集

i. 收集数据
数据是五次购物的清单(记录),a,b,c,d…分别代表物品(item)

ii. 去除非频繁项l, i, o等,并排序

iii. 将记录依次加入树,并建立索引表(左侧框),粉色为添加第一次购物数据。

iv. 从下往上构造每个item的条件模式基CPB(conditional pattern base)
 顺着header table中item的链表,找出所有包含该item的前缀路径,这些前缀路径就是该item的条件模式基(CPB)
 所有这些CPB的频繁度(计数)为该路径上item的频繁度(计数)

 如包含p的其中一条路径是fcamp,该路径中p的频繁度为2,则该CPB fcam的频繁度为2

v. 构造条件FP-tree(conditional FP-tree)
 累加每个CPB上的item的频繁度(计数),过滤低于阈值的item,构建FP-tree

 如m的CPB{<fca:2>, <fcab:1>},f:3, c:3, a:3, b:1, 阈值假设为3,则过滤掉b。
 递归的挖掘每个条件FP-tree,累加后缀频繁项集,直到找到FP-tree为空或者FP-tree只有一条路径。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,290评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,399评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,021评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,034评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,412评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,651评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,902评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,605评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,339评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,586评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,076评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,400评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,060评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,851评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,685评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,595评论 2 270