用python实现Apriori算法

Apriori算法是一种关联规则挖掘算法,用来找频繁项集和关联规则,Apriori算法利用了频繁项集的子集也一定是频繁的这一思想,例如,如果{A,B} 是频繁项集,则 {A}和{B} 也一定是频繁项集
从1到k(k项集)递归查找频繁项集,再用得到的频繁项集生成关联规则

例题

在这里,我用如下一题进行讲述:
提取以下购物篮数据中的频繁项集和强关联规则(参数设置:最小支持度计数 = 4,最小置信度 = 0.6)

事务ID

购买商品

001

面包,黄油,尿布,啤酒

002

咖啡,糖,小甜饼,鲑鱼,啤酒

003

面包,黄油,咖啡,尿布,啤酒,鸡蛋

004

面包,黄油,鲑鱼,鸡

005

鸡蛋,面包,黄油

006

鲑鱼,尿布,啤酒

007

面包,茶,糖鸡蛋

008

咖啡,糖,鸡,鸡蛋

009

面包,尿布,啤酒,盐

010

茶,鸡蛋,小甜饼,尿布,啤酒

首先我们将数据放入到文件当中,如下:

面包,黄油,尿布,啤酒
咖啡,糖,小甜饼,鲑鱼,啤酒
面包,黄油,咖啡,尿布,啤酒,鸡蛋
面包,黄油,鲑鱼,鸡
鸡蛋,面包,黄油
鲑鱼,尿布,啤酒
面包,茶,糖,鸡蛋
咖啡,糖,鸡,鸡蛋
面包,尿布,啤酒,盐
茶,鸡蛋,小甜饼,尿布,啤酒

导入一些需要用到的模块

import pandas as pd
import numpy as np
import itertools

读取文件中数据并进行处理

#读取数据并进行编号和转换
def load_dataSet():
    #利用pandas读取数据
    data = pd.read_csv('test4-1.csv', header=None, sep='\t', encoding='UTF-8')
    # print(data.values)
    # print('----')
    goods = []
    goodsList = {}
    change_data= []

    #对商品进行编号
    for key in data.values:
        key = key[0]
        key = key.split(',')
        for i in key:
            if i not in goods:
                goods.append(i)

    for key in range(len(goods)):
        goodsList[goods[key]] = key + 1

    #输出商品的编号
    print('商品编号:', goodsList)

    #转换数据
    for key in data.values:
        key_num = []
        key = key[0].split(',')

        for i in key:
            key_num.append(goodsList[i])

        key_num.sort()
        change_data.append(key_num)

    #输出转换后的数据
    print('\n转换后的数据:', change_data)

    return goodsList, change_data

加载数据并处理的结果如下

python sobel算子 python apriori算法 sklearn_数据挖掘


算法中需要将商品进行排列组合,代码如下

#separate函数用于将data中的数据进行排列组合,i是组合的大小
def separate(data, i):
    a = []
    b = []
    for k in data:
        for j in range(len(k)):
            if k[j] not in a:
                a.append(k[j])

    if i <= len(a):
        for k in itertools.combinations(a, i):
            b.append(list(k))
    return b

计算支持度核心算法如下:

#Apriori算法,其中s是最小支持度,data是数据集,data_iter是迭代中的数据集,c是输出的频繁项集,s是频繁项集对应的支持度
def apriori(s_min, data, data_iter, s=[], c=[], i=1):
    if len(data_iter) != 0:
        goods = separate(data_iter, i)
        data_iter = []
        for good in goods:
            num = 0
            for key in data:
                if set(good) <= set(key):
                    num = num + 1
            if num >= s_min:
                c.append(good)
                s.append(num)
                data_iter.append(good)

        apriori(s_min, data, data_iter, s, c, i=i+1)

计算支持度的结果截图如下

python sobel算子 python apriori算法 sklearn_python_02


计算关联规则的代码如下

#根据频繁项集获取关联规则,c是最小置信度,S是置信度列表,C是频繁项集
def get_associationRules(c, S, C, goodList):
    for key in C:
        a = []
        b = []
        if len(key) > 1:
            for i in key:
                a.append([i])
                b.append(list(goodList.keys())[list(goodList.values()).index(i)])

            for a_value in a:
                a_value_c = S[C.index(a_value)]
                key_c = S[C.index(key)]
                if key_c/a_value_c >= c:
                    # print(a_value, ' ---> ', key, ' : ', key_c/a_value_c)
                    value = list(goodList.keys())[list(goodList.values()).index(a_value[0])]
                    d = b.copy()
                    d.remove(value)
                    print([list(goodList.keys())[list(goodList.values()).index(a_value[0])]],
                          ' ---> ', d, ' : ', key_c/a_value_c)

结果如下:

python sobel算子 python apriori算法 sklearn_数据挖掘_03


以下是完整代码:

import pandas as pd
import numpy as np
import itertools

#读取数据并进行编号和转换
def load_dataSet():
    # , error_bad_lines = False, index_col=0
    #利用pandas读取数据
    data = pd.read_csv('test4-1.csv', header=None, sep='\t', encoding='UTF-8')
    # print(data.values)
    # print('----')
    goods = []
    goodsList = {}
    change_data= []

    #对商品进行编号
    for key in data.values:
        key = key[0]
        key = key.split(',')
        for i in key:
            if i not in goods:
                goods.append(i)

    for key in range(len(goods)):
        goodsList[goods[key]] = key + 1

    #输出商品的编号
    print('商品编号:', goodsList)

    #转换数据
    for key in data.values:
        key_num = []
        key = key[0].split(',')

        for i in key:
            key_num.append(goodsList[i])

        key_num.sort()
        change_data.append(key_num)

    #输出转换后的数据
    print('\n转换后的数据:', change_data)

    return goodsList, change_data

#Apriori算法,其中s是最小支持度,data是数据集,data_iter是迭代中的数据集,c是输出的频繁项集,s是频繁项集对应的支持度
def apriori(s_min, data, data_iter, s=[], c=[], i=1):
    if len(data_iter) != 0:
        goods = separate(data_iter, i)
        data_iter = []
        for good in goods:
            num = 0
            for key in data:
                if set(good) <= set(key):
                    num = num + 1
            if num >= s_min:
                c.append(good)
                s.append(num)
                data_iter.append(good)

        apriori(s_min, data, data_iter, s, c, i=i+1)

#separate函数用于将data中的数据进行排列组合,i是组合的大小
def separate(data, i):
    a = []
    b = []
    for k in data:
        for j in range(len(k)):
            if k[j] not in a:
                a.append(k[j])

    if i <= len(a):
        for k in itertools.combinations(a, i):
            b.append(list(k))
    return b

#根据频繁项集获取关联规则,c是最小置信度,S是置信度列表,C是频繁项集
def get_associationRules(c, S, C, goodList):
    for key in C:
        a = []
        b = []
        if len(key) > 1:
            for i in key:
                a.append([i])
                b.append(list(goodList.keys())[list(goodList.values()).index(i)])

            for a_value in a:
                a_value_c = S[C.index(a_value)]
                key_c = S[C.index(key)]
                if key_c/a_value_c >= c:
                    # print(a_value, ' ---> ', key, ' : ', key_c/a_value_c)
                    value = list(goodList.keys())[list(goodList.values()).index(a_value[0])]
                    d = b.copy()
                    d.remove(value)
                    print([list(goodList.keys())[list(goodList.values()).index(a_value[0])]],
                          ' ---> ', d, ' : ', key_c/a_value_c)

if __name__ == '__main__':
    goodList, data = load_dataSet()

    C = []
    C1 = []
    S = []
    #设置最小支持度为4
    apriori(4, data, data, S, C)

    for value in C:
        a = []
        for i in value:
            a.append(list(goodList.keys())[list(goodList.values()).index(i)])
        C1.append(a)

    # print('支持度:', S)
    # print('频繁项集:', C)
    # print(C1)

    print('\n频繁项集的支持度')
    for i in range(len(C1)):
        print(C1[i], '的支持度:', S[i])

    #输出关联规则
    print('\n关联规则:置信度')
    get_associationRules(0.6, S, C, goodList)