【数据分析】数据分析达人赛2:产品关联分析

目录

赛题背景

赛题数据

赛题任务

1、导入数据 

 2、数据探索

3、采用efficient_apriori算法挖掘频繁项集和频繁规则

 4、 绘制频繁项集的条形图

赛题背景

赛题以购物篮分析为背景,要求选手对品牌的历史订单数据,挖掘频繁项集与关联规则。通过这道赛题,鼓励学习者利用订单数据,为企业提供销售策略,产品关联组合,为企业提升销量的同时,也为消费者提供更适合的商品推荐。

赛题数据

数据源:order.csv,product.csv,customer.csv,date.csv ,分别为订单表,产品表,客户表,日期表

赛题任务

现在需要你使用关联分析(比如Apriori算法) 挖掘订单中的频繁项集及关联规则
说明:
1)频繁项集、关联规则的计算会用到支持度、置信度、提升度等指标,
2)频繁项集:即大于最小支持度的商品或商品组合
3)关联规则:在频繁项集中,满足最小置信度,或最小提升度的推荐规则
(这里最小支持度、最小置信度或最小提升度,选手可以根据数据集的特点自己设定)

1、导入数据 

!pip install efficient_apriori --user
'''在天池实验室做的,下载用!pip install efficient_apriori --user,如果在本地直接pip install efficient_apriori'''

import pandas as pd
import time
import matplotlib.pyplot as plt
from matplotlib import font_manager

#设置正常显示字体
font_manager.fontManager.addfont('./SimHei.ttf')
plt.rcParams['font.sans-serif'] = ['SimHei'] # 设置汉字字体,优先使用黑体
plt.rcParams['font.size'] = 12  # 设置字体大小
plt.rcParams['axes.unicode_minus'] = False   # 设置正常显示负号

df_order = pd.read_csv('./order.csv',encoding='gbk')
df_product = pd.read_csv('./product.csv',encoding='gbk')
df_customer = pd.read_csv('./customer.csv',encoding='gbk')
daf_date = pd.read_csv('./date.csv',encoding='gbk')
df_order.head()

【数据分析】数据分析达人赛2:产品关联分析_第1张图片

 【数据分析】数据分析达人赛2:产品关联分析_第2张图片

 2、数据探索


df_order['订单日期']=pd.to_datetime(df_order['订单日期'])    #将原表内订单日期转化为pandas日期格式
print(df_order.head())

print(df_order.info())

RangeIndex: 60398 entries, 0 to 60397
Data columns (total 17 columns):
 #   Column  Non-Null Count  Dtype         
---  ------  --------------  -----         
 0   订单日期    60398 non-null  datetime64[ns]
 1   年份      60398 non-null  int64         
 2   订单数量    60398 non-null  int64         
 3   产品ID    60398 non-null  int64         
 4   客户ID    60398 non-null  object        
 5   交易类型    60398 non-null  int64         
 6   销售区域ID  60398 non-null  int64         
 7   销售大区    60398 non-null  object        
 8   国家      60398 non-null  object        
 9   区域      60398 non-null  object        
 10  产品类别    60398 non-null  object        
 11  产品型号名称  60398 non-null  object        
 12  产品名称    60398 non-null  object        
 13  产品成本    60398 non-null  float64       
 14  利润      60398 non-null  float64       
 15  单价      60398 non-null  float64       
 16  销售金额    60398 non-null  float64       
dtypes: datetime64[ns](1), float64(4), int64(5), object(7)
memory usage: 7.8+ MB

#探索重复客户ID数量
print(df_order['客户ID'].value_counts())  

13206BA    68
13321BA    67
13298BA    65
13283BA    63
13308BA    62
           ..
31444BA     1
13428BA     1
18295BA     1
30732BA     1
30480BA     1
Name: 客户ID, Length: 18484, dtype: int64
#探索重复产品名称数量                
print(df_order['产品名称'].value_counts())
棒球手套      17332
硬式棒球       8068
球棒与球棒袋     7981
头盔         6440
软式棒球       4970
棒球服        3332
帽子         2190
垒球         2167
三角网架       2121
击打手套       1430
皮带         1019
垒垫          908
装备包         733
袜子          568
捕手护具        562
球网          328
打击T座        249
Name: 产品名称, dtype: int64
# 探索是否存在同一订单日期且客户ID也相同的情况,若存在则合并该天内该客户购买的所有产品                 
df_order=df_order.groupby(['客户ID','订单日期'])['产品名称'].unique()  

print(df_order)


客户ID     订单日期      
13021BA  2013-07-22                           [软式棒球]
         2015-07-22                     [三角网架, 软式棒球]
         2015-11-04              [垒球, 棒球服, 头盔, 棒球手套]
13022BA  2013-07-18                           [软式棒球]
         2015-07-20    [球棒与球棒袋, 软式棒球, 三角网架, 帽子, 棒球服]
Name: 产品名称, dtype: object
#将所有交易追加到同一个交易列表中,每一个交易是同一个客户同一天购买的所有产品的集合
transactions=[]    
for value in df_order:
    transactions.append(list(value))
# print(transactions)

3、采用efficient_apriori算法挖掘频繁项集和频繁规则

from efficient_apriori import apriori
# 单个transaction定义为同一天内同一客户ID购买的所有产品
start = time.time()
itemsets, rules = apriori(transactions, min_support=0.03, min_confidence=0.05)
print('频繁项集:', itemsets)
print('关联规则:', rules)
end = time.time()
print("用时:", end - start)
频繁项集: {1: {('软式棒球',): 4970, ('三角网架',): 2121, ('垒球',): 2167, ('棒球服',): 3332, ('头盔',): 6439, ('棒球手套',): 9844, ('球棒与球棒袋',): 4767, ('帽子',): 2190, ('硬式棒球',): 8068, ('击打手套',): 1430, ('皮带',): 1019, ('垒垫',): 908}, 2: {('三角网架', '软式棒球'): 898, ('垒球', '头盔'): 893, ('头盔', '棒球手套'): 2769, ('头盔', '球棒与球棒袋'): 1203, ('头盔', '硬式棒球'): 1353, ('头盔', '软式棒球'): 934, ('棒球手套', '硬式棒球'): 909, ('棒球手套', '软式棒球'): 910, ('球棒与球棒袋', '硬式棒球'): 986, ('球棒与球棒袋', '软式棒球'): 948}}
关联规则: [{软式棒球} -> {三角网架}, {三角网架} -> {软式棒球}, {头盔} -> {垒球}, {垒球} -> {头盔}, {棒球手套} -> {头盔}, {头盔} -> {棒球手套}, {球棒与球棒袋} -> {头盔}, {头盔} -> {球棒与球棒袋}, {硬式棒球} -> {头盔}, {头盔} -> {硬式棒球}, {软式棒球} -> {头盔}, {头盔} -> {软式棒球}, {硬式棒球} -> {棒球手套}, {棒球手套} -> {硬式棒球}, {软式棒球} -> {棒球手套}, {棒球手套} -> {软式棒球}, {硬式棒球} -> {球棒与球棒袋}, {球棒与球棒袋} -> {硬式棒球}, {软式棒球} -> {球棒与球棒袋}, {球棒与球棒袋} -> {软式棒球}]
用时: 0.016688108444213867

 4、 绘制频繁项集的条形图

  • 横坐标为apriori算法输出的频繁项集,纵坐标为相应的频数
itemsets_item=[]    #获取横坐标,频繁项集产品名称的列表
itemsets_count=[]    #获取纵坐标,频繁项集产品名称出现的频数的列表

for key in itemsets.keys():
    df1=itemsets[key]#df1 = 每个索引对应的频繁项集
    '''key = 1时,df1 = {('软式棒球',): 4970, ('三角网架',): 2121, ('垒球',): 2167, ('棒球服',): 3332, ('头盔',): 6439, ('棒球手套',): 9844,
    ('球棒与球棒袋',): 4767, ('帽子',): 2190, ('硬式棒球',): 8068, ('击打手套',): 1430, ('皮带',): 1019, ('垒垫',): 908}'''
    for key in df1:
        itemsets_item.append(key)#频繁项集产品名称
        itemsets_count.append(df1[key])#频繁项集产品名称出现的频数
        
itemsets_itemstr=[]    #将横坐标转化为字符串形式

for i in itemsets_item:
    itemsets_itemstr.append(','.join(list(i)))
print(itemsets_itemstr)
print(itemsets_count)
['软式棒球', '三角网架', '垒球', '棒球服', '头盔', '棒球手套', '球棒与球棒袋', '帽子', '硬式棒球', '击打手套', '皮带', '垒垫', '三角网架,软式棒球', '垒球,头盔', '头盔,棒球手套', '头盔,球棒与球棒袋', '头盔,硬式棒球', '头盔,软式棒球', '棒球手套,硬式棒球', '棒球手套,软式棒球', '球棒与球棒袋,硬式棒球', '球棒与球棒袋,软式棒球']
[4970, 2121, 2167, 3332, 6439, 9844, 4767, 2190, 8068, 1430, 1019, 908, 898, 893, 2769, 1203, 1353, 934, 909, 910, 986, 948]
plt.bar(itemsets_itemstr,itemsets_count)
plt.xlabel('频繁项集_产品名称',fontsize=14)                          #设置X轴标签
plt.ylabel('频繁项集_出现频数',fontsize=14)                          #设置Y轴标签
plt.title('频繁项集频数分布柱状图',fontsize=18)                       #为柱状图添加标题
plt.xticks(rotation=90,fontsize=10)                               #设置X轴内容竖排显示
for a, b in zip(itemsets_itemstr, itemsets_count):                  #设置数据标签可见
    plt.text(a, b + 0.005, str(b), ha='center', va='bottom', fontsize=8)
plt.show()

频繁模式挖掘及Python实现

你可能感兴趣的:(数据分析,数据挖掘,python)