超市购物小票关联关系

需求:对超市购物小票信息进行分析,得到商品的关联关系,从而向用户进行推荐,提升营业额。

数据:BreadBasket_DMS.csv

所用算法:apriori

完整代码:

import pandas as pd
import time

data = pd.read_csv('./BreadBasket_DMS.csv')

# 统一小写(Item列的数据全部小写)
data['Item'] = data['Item'].str.lower()
# 去掉none项(通过拿到具体的行索引来删除掉数据)
data = data.drop(data[data.Item == 'none'].index)

# 采用efficient_apriori工具包
def rule1():
    from efficient_apriori import apriori
    start = time.time()
    # 得到一维数组orders_series(是一个类似于一维数组的series对象),并且将Transaction作为index, value为Item取值
    # 然后就出现了同一个索引对应多个值
    # orders_series类型是pandas.core.series.Series
    orders_series = data.set_index('Transaction')['Item']

    # 将数据集转换成apriori模型需要的形式
    # 将数据集进行格式转换(创建列表,等下里面放集合(集合里面数据不重复))
    transactions = []

    temp_index = 0
    for i, v in orders_series.items():
        if i != temp_index:
            # set() 函数创建一个无序不重复元素集(这样可以保证订单里面的物品不重复,即我只关心你买了什么,不关心你相同物品买了多少)
            temp_set = set()
            temp_index = i
            temp_set.add(v)
            transactions.append(temp_set)
        else:
            # 因为是set集合,所以重复的物品不会添加进来
            temp_set.add(v)

    # 挖掘频繁项集和频繁规则(同时定义阈值min_support和min_confidence)
    # transactions包含了所有订单信息,但是同一个订单中相同物品的数量设置为1
    itemsets, rules = apriori(transactions, min_support=0.02, min_confidence=0.5)
    print('频繁项集:', itemsets)
    print('关联规则:', rules)
    end = time.time()
    print("用时:", end - start)

# 使>=1的数值全部变为1,目的是只考虑你买了啥,不考虑同一件商品你买了多少
def encode_units(x):
    if x <= 0:
        return 0
    if x >= 1:
        return 1

# 这里用到的模型是机器学习扩展包
# 采用mlxtend.frequent_patterns工具包
def rule2():
    from mlxtend.frequent_patterns import apriori
    from mlxtend.frequent_patterns import association_rules
    pd.options.display.max_columns = 100
    start = time.time()
    # stack()即“堆叠”,作用是将列旋转到行(默认操作最里层数据)
    # unstack()即stack()的反操作,将行旋转到列(默认操作最里层数据)
    # reset_index()把索引重置(从0开始)  把原来的索引删掉
    # .fillna(0),填充缺失数据(这里用常数0填充NaN)
    # set_index('Transaction') 索引还是用Transaction
    # 按照['Transaction', 'Item']进行分组(同一个订单、相同的商品分到一组),然后对['Item']列进行后续数据处理
    hot_encoded_df = data.groupby(['Transaction', 'Item'])['Item'].count().unstack().reset_index().fillna(
        0).set_index('Transaction')

    # 先计算频繁项集、再计算关联规则
    # 将自定义函数encode_units作用于DataFrame的所有元素(使>=1的数值全部变为1,目的是只考虑你买了啥,不考虑同一件商品你买了多少)
    hot_encoded_df = hot_encoded_df.applymap(encode_units)
    # 设置数据集、最小支持度、是否使用列名(因为是热编码数据,所以列名就是商品名)
    # 独热编码(one-hot编码)
    frequent_itemsets = apriori(hot_encoded_df, min_support=0.02, use_colnames=True)
    # metric(判定标准,这里设置判定标准为lift提升度),min_threshold(metric参数的阈值)
    # 因为下面设置lift>=1了,所以这里的0.5就没有作用了(其实lift>1才有意义)
    rules = association_rules(frequent_itemsets, metric="lift", min_threshold=0.5)
    print("频繁项集:\n", frequent_itemsets)
    # 进一步筛选出提升度lift>=1和置信度>=0.5的关联规则
    print("关联规则:\n", rules[(rules['lift'] >= 1) & (rules['confidence'] >= 0.5)])

    # 结束时间
    end = time.time()
    print("用时:", end - start)

# 两个规则分别执行
# rule1()
print('-' * 100)
rule2()

 

频繁项集:                                                              关联规则:

           

如有疏漏,望批评指正。 

 

posted @ 2020-10-12 19:11  mingke07  阅读(304)  评论(0)    收藏  举报