大数据--关联规则挖掘案例

环境:虚拟机hive+本地spark+python(pyspark)

数据:商品订单数据+商品种类数据

步骤:将数据上传到hdfs后,在python中完成hive表的创建,数据处理,关联规则挖掘,数据可视化

实现功能:对商品订单中的信息进行挖掘,得到商品组合之间的关联关系(本文只对order进行了处理,没有涉及到type)


一.数据准备

将GoodsOrder.csv和GoodsTypes.csv文件上传到hdfs创建的数据文件夹

hdfs dfs -mkdir /hive_data/homework/data/order            
hdfs dfs -mkdir /hive_data/homework/data/type
hdfs dfs -put /export/data/hive_data/GoodsOrder.csv /hive_data/homework/data/order
hdfs dfs -put /export/data/hive_data/GoodsTypes.csv /hive_data/homework/data/type

image

image


二.pyspark创建hive表

前提是已经完成了本地spark连接虚拟机hive的操作,见前文

而且这里有个小坑,spark直接删除hive表的话,只会删除表的元数据,不会删除表的数据文件,如果直接使用spark.sql(“drop..”)的话,在后面重新创建同名hive表的话,就会一直提示某某文件夹已存在,所以我查了一下可以直接去hive中删除,或者在spark中使用以下命令删除

spark.sql("ALTER TABLE homework.type SET TBLPROPERTIES ('external.table.purge'='true')")
spark.sql("drop table homework.type")

创建hive表--order和type

def createTable():
    spark = SparkSession \
        .builder \
        .appName("Python Spark SQL Hive integration example") \
        .enableHiveSupport() \
        .getOrCreate()
    spark.sql("show databases").show()
    # 创建数据库不指定location,则默认创建在hive.metastore.warehouse.dir设置的文件夹中,这个在hive-site.xml中设置
    spark.sql("create database IF NOT EXISTS homework")
    '''
    数据文件通过hdfs命令,hdfs dfs -put /export/data/hive_data/download.csv /hive_data/homework/data
    由虚拟机上传到hdfs的/hive_data/homework/data文件夹下,
    访问的前缀在hadoop的core-site.xml文件中设置,值为hdfs://master,master对应为node01和node02,
    具体的选择由Zookeeper完成,使用status命令查看哪一台虚拟机被选举为leader,当前是node2为leader,
    因此通过下面的地址就可以访问到hdfs文件系统(端口号为9000)
    注意建表语句的中表的数据格式要与导入的数据一致
    而且要注意加上分隔符的设置,否则导入都为null
    '''
    spark.sql("use homework")
    spark.sql("CREATE EXTERNAL TABLE IF NOT EXISTS homework.order(id INT,good STRING) "
              "ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LOCATION "
              "'hdfs://192.168.121.131:9000/hive_data/homework/data/order'")
    spark.sql("select * from homework.order").show()

    spark.sql("CREATE EXTERNAL TABLE IF NOT EXISTS homework.type(good STRING,type STRING) "
              "ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LOCATION "
              "'hdfs://192.168.121.131:9000/hive_data/homework/data/type'")
    spark.sql("show tables").show()
    spark.sql("select * from homework.type").show()

PS:如果发现select结果是乱码,那么很大的可能是因为csv文件没有保存为utf-8,修改格式后删除hdfs上的文件并重新上传修改后的文件,删除hive表后重新导入,即可解决乱码

image

image

image

成功创建

image


三.pyspark数据处理

使用的关联规则算法是Apriori,这里通过mlxtend库实现,因为它提供了支持度,更加详细,因此就需要先把order表中的数据转换成需要的列表格式。

# 按照id进行聚合,Goods_list存储每个订单中的商品
order_list = order.groupBy("id").agg(F.collect_list("good").alias("Goods_list"))
order_list.show()

# 将Goods_list列的内容取出存入good_list列表
Goods_list = order_list.select("Goods_list").collect()
good_list = []
for i in Goods_list:
     good_list.append(i["Goods_list"])

image


四.关联规则挖掘

这里研究订单的商品之间的关联规则,也就是说用户在购买了某一个商品的同时,购买另一个商品的概率。通过设置支持度和置信度得到合适的结果、支持度大于一表示正相关,小于一表示负相关。

'''
2.关联规则挖掘
'''
TE = TransactionEncoder()  # 构造转换模型
data = TE.fit_transform(good_list)  # 将原始数据转换为bool型
df = pd.DataFrame(data, columns=TE.columns_)  # 使用DataFrame存储bool数据

item_set = apriori(df, min_support=0.05, use_colnames=True)  # 设置最小支持度参数
print(item_set)

# 提示:Empty DataFrame----可能是没有超过该阈值的频繁项目,因此item_set为空,rules调用出错
rules = association_rules(item_set, min_threshold=0.2)  # 设置最小置信度,根据最小置信度在频繁项集中产生强关联规则
pd.set_option('expand_frame_repr', False)
print(rules)

data_a = []  # 柱状图的横坐标,记录关联关系
data_b = []  # 关联的第一个柱,表示置信度
data_c = []  # 关联的第二个柱,表示提升度
for i, j in rules.iterrows():  # 'for index, row in dataset.iterrows():'index是行索引值,row是对应的行内容
    X = j['antecedents']
    Y = j['consequents']
    Z = j['confidence']
    U = j['lift']
    x = ','.join([item for item in X])
    y = ','.join([item for item in Y])
    xy = x + "" + y
    print(xy + " 置信度=" + str(Z) + " 提升度=" + str(U))
    data_a.append(xy)
    data_b.append(Z)
    data_c.append(U)

image


五.关联情况可视化

# 绘制柱状图
plt.rcParams['font.sans-serif'] = ["SimHei"]  # 不支持中文,所以进行临时设置
size = len(data_a)
place = np.arange(size)  # 根据数据个数生成柱子的中点位置,也是放置横轴数据的位置
# 1.设置横轴
plt.figure(figsize=(15, 12), dpi=200)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.set_xticks(place)  # x轴的位置
ax.set_xticklabels(data_a, rotation=0, fontsize=10)  # x轴
ax.set_xlabel('关联规则')  # x轴名称
# 2.设置两个柱
total_width, n = 0.8, 2  # n表示柱子的种类数
width = total_width / n  # 得到每个柱子的宽度
place = place - (total_width - width) / 2  # 得到柱子的每个起始位置
plt.bar(place, data_b, width=width, label='置信度')  # 柱1
plt.bar(place + width, data_c, width=width, label='提升度')  # 柱2
# 3.设置数字在柱上显示
for i in range(size):
    plt.text(place[i], data_b[i] + 0.01, '%.3f' % data_b[i], ha='center', va='bottom',
             fontsize=10)  # 设置在柱1的顶部显示数字--保留三位小数,在柱子上方0.01处居中显示
    plt.text(place[i] + width, data_c[i] + 0.01, '%.3f' % data_c[i], ha='center', va='bottom',
             fontsize=10)  # 设置在柱2的顶部显示数字
plt.legend()
plt.show()
image


六.完整代码以及数据文件

https://files.cnblogs.com/files/blogs/745215/%E5%85%B3%E8%81%94%E8%A7%84%E5%88%99%E6%8C%96%E6%8E%98.zip?t=1671788956


七.总结

通过关联规则挖掘,可以对商品的摆放提供参考,例如酸奶和全脂牛奶可以一起摆放,同时也可以结合商品种类,对于不同种类的商品摆放提供参考。

posted @ 2022-12-23 17:52  脑袋凉凉  阅读(285)  评论(0编辑  收藏  举报