1. 程式人生 > >從0開始學pyspark(十):使用pyspark.ml.clustering模組對商場顧客聚類

從0開始學pyspark(十):使用pyspark.ml.clustering模組對商場顧客聚類

資料下載:

資料為kaggle上的關於商場客戶的資料,地址:https://www.kaggle.com/vjchoudhary7/customer-segmentation-tutorial-in-python

資料準備:

資料集很小,四個特徵值:性別,年齡,收入能力,消費能力,這裡我們用收入能力和消費能力兩項對客戶進行聚類處理

from pyspark.sql import SparkSession
spark = SparkSession.builder.master('local[1]').appName('learn_cluster').getOrCreate()
# 匯入資料 df = spark.read.csv('file:///home/ffzs/python-projects/learn_spark/Mall_Customers.csv', header=True, inferSchema=True) # 更換列名 df = df.withColumnRenamed('Annual Income (k$)', 'Income').withColumnRenamed('Spending Score (1-100)', 'Spend') # 看下資料 df.show(3) +----------+------+---+------+-----+ |CustomerID|
Gender|Age|Income|Spend| +----------+------+---+------+-----+ | 1| Male| 19| 15| 39| | 2| Male| 21| 15| 81| | 3|Female| 20| 16| 6| +----------+------+---+------+-----+ only showing top 3 rows # 檢視是否有缺失值 df.toPandas().isna().sum() CustomerID 0 Gender 0
Age 0 Income 0 Spend 0 dtype: int64 # 沒有缺失值,都是0 #選取特徵項,將特徵項合併成向量 from pyspark.ml.feature import VectorAssembler vecAss = VectorAssembler(inputCols = df.columns[3:], outputCol = 'features') df_km = vecAss.transform(df).select('CustomerID', 'features') df_km.show(3) #看一下 +----------+-----------+ |CustomerID| features| +----------+-----------+ | 1|[15.0,39.0]| | 2|[15.0,81.0]| | 3| [16.0,6.0]| +----------+-----------+ only showing top 3 rows ## 視覺化資料看一下 # spark不方便提取列資料轉換成pandas dataframe pd_df = df.toPandas() from plotly.offline import iplot, init_notebook_mode import plotly.graph_objs as go init_notebook_mode(connected=True) trace = go.Scatter(x=pd_df.Income, y=pd_df.Spend , mode='markers', marker = {'size':6}) iplot([trace])

結果如下:

在這裡插入圖片描述

看上去是5類;是不是我們接下來看。。

KMeans k均值聚類

class pyspark.ml.clustering.KMeans(self, featuresCol="features", predictionCol="prediction", k=2, initMode="k-means||", initSteps=2, tol=1e-4, maxIter=20, seed=None)

引數

initMode: 初始化演算法,可以使隨機的“random",也可以是”k-means||"
initSteps: k-means||初始化的步數,需>0
fit(datast,params=None)方法

model方法

cluster: 每個訓練資料點預測的聚類中心資料框
clusterSize: 每個簇的大小(簇內資料點的個數)
k: 模型訓練的簇個數
predictions: 由模型transform方法產生的資料框

from pyspark.ml.clustering import KMeans
# k取 2-19 時 獲取對應 cost 來確定 k 的最優取值
cost = list(range(2,20))
for k in range(2, 20):
    kmeans = KMeans(k=k, seed=1)
    km_model = kmeans.fit(df_km)
    # computeCost:計算輸入點與其對應的聚類中心之間的平方距離之和。
    cost[k-2] = km_model.computeCost(df_km)

# 視覺化
import matplotlib.pyplot as plt
%matplotlib inline

fig, ax = plt.subplots(1,1, figsize=(8,6))
ax.plot(range(2,20), cost)
ax.set_xlabel('k')
ax.set_ylabel('cost')

結果如下:

在這裡插入圖片描述

可以見到在k=5時,出現了拐角,我們取k=5

# k=5 建立模型
kmeans = KMeans(k=5, seed=1)
km_model = kmeans.fit(df_km)
centers = km_model.clusterCenters()
# 集簇中心點
centers
[array([55.2962963 , 49.51851852]),
 array([25.72727273, 79.36363636]),
 array([86.53846154, 82.12820513]),
 array([88.2       , 17.11428571]),
 array([26.30434783, 20.91304348])]

# 獲取聚類預測結果
transformed = km_model.transform(df_km).select('CustomerID', 'prediction')

# 合併表格
df_pred = df.join(transformed, 'CustomerID')

# 轉化pandas dataframe 然後視覺化
pd_df = df_pred.toPandas()
trace = go.Scatter(x=pd_df.Income, y=pd_df.Spend, 
                 mode='markers',
                marker = {'size':10,'color':pd_df.prediction,'colorscale':'Viridis'})
iplot([trace])

結果如下:
在這裡插入圖片描述

BisectingKMeans 二分k均值

pyspark.ml.clustering.BisectingKMeans(featuresCol='features', predictionCol='prediction', maxIter=20, seed=None, k=4, minDivisibleClusterSize=1.0, distanceMeasure='euclidean')

二分k均值(bisecting k-means)演算法的主要思想是:首先將所有點作為一個簇,然後將該簇一分為二。之後選擇能最大程度降低聚類代價函式(也就是誤差平方和)的簇劃分為兩個簇。以此進行下去,直到簇的數目等於使用者給定的數目k為止。
以上隱含著一個原則是:因為聚類的誤差平方和能夠衡量聚類效能,該值越小表示資料點月接近於它們的質心,聚類效果就越好。所以我們就需要對誤差平方和最大的簇進行再一次的劃分,因為誤差平方和越大,表示該簇聚類越不好,越有可能是多個簇被當成一個簇了,所以我們首先需要對這個簇進行劃分。

引數

maxIter: 最大迭代次數
K:聚類簇數
minDivisibleClusterSize: 聚類的最少資料點數(>1)或比例(0-1之間)
fit(dataset, params=None)方法

model方法

clusterCenters(): 獲取聚類中心,numpy array型別
computeCost():計算點與其中心的平方和距離
Transform():對預測資料進行預測
hasSummary:訓練模型是否有summary
Summary:獲取summary

Summary擁有的屬性

cluster:預測的聚類中心
clusterSizes:每個聚類的大小
K:聚類個數
Predictions:由模型的transforn方法產生的預測資料框

GaussianMixture 高斯混合模型

pyspark.ml.clustering.GaussianMixture(featuresCol='features', predictionCol='prediction', k=2, probabilityCol='probability', tol=0.01, maxIter=100, seed=None)

物件實現了用來擬合高斯混合模型的 期望最大化 (EM) 演算法。它還可以為多變數模型繪製置信區間,同時計算 BIC(Bayesian Information Criterion,貝葉斯資訊準則)來評估資料中聚類的數量。

優點:GMM的優點是投影后樣本點不是得到一個確定的分類標記,而是得到每個類的概率,這是一個重要資訊。GMM不僅可以用在聚類上,也可以用在概率密度估計上。缺點:當每個混合模型沒有足夠多的點時,估算協方差變得困難起來,同時演算法會發散並且找具有無窮大似然函式值的解,除非人為地對協方差進行正則化。GMM每一步迭代的計算量比較大,大於k-means。GMM的求解辦法基於EM演算法,因此有可能陷入區域性極值,這和初始值的選取十分相關了。

引數

fit(dataset,params=None)方法
k: 獨立高斯分佈的個數,>1
maxIter: 最大迭代次數 >=0
tol: 迭代演算法的收斂偏差 >=0

model方法

gaussianDF: 抽取高斯分佈作為資料框,每一行代表高斯分佈,有兩列:mean(vector)和 cov(Matrix)
hasSummary: 模型是否有總括函式
summary: 獲取總括資訊
transform(dataset,params=None)方法
weights: 高斯混合模型的權重,和為1

Summary擁有的屬性

cluster:預測的聚類中心
clusterSizes:每個聚類的大小
K:聚類個數
Predictions:由模型的transforn方法產生的預測資料框