數據分析與挖掘(十五)------挖掘建模之K-Means聚類算法

K-Means算法是經典的基於距離的非層次聚類算法,在最小化誤差函數的基礎上將數據劃分爲預定的類數K,採用距離作爲相似性的評價指標,即認爲兩個對象的距離越近,其相似度就越大。

1.算法過程    

(1)從N個樣本數據中隨機選取K個對象作爲初始的聚類中心。

(2)分別計算每個樣本到各個聚類中心的距離,將對象分配到距離最近的聚類中。

(3)所有對象分配完成後,重新計算K個聚類的中心。

(4)與前一次計算得到的K個聚類中心比較,如果聚類中心發生變化,轉過程(2),否則轉過程(5)。

(5)當質心不發生變化時停止並輸出聚類結果。

聚類的結果可能依賴於初始聚類中心的隨機選擇,可能使得結果嚴重偏離全局最優分類。實踐中,爲了得到較好的結果,通常選擇不同的聚類中心,多次運行K-Means算法。在所有對象分配完成後,重新計算K個聚類的中心時,對於連續數據,聚類中心取該簇的均值,但是當樣本的某些屬性是分類變量時,均值可能無定義,可以使用K-衆數方法。

2.數據類型與相似性的度量

(1)連續屬性

   對於連續屬性,要先對各屬性值進行零-均值規範,再進行距離的計算。在K-Means聚類算法中,一般需要度量樣本之間的距離、樣本與簇之間的距離以及簇與簇之間的距離。

    度量樣本之間的相似性最常用的是歐幾里得距離、曼哈頓距離和閔可夫斯基距離;樣本與簇之間的距離可以用樣本到簇中心的距離簇與簇之間的距離可以用簇中心的距離

(2)文檔數據

   

3.目標函數

 

使用誤差平方和SSE作爲度量聚類質量的目標函數,對於兩種不同的聚類結果,選擇誤差平方和較小的分類結果。

 

4.實例

根據餐飲客戶的消費行爲特徵數據,將客戶分類成不同客戶羣,並評價這些客戶羣的價值。

採用K-Means聚類算法,設定聚類個數K爲3,最大迭代次數爲500次,距離函數取歐氏距離。

#-*- coding: utf-8 -*-
#使用K-Means算法聚類消費行爲特徵數據

import pandas as pd

#參數初始化
inputfile = '../data/consumption_data.xls' #銷量及其他屬性數據
outputfile = '../tmp/data_type.xls' #保存結果的文件名
k = 3 #聚類的類別
iteration = 500 #聚類最大循環次數
data = pd.read_excel(inputfile, index_col = 'Id') #讀取數據
data_zs = 1.0*(data - data.mean())/data.std() #數據標準化

from sklearn.cluster import KMeans
model = KMeans(n_clusters = k, n_jobs = 4, max_iter = iteration) #分爲k類,併發數4
model.fit(data_zs) #開始聚類

#簡單打印結果
r1 = pd.Series(model.labels_).value_counts() #統計各個類別的數目
r2 = pd.DataFrame(model.cluster_centers_) #找出聚類中心
r = pd.concat([r2, r1], axis = 1) #橫向連接(0是縱向),得到聚類中心對應的類別下的數目
r.columns = list(data.columns) + [u'類別數目'] #重命名錶頭
print(r)

#詳細輸出原始數據及其類別
r = pd.concat([data, pd.Series(model.labels_, index = data.index)], axis = 1)  #詳細輸出每個樣本對應的類別
r.columns = list(data.columns) + [u'聚類類別'] #重命名錶頭
r.to_excel(outputfile) #保存結果

# 繪製聚類後的概率密度圖
def density_plot(data): #自定義作圖函數
  import matplotlib.pyplot as plt
  plt.rcParams['font.sans-serif'] = ['SimHei'] #用來正常顯示中文標籤
  plt.rcParams['axes.unicode_minus'] = False #用來正常顯示負號
  p = data.plot(kind='kde', linewidth = 2, subplots = True, sharex = False)
  [p[i].set_ylabel(u'密度') for i in range(k)]
  plt.legend()
  return plt

pic_output = '../tmp/pd_' #概率密度圖文件名前綴
for i in range(k):
  density_plot(data[r[u'聚類類別']==i]).savefig(u'%s%s.png' %(pic_output, i))

輸出:

分羣概率密度函數圖:

(1)分羣1特點:R間隔分佈在0-30天;消費次數集中在10-25次;消費金額在500-2000

 

(2)分羣2特點:R間隔分佈在0-30天;消費次數集中在0-12次;消費金額在0-1800

 

(3)分羣3特點:R間隔相對較大(25-100天);消費次數集中在0-15次;消費金額在0-2000

對比分析:分羣1消費時間間隔較短,消費次數多,而且消費金額較大,是高消費、高價值人羣。分羣2的時間間隔、消費次數和消費金額處於中等水平,代表着一般客戶。分羣3的消費時間間隔較長,消費次數較少,消費金額也不是特別高,是價值較低的客戶羣體。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章