使用python挖掘频繁项集

本实验包含以下内容:

学习挖掘频繁项集,掌握apriori算法

1.实现用apriori算法挖掘频繁项集(最小支持度计数2)  

2.分析你所实现的apriori算法的缺点

3. 数据集:

数据集
TID 项集
T100 I1,I2,I5
T200 I2,I4
T300 I2,I3
T400 I1,I2,I4
T500 I1,I3
T600 I2,I3
T700 I1,I3
T800 I1,I2,I3,I5
T900 I1,I2,I3

代码如下:

# 录入数据
def data_fetch():
    data = [['l1', 'l2', 'l5'],
            ['l2', 'l4'],
            ['l2', 'l3'],
            ['l1', 'l2', 'l4'],
            ['l1', 'l3'],
            ['l2', 'l3'],
            ['l1', 'l3'],
            ['l1', 'l2', 'l3', 'l5'],
            ['l1', 'l2', 'l3']]
    return data


# 根据项目,寻找支持度计数
def xunzhao(s, L):
    k = len(s) - 1  # 根据项目长度,决定在频繁几项集中寻找
    if k < 0:  # s为空的情况
        print(s, '不是有效输入')
    # 标志变量,如果s中的项目有和当前比较的不同的,就置0;
    t = 0
    for i in range(len(L[k])):  # 遍历频繁k项集
        t = 1
        for j in range(k + 1):  # 开始比较是不是该项目
            if L[k][i][0][j] != s[j]:
                t = 0
                break
        if t:
            return L[k][i][1]  # 是的话,返回该项目的支持度计数
    print('未找到')  # 遍历结束的话说明未找到
    return -1  # 返回 -1 (无)


# 得到划分,并顺便求出置信度
def huafen(L, l, conf):  # 划分得到置信度
    X = l[0]  # 需要划分的列表
    lx = len(X)  # 长度
    # 用二进制的性质求真子集
    for i in range(1, 2 ** lx - 1):
        s1 = []
        s2 = []
        for j in range(lx):
            # 二进制末尾是0就进s1,否则就进s2达到划分目的
            if (i >> j) % 2:
                s1.append(X[j])
            else:
                s2.append(X[j])
        conf[str(s1), '->', str(s2)] = l[1] / xunzhao(s1, L)


# 判断s中的数据在data中的数目
def jishu(s, data):
    c = 0  # 记录出现数目
    # 标志变量,如果s中的数据有在data这一行不存在的,就置0;
    t = 0
    for ii in data:  # 数据每一行
        t = 1
        for jj in s:  # 对于 s 中的每一个项
            if not (jj in ii):
                t = 0
                break
        c += t  # 如果 s 在这一行存在,c++
    return c


# 输入频繁k-1项集,支持度计数,数据,输出频繁k项集
def Apriori(L, N, data):
    if not L:
        return L
    L_ = []  # 频繁k项集
    L = [i[0] for i in L]  # k-1项集包含哪些
    k = len(L[0]) + 1  # 几项集
    L_len = len(L)
    up = k - 2  # 拼接同项长度
    i = 0
    while i < L_len - 1:  # 只剩最后一个时肯定没法拼
        A = L[i][0:up]  # 拼接前项
        c = i  # 记录走到那个前项了
        i += 1  # i 到下一个
        for j in range(c + 1, L_len):
            if L[j][0:up] != A:  # 前几项不一致就停止
                i = j  # i 快进到发现新键值的地方
                break
            else:  # 前几项一致时
                s = L[c] + L[j][up:]  # 生成预选项
                t = jishu(s, data)  # 得到 s 的支持度计数
                if t >= N:  # 支持度计数大于N
                    L_.append([s, t])  # 添加到频繁项集中
    return L_


data = data_fetch()  # 生成数据,存到data
N = 2  # 支持度计数
L = {}  # 储存一项集
for i in data:  # 得到所有的一项集
    for j in i:
        if j in L:
            L[j] += 1
        else:
            L[j] = 1
L_1 = []  # 储存频繁一项集
for i in L.keys():  # 取其中所有的频繁集
    if L[i] >= N:
        L_1.append([[i], L[i]])
L = []  # 频繁1~4项集
L.append(sorted(L_1, key=lambda x: x[0]))  # 按键值排序转为列表
print('频繁 1 项集', L[0])
for i in range(3):
    L.append(Apriori(L[i], N, data))  # 求频繁2项集
    print('频繁', i + 2, '项集', L[i + 1])
# 置信度计算 ===============================================
conf = {}  # 储存置信度
# 对每一个k项集分析
print('置信度:============================================')
for i in L[1:len(L)]:  # 频繁1项集不用看
    for j in i:
        huafen(L, j, conf)  # 划分得到置信度
for key in conf:
    print(key,conf[key]*100,'%')

结果示例:

频繁 1 项集 [[['l1'], 6], [['l2'], 7], [['l3'], 6], [['l4'], 2], [['l5'], 2]]
频繁 2 项集 [[['l1', 'l2'], 4], [['l1', 'l3'], 4], [['l1', 'l5'], 2], [['l2', 'l3'], 4], [['l2', 'l4'], 2], [['l2', 'l5'], 2]]
频繁 3 项集 [[['l1', 'l2', 'l3'], 2], [['l1', 'l2', 'l5'], 2]]
频繁 4 项集 []
置信度:============================================
("['l1']", '->', "['l2']") 66.66666666666666 %
("['l2']", '->', "['l1']") 57.14285714285714 %
("['l1']", '->', "['l3']") 66.66666666666666 %
("['l3']", '->', "['l1']") 66.66666666666666 %
("['l1']", '->', "['l5']") 33.33333333333333 %
("['l5']", '->', "['l1']") 100.0 %
("['l2']", '->', "['l3']") 57.14285714285714 %
("['l3']", '->', "['l2']") 66.66666666666666 %
("['l2']", '->', "['l4']") 28.57142857142857 %
("['l4']", '->', "['l2']") 100.0 %
("['l2']", '->', "['l5']") 28.57142857142857 %
("['l5']", '->', "['l2']") 100.0 %
("['l1']", '->', "['l2', 'l3']") 33.33333333333333 %
("['l2']", '->', "['l1', 'l3']") 28.57142857142857 %
("['l1', 'l2']", '->', "['l3']") 50.0 %
("['l3']", '->', "['l1', 'l2']") 33.33333333333333 %
("['l1', 'l3']", '->', "['l2']") 50.0 %
("['l2', 'l3']", '->', "['l1']") 50.0 %
("['l1']", '->', "['l2', 'l5']") 33.33333333333333 %
("['l2']", '->', "['l1', 'l5']") 28.57142857142857 %
("['l1', 'l2']", '->', "['l5']") 50.0 %
("['l5']", '->', "['l1', 'l2']") 100.0 %
("['l1', 'l5']", '->', "['l2']") 100.0 %
("['l2', 'l5']", '->', "['l1']") 100.0 %

进程已结束,退出代码为 0

总结:

        生成备选频繁项集时,没有充分利用频繁项集的子集也属于频繁项集的性质,导致有一些冗余。

你可能感兴趣的:(大数据)