K-Means 算法的原理
- 输入:
- 数据集 ,每个数据点 是一个 维向量。
- 簇数。
- 步骤:
- 初始化 个簇中心(可以随机初始化或使用其他方法)。
- 分配簇:
- 对每个点 ,将其分配到距离最近的簇中心 :
- 更新簇中心:
- 计算每个簇中所有点的均值作为新簇中心:
- 重复步骤 2 和步骤 3,直到簇中心收敛或达到最大迭代次数。
- 输出:
- 每个点的簇标签。
- 每个簇的中心。
Spark ML中的高斯混合模型(GMM)聚类算法
高斯混合模型(Gaussian Mixture Model, GMM)是一种基于概率模型的聚类算法。它假设数据是由多个高斯分布混合而成,每个高斯分布对应一个簇。
1. GMM算法的基本原理
- 高斯分布:
- 每个簇 k被假设为一个高斯分布:
- :第 k 个高斯分布的均值向量。
- :第 k 个高斯分布的协方差矩阵。
- d:数据的维度。
-
混合模型:
- 假设数据点 x 的生成来自一个混合分布:
- :第 k 个分布的混合权重,满足 。
-
模型参数:
- 模型需要估计参数 。
- 使用期望最大化(EM)算法进行参数估计。
2. GMM的特点
- 优势:
- 可以发现形状复杂的簇(非球形)。
- 提供每个数据点属于某个簇的概率分布,支持软聚类。
- 局限性:
- 对高维数据可能需要较大的计算成本。
- 对初始参数敏感,可能陷入局部最优。
- 需要预设簇的数量 k。
# -*- coding: utf-8 -*-
# @Time : 2024/10/2 12:42
# @Author : pblh123@126.com
# @File : pyspark_ClusteringAlgorithm.py
# @Describe : 距离算法kmeans,gmm
import os
import warnings
from pyspark.ml.clustering import KMeans, GaussianMixture
from pyspark.ml.evaluation import ClusteringEvaluator
from pyspark.ml.feature import VectorAssembler
from pyspark.sql import SparkSession
from pyspark.sql.types import DoubleType
from utils.window_Utils import windows_enviroment_set
# 过滤警告信息
warnings.simplefilter("ignore")
windows_enviroment_set()
def kmeans():
# 指定CSV文件路径
path = r"D:\PycharmProjects\2024\pyspark\datas\iris.txt"
# 使用Spark读取CSV文件并推断列的数据类型,然后重命名列
df_raw = spark.read.option("inferSchema", "true").option("sep", ","). \
csv(path).toDF("c0", "c1", "c2", "c3", "label")
# 将列的数据类型转换为Double
df_double = df_raw.select(
df_raw["c0"].cast(DoubleType()),
df_raw["c1"].cast(DoubleType()),
df_raw["c2"].cast(DoubleType()),
df_raw["c3"].cast(DoubleType()),
df_raw["label"]
)
# 创建 VectorAssembler assembler = VectorAssembler(inputCols=["c0", "c1", "c2", "c3"], outputCol="features")
# 使用 VectorAssembler 转换数据
df = assembler.transform(df_double).select("features")
# 创建 KMeans 模型
kmeans = KMeans().setK(3) # 设置簇的数量
kmeans.setFeaturesCol("features") # 设置特征列
kmeans.setPredictionCol("prediction") # 设置预测列
# 训练 KMeans 模型
kmeansmodel = kmeans.fit(df)
# 进行聚类预测
results = kmeansmodel.transform(df)
# 打印结果
for result in results.collect():
print(str(result.features) + " => cluster " + str(result.prediction))
# 打印 KMeans 模型的聚类中心
for center in kmeansmodel.clusterCenters():
print("Clustering Center: {}".format(center))
# 创建聚类评估器
evaluator = ClusteringEvaluator()
# 计算轮廓系数
silhouette = evaluator.evaluate(results)
print("Silhouette Score:", silhouette)
def gmm():
# 指定CSV文件路径
path = r"D:\PycharmProjects\2024\pyspark\datas\iris.txt"
# 使用Spark读取CSV文件并推断列的数据类型,然后重命名列
df_raw = spark.read.option("inferSchema", "true").option("sep", ","). \
csv(path).toDF("c0", "c1", "c2", "c3", "label")
# 将列的数据类型转换为Double
df_double = df_raw.select(
df_raw["c0"].cast(DoubleType()),
df_raw["c1"].cast(DoubleType()),
df_raw["c2"].cast(DoubleType()),
df_raw["c3"].cast(DoubleType()),
df_raw["label"]
)
# 创建 VectorAssembler assembler = VectorAssembler(inputCols=["c0", "c1", "c2", "c3"], outputCol="features")
# 使用 VectorAssembler 转换数据
df = assembler.transform(df_double).select("features")
# 创建 Gaussian Mixture 模型
gm = GaussianMixture().setK(3).setPredictionCol("Prediction") \
.setProbabilityCol("Probability")
# 训练模型
gmm = gm.fit(df)
# 使用 Gaussian Mixture 模型进行聚类预测
result = gmm.transform(df)
# 显示结果
result.show(150, truncate=False)
# 获取聚类簇数
k = gmm.getK()
# 打印每个组件的权重、均值向量和协方差矩阵
for i in range(k):
print("Component {}: ".format(i))
print("Weight: {}".format(gmm.weights[i]))
print("Mu Vector: \n{}".format(gmm.gaussians[i].mean))
print("Sigma Matrix: \n{}".format(gmm.gaussians[i].cov))
if __name__ == '__main__':
# 1. 创建SparkSession
spark = SparkSession.builder \
.appName("PysparkmllibclusteringAlgorithm_spark341") \
.master("local[2]") \
.getOrCreate()
# sparkcontext
sc = spark.sparkContext
spark.sparkContext.setLogLevel("WARN")
# 2. spark业务代码 business code kmeans()
gmm()
# 3. 关闭sparkSession, sparkcontext
sc.stop()
spark.stop()