ToB企服应用市场:ToB评测及商务社交产业平台
标题:
PySpark关联规则及聚类模子简明教程
[打印本页]
作者:
老婆出轨
时间:
2024-8-30 02:24
标题:
PySpark关联规则及聚类模子简明教程
一、PySpark关联规则模子
关联规则分析为的就是发现商品与商品之间的关联。通过盘算商品之间的支持度、置信度与提拔度,分析哪些商品有正向关系,顾客乐意同时购买它们。
此处利用了pyspark自带的FPGrowth算法。它和APRIORI算法一样都是盘算两两商品之间支持度置信度与提拔度的算法,虽然算法流程差别,但是盘算结果是一样的。
(1) Antecedent(前件)
界说:在关联规则中,if部分称为条件(Antecedent),表现某些物品的组合。它是规则中用于推断或猜测的条件部分。
示例:在规则“购买牛奶 → 购买面包”中,“购买牛奶”是前件。
(2) Consequent(后件)
界说:在关联规则中,then部分称为结果(Consequent),表现其他物品的组合。它是在前件满足时大概发生的结果。
示例:在规则“购买牛奶 → 购买面包”中,“购买面包”是后件。
(3) Confidence(置信度)
界说:置信度是关联规则的可信水平,表现在包含前件的事件中,同时也包含后件的事件所占的比例。
示例:如果购买牛奶的顾客中有70%也购买了面包,则规则“购买牛奶 → 购买面包”的置信度为70%。
(4) Lift(提拔度)
界说:提拔度表现在包含前件的事件中同时包含后件的比例,与仅包含后件的事件的比例之间的比值。它反映了前件对后件出现的提拔作用。
示例:如果购买牛奶的顾客中购买面包的比例是70%,而所有顾客中购买面包的比例是50%,则规则“购买牛奶 → 购买面包”的提拔度为1.4(70% / 50%)。
(5) Support(支持度)
界说:支持度是项集在数据会合出现的频率或概率,表现同时包含前件和后件的事件占所有事件的比例。
示例:如果100个购物交易中,有30个交易同时包含了牛奶和面包,则规则“购买牛奶 → 购买面包”的支持度为30%。
二、关联规则模子应用
1. 数据集介绍
数据集:简单关联规则分析.txt,为5张购物小票,每张购物小票上面是购买的商品名称,如下图所示。
数据集的样本数很少,这里仅为演示PySpark关联规则的简单教程,方便读者理解。
2.数据导入及预处理惩罚
配置Pyspark应用程序,导入数据集:简单关联规则分析.txt。
PySpark关联规则模子仅需要一列数据,而且需将每行数据以逗号分隔,放在列表里。处理惩罚 后的数据集如下:
代码如下:
from pyspark import SparkConf
from pyspark.ml.feature import StringIndexer
from pyspark.sql import SparkSession
from pyspark.sql.functions import *
from pyspark.ml.recommendation import ALS
from pyspark.ml.evaluation import RegressionEvaluator
from pyspark.ml.fpm import *
import matplotlib
# 设置一个支持GUI的后端,用于在IDEA绘图
matplotlib.use('TkAgg') # 或者 'Qt5Agg', 'GTK3Agg' 等,用于在IDEA绘图
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 配置PySpark应用程序
conf = SparkConf().setAppName("简单关联规则分析").setMaster('spark://192.168.126.10:7077')
sc = SparkContext.getOrCreate(conf)
spark = SparkSession(sc)
# ------------1.加载数据--------------------
filename = "关联规则分析.txt"
data = spark.read.text('hdfs://192.168.126.10:9000/data/' + filename)
data.show()
# --------2.数据处理---------
transactions = data.select(split('value', ',').alias('items')) # 将每行数据按逗号分割,并将结果数组作为新的列items
transactions.show()
复制代码
3.关联规则分析
创建FPGrowth模子
。
训练模子
。设最小支持度minSupport=0.5, 最小置信度minConfidence=0.6
获取频仍项集
。频仍项集是指那些在数据会合频仍出现的项的集合。在购物篮分析中,一个频仍项集大概是一组经常被顾客一起购买的商品。频仍项集的识别是关联规则挖掘的第一步。通常利用支持度(Support)来量化一个项集的频仍水平,即数据会合包含该项集的交易数占总交易数的比例。
上图可知,“面包”在数据会合出现了4次,“面包”和“尿不湿”同时在数据会合出现3次。
获取关联规则
。关联规则是形貌数据会合项之间关系的规则。它们通常以“如果…那么…”的形式出现,例如,“如果顾客购买了牛奶,那么他们也大概购买面包”。关联规则由两个主要部分组成:前项(Antecedent)和后项(Consequent),分别对应于“如果…”和“那么…”部分。
由上图可知,第一条关联规则为:
啤酒–>尿不湿
,置信度confidence=1.0,提拔度lift=1.25,支持度support=0.6。这表明:
置信度(Confidence) = 1.0
:这意味着在所有包含“啤酒”的交易中,都同时也包含了“尿不湿”。换句话说,当顾客购买了啤酒时,他们100%的几率也会购买尿不湿。这是一个非常高的置信度,表明啤酒和尿不湿之间的购买举动险些是同时发生的。
提拔度(Lift) = 1.25
:提拔度大于1表明“啤酒”和“尿不湿”之间存在正相关性,即它们不是独立出现的。具体来说,当“啤酒”出现时,“尿不湿”出现的频率是它在整个数据会合出现频率的1.25倍。这意味着,啤酒的购买增长了尿不湿被购买的大概性。
支持度(Support) = 0.6
:支持度表现同时包含“啤酒”和“尿不湿”的交易占所有交易的比例是60%。这是一个相对较高的支持度,表明这两种商品经常被一起购买。
综合这些指标,我们可以得出以下结论:
强关联性
:由于置信度和提拔度都很高,这条规则表明啤酒和尿不湿之间存在很强的关联性。商家可以利用这种关联性来优化商品结构、促销策略或保举系统,以增长贩卖额。
高购买频率
:支持度较高表明这两种商品经常被顾客一起购买。这大概反映了某种生存风俗或购物模式,商家可以进一步分析这种模式的成因,以便更好地满足顾客需求。
营销策略
:基于这条规则,商家可以考虑将啤酒和尿不湿放在相邻的货架上,大概提供捆绑贩卖、满减优惠等促销活动,以吸引顾客购买这两种商品。
代码如下:
# ---------3.关联规则挖掘---------
fp = FPGrowth(minSupport=0.5, minConfidence=0.6, itemsCol='items') # 创建FPGrowth模型
fpModel = fp.fit(transactions) # 训练模型
fpModel.freqItemsets.show() # 获取频繁项集
associations_rules = fpModel.associationRules.sort('lift', ascending=False) # 获取 关联规则
associations_rules.show()
复制代码
4. 关联规则数据处理惩罚,为可视化做准备
只有提拔度大于1,关联规则才有用,因此提取提拔度大于1的关联规则,并转换为Pandas DataFrame。
关联规则里面的前件antecedent和后件consequent的元素都是以集合形式存在,需通过遍历或用apply()函数将每个元素提取出来,组成:“啤酒–>尿不湿” 的字符串形式,用于绘制柱形图。
# ----4.关联规则处理,为可视化做准备-----
rules_pd = associations_rules.filter(col('lift') > 1).toPandas()
print(rules_pd)
ant_cons = [] # 前件antecedent-->后件consequent
confidence = [] # 置信度
lift = [] # 提升度
# 使用apply()函数对数据批量处理
def process_row(row):
ant = row['antecedent']
cons = row['consequent']
conf = row['confidence']
li = row['lift']
ant_join = ','.join([item for item in ant])
cons_join = ','.join([item for item in cons])
a_c = ant_join + '→' + cons_join
print(a_c + ",置信度:" + str(conf) + ",提升度:" + str(li))
ant_cons.append(a_c)
confidence.append(conf)
lift.append(li)
rules_pd.apply(process_row, axis=1) # 处理每一行
print(ant_cons)
print(confidence)
print(lift)
复制代码
5.关联规则可视化
将置信度和提拔度绘制成柱形图。
代码如下:
# -----5.关联规则可视化--------
size = len(ant_cons)
place = np.arange(size) # 根据数据个数生成柱子的中点位置:0,1,2,3
plt.bar(place, confidence, width=0.4, label='置信度') # 第1根柱子的中心位置为0,宽度0.4,第2根中心位置为1
plt.bar(place + 0.4, lift, width=0.4, label='提升度') # 第2根柱子的中心位置为0+0.4,宽度为0.4
for i in place:
plt.text(i, confidence[i] + 0.01, '%.2f' % confidence[i]) # 置信度 柱子的顶部数字
plt.text(i + 0.4, lift[i] + 0.01, '%.2f' % lift[i]) # 提升度 柱子的顶部数字,数字保留2位小数,离顶部柱子距离0.01
plt.xticks(place+0.2, ant_cons) # 替换x轴刻度标签
plt.legend() # 显示图例
plt.show()
复制代码
三、聚类模子应用:客户细分
1. PySpark聚类模子介绍
在PySpark中,有LDA(Latent Dirichlet Allocation,潜在狄利克雷分配)、BisectingKMeans和KMeans三种差别的聚类或主题模子算法。
(1)LDA
LDA
:是一种文档主题生成模子,也是一种无监视学习算法。它主要用于发现文档集合中的潜在主题,并将每个文档表现为这些主题的混淆体。LDA通过找到词、文档与主题三者之间的统计学关系举行推断,从而实现对文档的聚类或主题分析。
应用场景
:LDA特别实用于文本数据,如文章、书籍、网页等,可以帮助用户理解文档集合中的主题结构。
LDA实现
:在PySpark中,LDA模子通过pyspark.ml.clustering.LDA类实现。用户需要指定特性列(featuresCol)、迭代次数(maxIter)、随机种子(seed)、主题数(k)等参数来训练模子。训练完成后,可以利用模子的describeTopics方法来查看主题分布,大概利用logLikelihood和logPerplexity方法来评估模子性能。
(2)BisectingKMeans
BisectingKMeans
:是一种基于二分策略的K-means聚类算法,是一种条理型聚类算法。与传统的K-means算法差别,BisectingKMeans从包含所有点的单个簇开始,通过迭代地将簇一分为二,直到达到指定的簇数量或满足其他制止条件。
应用场景
:BisectingKMeans实用于需要快速收敛到指定簇数量的场景,特别是当数据集较大时,它可以比传统的K-means算法更快地找到解。
BisectingKMeans实现
:在PySpark中,BisectingKMeans通过pyspark.ml.clustering.BisectingKMeans类实现。用户需要指定特性列(featuresCol)、猜测列(predictionCol)、最大迭代次数(maxIter)、随机种子(seed)、叶簇数(k)等参数来训练模子。训练完成后,可以利用模子的clusterCenters方法来查看聚类中心,大概利用computeCost方法来盘算输入点与其对应的聚类中心之间的距离平方和。
(3)KMeans
KMeans
:是一种广泛利用的聚类算法,它将数据点分别到具有相似特性的K个簇中。KMeans通过迭代地更新簇中心和重新分配数据点到近来的簇中心来实现聚类。
应用场景
:KMeans实用于各种范例的数据集,特别是当数据集具有明显的簇结构时。它可以帮助用户发现数据中的潜在群组或模式。
KMeans实现
:在PySpark中,KMeans通过pyspark.ml.clustering.KMeans类实现。用户需要指定特性列(featuresCol)、聚类数(k)、随机种子(seed)、最大迭代次数(maxIter)等参数来训练模子。训练完成后,可以利用模子的transform方法来对新数据举行聚类猜测,大概利用clusterCenters方法来查看聚类中心。
2.数据集介绍
聚类目标:将具有相似特性(如年事、性别、年收入和消耗风俗)的客户分组,了解差别客户群体的特性和需求,为后续的市场细分和个性化营销提供基础。数据集CustomersCluster.csv字段如下:
CustomerID
: 每个客户的唯一ID。
Genre
:用户的性别。
Age
:用户当前的年事。
Income
: 用户的年收入 (千美元)。
Spending
:(0-1),用户消耗风俗(分数越高表现消耗越多,反之亦然)。
数据集的部分数据如下:
3.初始化Spark环境
创建SparkSession对象,用于访问SparkContext和其他Spark功能。Spark集群主节点IP为192.168.126.10。代码如下:
from pyspark import SparkConf
from pyspark.ml.feature import StringIndexer, VectorAssembler, OneHotEncoder, MinMaxScaler
from pyspark.sql import SparkSession, Row
from pyspark.sql.functions import *
from pyspark.ml.classification import *
from pyspark.ml.evaluation import *
from pyspark.ml import Pipeline, tuning
from pyspark.ml.linalg import Vectors
from pyspark.ml.regression import *
from pyspark.ml.clustering import *
import pandas as pd
import matplotlib.pyplot as plt
from pyspark.ml.stat import Correlation
import matplotlib
# 设置一个支持GUI的后端,用于在IDEA绘图
matplotlib.use('TkAgg') # 或者 'Qt5Agg', 'GTK3Agg' 等,用于在IDEA绘图
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体为SimHei显示中文
plt.rcParams['axes.unicode_minus'] = False # 解决保存图像时负号'-'显示为方块的问题
conf = SparkConf().setAppName("聚类_客户").setMaster('spark://192.168.126.10:7077')
sc = SparkContext.getOrCreate(conf)
spark = SparkSession(sc)
复制代码
4. 数据准备
数据集CustomersCluster.csv存放在HDFS系统的/data/目次下,Spark从HDFS系统中读取数据,代码如下。
# -----------------1.数据获取-------------------
filename = "CustomersCluster.csv"
customers = spark.read.csv('hdfs://192.168.126.10:9000/data/' + filename, header=True,
inferSchema=True) # 训练集包含标题行,inferSchema=True自动推断数据类型
customers.show(5)
customers.describe().show() # 查看数据集的基本数据信息
customers.printSchema() # 输出数据集的结构
print(f"训练数据集总的记录数:{customers.count()}, 总列数:{len(customers.columns)}")
复制代码
程序运行结果如下:
5. 数据探索
PySpark主要计划用于大数据的分布式处理惩罚,而不是数据可视化。然而,可以通过将PySpark DataFrame中的数据转换为Pandas DataFrame(如果数据量不是极端庞大), 然后利用Matplotlib或Seaborn等库来绘制图形。对于大数据集,将整个数据集转换为Pandas DataFrame大概会导致内存不足的问题。因此,请确保数据集大小适当在单个节点的内存中处理惩罚。
起首分组统计男女的人数,并绘制柱形图。然后再将PySpark DataFrame转换为Pandas DataFrame,分别绘制收入、年事、消耗的分布图,以及收入-消耗的散点图。代码如下:
gender_counts = customers.groupBy('Gender').agg(count('*').alias('人数')).toPandas()
print(gender_counts)
gender_counts.plot(x='Gender', y='人数', kind='bar')
plt.xticks(rotation=45)
plt.show()
customers_df = customers.toPandas() # 将数据转换为Pandas DataFrame(这里仅为示例,对于大数据集不推荐)
print(customers_df)
customers_df['Income'].plot(kind='kde') # 收入的核密度图
plt.title("收入分布图")
plt.show()
customers_df['Age'].hist(bins=10, alpha=0.7, color='skyblue') # bins参数控制直方图的柱数
plt.title("年龄分布图")
plt.show()
customers_df['Spending'].plot(kind='kde')
plt.title("消费分布图")
plt.show()
customers_df.plot(x='Income', y='Spending', kind='scatter')
plt.title("收入-消费 散点图")
plt.xlabel("收入")
plt.ylabel("消费")
plt.show()
income_spending_corr = customers.corr('Income', 'Spending')
print('Income和Spending的相关系数为:', income_spending_corr)
复制代码
绘图结果如下:
6.特性工程
6.1 数值化字符串范例 数据
gender字段是字符串范例,需数值化。
# 将字符串型数据列 数值化
labelIndex = StringIndexer(inputCol='Gender', outputCol='indexed_Gender')
model = labelIndex.fit(customers) # 拟合数据,得到 字符型数据转换模型
customers = model.transform(customers) # 将customers中的字符型数据数值化,并把转化后的列添加到原数据customers
print("数值化字符型列的数据集:")
customers.show(5)
复制代码
数值化后的数据集部分 数据 如下。
6.2 选择、向量化特性
选择数值范例的特性"Age", “Income”, “Spending”, “indexed_Gender”,并向量化为一列:raw_features。
# 选择特征
features = ["Age", "Income", "Spending", "indexed_Gender"]
# 将选择的特征组合成一个向量
data_assembler = VectorAssembler(inputCols=features, outputCol='raw_features') # 实例化向量转换器
customers_assembled = data_assembler.transform(customers) # 向量化数据集中选定的数值型特征,将自动添加一列数据raw_features
customers_assembled.show(5)
复制代码
向量化后的数据集部分数据如下:
6.3 盘算特性之间的相关性系数(Correlation()),绘制热力图
特性"Age", “Income”, “Spending”, "indexed_Gender"之间的相关性稀疏如下:
热力图如下:
相关性系数的值范围从-1到1,其中1表现完全正相关,-1表现完全负相关,0表现没有线性相关。
代码如下:
# -------计算相关性系数,绘制热力图------
print("\n\n-------计算相关性系数------")
corr = Correlation.corr(customers_assembled, 'raw_features').collect()[0][0]
corr_float = corr.toArray().astype(float)
print(corr_float)
# 将相关性系数矩阵转换为Pandas DataFrame,以便使用matplotlib显示
corr_df = pd.DataFrame(corr_float, columns=features, index=features)
# 显示相关性系数矩阵的热力图
plt.imshow(corr_df, cmap='coolwarm', interpolation='nearest')
plt.colorbar()
plt.xticks(range(len(features)), features, rotation=45) # 设置横坐标标签
plt.yticks(range(len(features)), features) # 设置纵坐标标签
# 在热力图上添加每个相关性系数的值
for i in range(len(features)):
for j in range(len(features)):
if i == j:
# 不显示对角线上的值
continue
plt.text(j, i, np.round(corr_df.iloc[i, j], 2), ha='center', va='center', color='black')
plt.show()
复制代码
6.4 构建聚类模子、评估聚类模子
设聚类簇数k=3,将客户分为3类。
# -----------5.构建聚类模型--------
km = KMeans(featuresCol='raw_features', k=3) # 构建聚类模型
# km = BisectingKMeans(featuresCol='raw_features', k=3)
kmModel = km.fit(customers_assembled) # 拟合模型
km_pred = kmModel.transform(customers_assembled) # 用模型聚类,得到聚类结果列:prediction
km_pred.show(10)
# 评估聚类模型
km_evaluator = ClusteringEvaluator(predictionCol='prediction', featuresCol='raw_features')
silhouette = km_evaluator.evaluate(km_pred)
print("轮廓系数为:", silhouette)
results = kmModel.clusterCenters() # 聚类中心:"Age", "Income", "Spending", "indexed_Gender"
print("聚类中心:", results)
# -------打印3簇聚类中心------
for i in results:
print(i)
复制代码
6.5 数据可视化
绘制各簇的的Income和Spending核密度图,以及散点图和簇中心。代码如下。
# --------6. 数据可视化-------
print("\n-----分别选取各簇数据------")
pred_0 = km_pred.where(km_pred['prediction'] == 0).toPandas() # 选取 簇0 数据
pred_1 = km_pred.select('Age', 'Income', 'Spending', 'prediction') \
.where(km_pred['prediction'] == 1) \
.toPandas() # 选取 簇1 数据
pred_2 = km_pred.select('Age', 'Income', 'Spending', 'prediction') \
.where(km_pred['prediction'] == 2) \
.toPandas() # 选取 簇2 数据
#--- 绘制各簇 的Income和Spending核密度图--
plt.subplot(2, 1, 1)
pred_0['Income'].plot(kind='kde')
plt.title("簇0 Income、Spending概率密度图")
plt.subplot(2, 1, 2)
pred_0['Spending'].plot(kind='kde', c='orange')
plt.show() # 簇0的概率密度图
plt.subplot(2, 1, 1)
pred_1['Income'].plot(kind='kde')
plt.title("簇1 Income、Spending概率密度图")
plt.subplot(2, 1, 2)
pred_1['Spending'].plot(kind='kde', c='orange')
plt.show() # 簇1的概率密度图
plt.subplot(2, 1, 1)
pred_2['Income'].plot(kind='kde')
plt.title("簇2 Income、Spending概率密度图")
plt.subplot(2, 1, 2)
pred_2['Spending'].plot(kind='kde', c='orange')
plt.show() # 簇2的概率密度图
# ---------------绘制各簇Income和Spending 散点图-----------------
plt.scatter(pred_0['Income'], pred_0['Spending'], c='red', label='Cluster 0')
plt.scatter(pred_1['Income'], pred_1['Spending'], c='blue', label='Cluster 1')
plt.scatter(pred_2['Income'], pred_2['Spending'], c='green', label='Cluster 2')
# 簇中心:"Age", "Income", "Spending", "indexed_Gender",
x_coords = [result[1] for result in results] #提取所有聚类中心的第二个元素Income作为 x 坐标
y_coords = [result[2] for result in results] # 提取所有聚类中心的第三个元素Spending作为 y 坐标
plt.scatter(x_coords, y_coords, c='pink', s=100, label='Centroids') # 聚类中心
plt.xlabel('Income')
plt.ylabel('Spending')
plt.legend()
plt.show()
复制代码
各簇的Income和Spending概率密度图如下:
各簇的Income和Spending散点图。
参考资料:
1.pyspark学生结果分析与猜测(上):https://blog.csdn.net/weixin_52563520/article/details/137675514
2.https://blog.csdn.net/weixin_52563520/article/details/139126270?spm=1001.2014.3001.5502
3.https://blog.csdn.net/weixin_52563520/article/details/135358767?spm=1001.2014.3001.5502
4.spark学习回归理论和实战房价猜测:https://blog.csdn.net/qq_35394891/article/details/83184779
5.基于pyspark的波士顿房价猜测案例:https://blog.csdn.net/weixin_46474921/article/details/121780705
6.戴刚,张良均. PySpark大数据分析与应用. 人民邮电出书社,2024.
7.汪明. PySpark实战. 清华大学出书社,2022
8.用 K-Means聚类算法(K-Means Clustering)分析客户:https://zhuanlan.zhihu.com/p/502192474
9.Python实现聚类(Kmeans)分析客户分组:https://blog.csdn.net/weixin_42163563/article/details/119829124
10.Pyspark+关联规则 Kaggle购物篮分析案例:https://blog.csdn.net/thorn_r/article/details/138351087
11.Spark 关联规则挖掘:https://blog.csdn.net/weixin_39709476/article/details/109223271
12.大数据–关联规则挖掘案例:https://blog.csdn.net/qq_51641196/article/details/128478588
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/)
Powered by Discuz! X3.4