大数据--关联规则挖掘案例
环境:虚拟机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
二.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表后重新导入,即可解决乱码
成功创建
三.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"])
四.关联规则挖掘
这里研究订单的商品之间的关联规则,也就是说用户在购买了某一个商品的同时,购买另一个商品的概率。通过设置支持度和置信度得到合适的结果、支持度大于一表示正相关,小于一表示负相关。
''' 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)
五.关联情况可视化
# 绘制柱状图 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()
六.完整代码以及数据文件
七.总结
通过关联规则挖掘,可以对商品的摆放提供参考,例如酸奶和全脂牛奶可以一起摆放,同时也可以结合商品种类,对于不同种类的商品摆放提供参考。