日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Spark ML - 聚类算法

發布時間:2023/12/4 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spark ML - 聚类算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://ihoge.cn/2018/ML2.html

Spark ML - 聚類算法

1.KMeans快速聚類

首先到UR需要的包:

import org.apache.spark.ml.clustering.{KMeans,KMeansModel} import org.apache.spark.ml.linalg.Vectors

開啟RDD的隱式轉換:

import spark.implicits._

? 為了便于生成相應的DataFrame,這里定義一個名為model_instance的case class作為DataFrame每一行(一個數據樣本)的數據類型。

case class model_instance (features: org.apache.spark.ml.linalg.Vector)

? 在定義數據類型完成后,即可將數據讀入RDD[model_instance]的結構中,并通過RDD的隱式轉換.toDF()方法完成RDD到DataFrame的轉換:

val rawData = sc.textFile("file:///home/hduser/iris.data") val df = rawData.map(line =>{ model_instance( Vectors.dense(line.split(",").filter(p => p.matches("\\d*(\\.?)\\d*")).map(_.toDouble)) )}).toDF()

? 與MLlib版的教程類似,我們使用了filter算子,過濾掉類標簽,正則表達式\\d*(\\.?)\\d*可以用于匹配實數類型的數字,\\d*使用了*限定符,表示匹配0次或多次的數字字符,\\.?使用了?限定符,表示匹配0次或1次的小數點。

? 在得到數據后,我們即可通過ML包的固有流程:創建Estimator并調用其fit()方法來生成相應的Transformer對象,很顯然,在這里KMeans類是Estimator,而用于保存訓練后模型的KMeansModel類則屬于Transformer:

val kmeansmodel = new KMeans().setK(3).setFeaturesCol("features").setPredictionCol("prediction").fit(df)

? 與MLlib版本類似,ML包下的KMeans方法也有Seed(隨機數種子)、Tol(收斂閾值)、K(簇個數)、MaxIter(最大迭代次數)、initMode(初始化方式)、initStep(KMeans||方法的步數)等參數可供設置,和其他的ML框架算法一樣,用戶可以通過相應的setXXX()方法來進行設置,或以ParamMap的形式傳入參數,這里為了簡介期間,使用setXXX()方法設置了參數K,其余參數均采用默認值。

? 與MLlib中的實現不同,KMeansModel作為一個Transformer,不再提供predict()樣式的方法,而是提供了一致性的transform()方法,用于將存儲在DataFrame中的給定數據集進行整體處理,生成帶有預測簇標簽的數據集:

val results = kmeansmodel.transform(df)

? 為了方便觀察,我們可以使用collect()方法,該方法將DataFrame中所有的數據組織成一個Array對象進行返回:

results.collect().foreach(row => {println( row(0) + " is predicted as cluster " + row(1))})

也可以通過KMeansModel類自帶的clusterCenters屬性獲取到模型的所有聚類中心情況:

kmeansmodel.clusterCenters.foreach(center => {println("Clustering Center:"+center)})

? 與MLlib下的實現相同,KMeansModel類也提供了計算 集合內誤差平方和(Within Set Sum of Squared Error, WSSSE) 的方法來度量聚類的有效性,在真實K值未知的情況下,該值的變化可以作為選取合適K值的一個重要參考:

kmeansmodel.computeCost(df)

2.高斯混合模型(GMM)聚類算法

2.1 基本原理

? 高斯混合模型(Gaussian Mixture Model, GMM) 是一種概率式的聚類方法,屬于生成式模型,它假設所有的數據樣本都是由某一個給定參數的 多元高斯分布 所生成的。具體地,給定類個數K,對于給定樣本空間中的樣本

,一個高斯混合模型的概率密度函數可以由K個多元高斯分布組合成的混合分布表示:

其中,

是以

為均值向量,

為協方差矩陣的多元高斯分布的概率密度函數,可以看出,高斯混合模型由K個不同的多元高斯分布共同組成,每一個分布被稱為高斯混合模型中的一個 成分(Component), 而

為第i個多元高斯分布在混合模型中的 權重 ,且有

假設已有一個存在的高斯混合模型,那么,樣本空間中的樣本的生成過程即是:以

作為概率(實際上,權重可以直觀理解成相應成分產生的樣本占總樣本的比例),選擇出一個混合成分,根據該混合成分的概率密度函數,采樣產生出相應的樣本。

那么,利用GMM進行聚類的過程是利用GMM生成數據樣本的“逆過程”:給定聚類簇數K,通過給定的數據集,以某一種 參數估計 的方法,推導出每一個混合成分的參數(即均值向量

、協方差矩陣

和權重

),每一個多元高斯分布成分即對應于聚類后的一個簇。高斯混合模型在訓練時使用了極大似然估計法,最大化以下對數似然函數:

顯然,該優化式無法直接通過解析方式求得解,故可采用 期望-最大化(Expectation-Maximization, EM) 方法求解,具體過程如下(為了簡潔,這里省去了具體的數學表達式,詳細可見wikipedia):

1.根據給定的K值,初始化K個多元高斯分布以及其權重; 2.根據貝葉斯定理,估計每個樣本由每個成分生成的后驗概率;(EM方法中的E步) 3.根據均值,協方差的定義以及2步求出的后驗概率,更新均值向量、協方差矩陣和權重;(EM方法的M步) 重復2~3步,直到似然函數增加值已小于收斂閾值,或達到最大迭代次數

? 當參數估計過程完成后,對于每一個樣本點,根據貝葉斯定理計算出其屬于每一個簇的后驗概率,并將樣本劃分到后驗概率最大的簇上去。相對于KMeans等直接給出樣本點的簇劃分的聚類方法,GMM這種給出樣本點屬于每個簇的概率的聚類方法,被稱為 軟聚類(Soft Clustering / Soft Assignment)

2.2 模型的訓練與分析

? Spark的ML庫提供的高斯混合模型都在org.apache.spark.ml.clustering包下,和其他的聚類方法類似,其具體實現分為兩個類:用于抽象GMM的超參數并進行訓練的GaussianMixture類(Estimator)和訓練后的模型GaussianMixtureModel類(Transformer),在使用前,引入需要的包:

import org.apache.spark.ml.clustering.{GaussianMixture,GaussianMixtureModel} import org.apache.spark.ml.linalg.Vector

開啟RDD的隱式轉換:

import spark.implicits._

? 我們仍采用Iris數據集進行實驗。為了便于生成相應的DataFrame,這里定義一個名為model_instance的case class作為DataFrame每一行(一個數據樣本)的數據類型。

case class model_instance (features: org.apache.spark.ml.linalg.Vector)

在定義數據類型完成后,即可將數據讀入RDD[model_instance]的結構中,并通過RDD的隱式轉換.toDF()方法完成RDD到DataFrame的轉換:

val rawData = sc.textFile("file:///home/hduser/iris.data") val df = rawData.map(line =>{ model_instance( Vectors.dense(line.split(",").filter(p => p.matches("\\d*(\\.?)\\d*")).map(_.toDouble)) )}).toDF()

? 與MLlib的操作類似,我們使用了filter算子,過濾掉類標簽,正則表達式\\d*(\\.?)\\d*可以用于匹配實數類型的數字,\\d*使用了*限定符,表示匹配0次或多次的數字字符,\\.?使用了?限定符,表示匹配0次或1次的小數點。

? 可以通過創建一個GaussianMixture類,設置相應的超參數,并調用fit(..)方法來訓練一個GMM模型GaussianMixtureModel,在該方法調用前需要設置一系列超參數,如下表所示:

  • K:聚類數目,默認為2
  • maxIter : 最大迭代次數,默認為100
  • seed : 隨機數種子,默認為隨機Long值
  • Tol : 對數似然函數收斂閾值,默認為0.01

其中,每一個超參數均可通過名為setXXX(...)(如maxIterations即為setMaxIterations())的方法進行設置。這里,我們建立一個簡單的GaussianMixture對象,設定其聚類數目為3,其他參數取默認值。

val gm = new GaussianMixture().setK(3).setPredictionCol("Prediction").setProbabilityCol("Probability") val gmm = gm.fit(df)

和KMeans等硬聚類方法不同的是,除了可以得到對樣本的聚簇歸屬預測外,還可以得到樣本屬于各個聚簇的概率(這里我們存在”Probability”列中)。

? 調用transform()方法處理數據集之后,打印數據集,可以看到每一個樣本的預測簇以及其概率分布向量

val result = gmm.transform(df) result.show(150, false)

? 得到模型后,即可查看模型的相關參數,與KMeans方法不同,GMM不直接給出聚類中心,而是給出各個混合成分(多元高斯分布)的參數。在ML的實現中,GMM的每一個混合成分都使用一個MultivariateGaussian類(位于org.apache.spark.ml.stat.distribution包)來存儲,我們可以使用GaussianMixtureModel類的weights成員獲取到各個混合成分的權重,使用gaussians成員來獲取到各個混合成分的參數(均值向量和協方差矩陣):

for (i <- 0 until gmm.getK) {println("Component %d : weight is %f \n mu vector is %s \n sigma matrix is %s" format(i, gmm.weights(i), gmm.gaussians(i).mean, gmm.gaussians(i).cov))}

更多精彩內容請關注: http://ihoge.cn

總結

以上是生活随笔為你收集整理的Spark ML - 聚类算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。