Python:优化函数以找到给定候选项目集的大小为k的频繁项目集

Asr

我编写了一个函数,用于在给定候选项目集的情况下找到大小为k的项目集的频率。数据集包含16000多个事务。有人可以帮我优化此功能吗,因为以当前形式使用minSupport = 1大约需要45分钟才能执行。

样本数据集

数据集

附庸风雅

算法0(请参阅下面的其他算法)

使用Numba实现了算法的增强Numba是一个JIT编译器,可将Python代码转换为高度优化的C ++代码,然后编译为机器代码。对于许多算法,Numba的速度提高了50-200倍。

要使用numba,您必须通过安装它pip install numba,请注意,仅Numba仅支持python <= 3.8,而3.9尚未发布!

我已经重新编写了一些代码以满足Numba的编译要求,我的代码在行为上应该与您的代码相同,请进行一些测试。

我的numba优化代码应该为您带来非常好的加速!

我也创建了一些人为的简短示例输入数据来进行测试。

在线尝试!

import numba, numpy as np, pandas as pd

@numba.njit(cache = True)
def selectLkNm(dataSet,Ck,minSupport):
    dict_data = {}
    transactions = dataSet.shape[0]
    for items in Ck:
        count = 0
        while count < transactions:
            if items not in dict_data:
                dict_data[items] = 0
            for item in items:
                for e in dataSet[count, :]:
                    if item == e:
                        break
                else:
                    break
            else:
                dict_data[items] += 1
            count += 1
    Lk = {}
    for k, v in dict_data.items():
        if v >= minSupport:
            Lk[k] = v
    return Lk
    
def selectLk(dataSet, Ck, minSupport):
    tCk = numba.typed.List()
    for e in Ck:
        tCk.append(e)
    return selectLkNm(dataSet.values, tCk, minSupport)

dataset = pd.DataFrame([[100,160,100,160],[170,180,190,200],[100,160,190,200]])
C1 = set()
C1.add((100, 160))
C1.add((170, 180))
C1.add((190, 200))
Lk = selectLk(dataset, C1, 2)
print(Lk)

输出:

{(100, 160): 2, (190, 200): 2}

算法1(请参阅下面的其他算法)

我通过对数据进行排序改进了算法0(上述),如果Ck中有很多值或Ck中的每个元组都相当长,它将大大提高速度。

在线尝试!

import numba, numpy as np, pandas as pd

@numba.njit(cache = True)
def selectLkNm(dataSet,Ck,minSupport):
    assert dataSet.ndim == 2
    dataSet2 = np.empty_like(dataSet)
    for i in range(dataSet.shape[0]):
        dataSet2[i] = np.sort(dataSet[i])
    dataSet = dataSet2
    dict_data = {}
    transactions = dataSet.shape[0]
    for items in Ck:
        count = 0
        while count < transactions:
            if items not in dict_data:
                dict_data[items] = 0
            for item in items:
                ix = np.searchsorted(dataSet[count, :], item)
                if not (ix < dataSet.shape[1] and dataSet[count, ix] == item):
                    break
            else:
                dict_data[items] += 1
            count += 1
    Lk = {}
    for k, v in dict_data.items():
        if v >= minSupport:
            Lk[k] = v
    return Lk
    
def selectLk(dataSet, Ck, minSupport):
    tCk = numba.typed.List()
    for e in Ck:
        tCk.append(e)
    return selectLkNm(dataSet.values, tCk, minSupport)

dataset = pd.DataFrame([[100,160,100,160],[170,180,190,200],[100,160,190,200]])
C1 = set()
C1.add((100, 160))
C1.add((170, 180))
C1.add((190, 200))
Lk = selectLk(dataset, C1, 2)
print(Lk)

输出:

{(100, 160): 2, (190, 200): 2}

算法2(请参阅下面的其他算法)

如果不允许使用Numba,则建议您对算法做进一步的改进。我对您的数据集进行了预排序,以使您可以O(N)按时而不是按时间搜索每个项目O(Log(N))这要快得多。

我在您的代码中看到您使用了pandas数据框,这意味着您已经安装了pandas,如果您安装了pandas,那么您肯定拥有Numpy,所以我决定使用它。如果要处理熊猫数据框,则不能没有Numpy。

在线尝试!

import numpy as np, pandas as pd, collections

def selectLk(dataSet,Ck,minSupport):
    dataSet = np.sort(dataSet.values, axis = 1)
    dict_data = collections.defaultdict(int)
    transactions = dataSet.shape[0]
    for items in Ck:
        count = 0
        while count < transactions:
            for item in items:
                ix = np.searchsorted(dataSet[count, :], item)
                if not (ix < dataSet.shape[1] and dataSet[count, ix] == item):
                    break
            else:
                dict_data[items] += 1
            count += 1
    Lk = {k : v for k, v in dict_data.items() if v >= minSupport}
    return Lk
    
dataset = pd.DataFrame([[100,160,100,160],[170,180,190,200],[100,160,190,200]])
C1 = set()
C1.add((100, 160))
C1.add((170, 180))
C1.add((190, 200))
Lk = selectLk(dataset, C1, 2)
print(Lk)

输出:

{(100, 160): 2, (190, 200): 2}

算法3

我只是有一个想法,算法2的排序部分可能不是瓶颈,而循环中的事务可能是瓶颈。

因此,为了改善情况,我决定在2D searchsorted版本(没有内置2D版本,因此必须单独实现)中实施并使用更快的算法,大多数情况下,它没有任何长的纯Python循环用于Numpy函数。

请尝试一下该Algo 3是否会更快,如果不是排序瓶颈,而是内部while循环,那么它应该只会更快。

在线尝试!

import numpy as np, pandas as pd, collections

def selectLk(dataSet, Ck, minSupport):
    def searchsorted2d(a, bs):
        s = np.r_[0, (np.maximum(a.max(1) - a.min(1) + 1, bs.ravel().max(0)) + 1).cumsum()[:-1]]
        a_scaled = (a + s[:, None]).ravel()
        def sub(b):
            b_scaled = b + s
            return np.searchsorted(a_scaled, b_scaled) - np.arange(len(s)) * a.shape[1]
        return sub

    assert dataSet.values.ndim == 2, dataSet.values.ndim
    dataSet = np.sort(dataSet.values, axis = 1)
    dict_data = collections.defaultdict(int)
    transactions = dataSet.shape[0]
    Ck = np.array(list(Ck))
    assert Ck.ndim == 2, Ck.ndim
    ss = searchsorted2d(dataSet, Ck)
    for items in Ck:
        cnts = np.zeros((dataSet.shape[0],), dtype = np.int64)
        for item in items:
            bs = item.repeat(dataSet.shape[0])
            ixs = np.minimum(ss(bs), dataSet.shape[1] - 1)
            cnts[...] += (dataSet[(np.arange(dataSet.shape[0]), ixs)] == bs).astype(np.uint8)
        dict_data[tuple(items)] += int((cnts == len(items)).sum())
    return {k : v for k, v in dict_data.items() if v >= minSupport}
    
dataset = pd.DataFrame([[100,160,100,160],[170,180,190,200],[100,160,190,200]])
C1 = set()
C1.add((100, 160))
C1.add((170, 180))
C1.add((190, 200))
Lk = selectLk(dataset, C1, 2)
print(Lk)

输出:

{(100, 160): 2, (190, 200): 2}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Python:优化函数以找到给定候选项目集的大小为k的频繁项目集

来自分类Dev

生成Apriori算法的候选项目集

来自分类Dev

Apriori算法-频繁项目集生成

来自分类Dev

Python:为相对支持先验算法生成候选项集

来自分类Dev

R:如何找到项目集的提升?

来自分类Dev

在给定的频率下获取python词典中最频繁的项目

来自分类Dev

将项目分组为子集(功率集)

来自分类Dev

R优化代码:查找最常用的项目集/替代产品

来自分类Dev

计算给定数据帧中项目集的频率

来自分类Dev

计算给定数据帧中项目集的频率

来自分类Dev

连续循环遍历给定项目数的数据集

来自分类Dev

Spark MLlib FPGrowth正在运行,但不显示频繁的项目集

来自分类Dev

从项目集到数据框的python熊猫

来自分类Dev

从项目集到数据框的python熊猫

来自分类Dev

Gitlab为每个项目共享运行程序集并发

来自分类Dev

如何在R中使用apriori找到频繁项集?

来自分类Dev

从Redis集过滤/删除项目

来自分类Dev

熊猫groupby并设置项目集

来自分类Dev

无法加载项目程序集

来自分类Dev

从0/1数据框到项目集列表的python熊猫

来自分类Dev

从0/1数据框到项目集列表的python熊猫

来自分类Dev

如何通过以Web Api项目为目标从库项目创建迁移并将lib项目用作迁移程序集?

来自分类Dev

Python打字:给定值集

来自分类Dev

PostgreSQL集返回函数调用优化

来自分类Dev

使用ForEach的Linq筛选项目会导致大型数据集崩溃

来自分类Dev

部署MVC4项目时出错:无法找到文件或程序集

来自分类Dev

重命名项目→“无法解析此引用。无法找到程序集”

来自分类Dev

重命名项目→“无法解析此引用。无法找到程序集”

来自分类Dev

部署MVC4项目时出错:无法找到文件或程序集

Related 相关文章

  1. 1

    Python:优化函数以找到给定候选项目集的大小为k的频繁项目集

  2. 2

    生成Apriori算法的候选项目集

  3. 3

    Apriori算法-频繁项目集生成

  4. 4

    Python:为相对支持先验算法生成候选项集

  5. 5

    R:如何找到项目集的提升?

  6. 6

    在给定的频率下获取python词典中最频繁的项目

  7. 7

    将项目分组为子集(功率集)

  8. 8

    R优化代码:查找最常用的项目集/替代产品

  9. 9

    计算给定数据帧中项目集的频率

  10. 10

    计算给定数据帧中项目集的频率

  11. 11

    连续循环遍历给定项目数的数据集

  12. 12

    Spark MLlib FPGrowth正在运行,但不显示频繁的项目集

  13. 13

    从项目集到数据框的python熊猫

  14. 14

    从项目集到数据框的python熊猫

  15. 15

    Gitlab为每个项目共享运行程序集并发

  16. 16

    如何在R中使用apriori找到频繁项集?

  17. 17

    从Redis集过滤/删除项目

  18. 18

    熊猫groupby并设置项目集

  19. 19

    无法加载项目程序集

  20. 20

    从0/1数据框到项目集列表的python熊猫

  21. 21

    从0/1数据框到项目集列表的python熊猫

  22. 22

    如何通过以Web Api项目为目标从库项目创建迁移并将lib项目用作迁移程序集?

  23. 23

    Python打字:给定值集

  24. 24

    PostgreSQL集返回函数调用优化

  25. 25

    使用ForEach的Linq筛选项目会导致大型数据集崩溃

  26. 26

    部署MVC4项目时出错:无法找到文件或程序集

  27. 27

    重命名项目→“无法解析此引用。无法找到程序集”

  28. 28

    重命名项目→“无法解析此引用。无法找到程序集”

  29. 29

    部署MVC4项目时出错:无法找到文件或程序集

热门标签

归档