K-Means算法是典型的基于距離的非層次聚類(lèi)算法,在最小化誤差函數(shù)的基礎(chǔ)上將數(shù)據(jù)換分為預(yù)定的類(lèi)數(shù)K戏溺,采用距離作為相似性的評(píng)價(jià)指標(biāo)撇眯,即認(rèn)為兩個(gè)對(duì)象的距離越近,其相似度就越大棺耍。
算法過(guò)程
- 從N個(gè)樣本數(shù)據(jù)中隨機(jī)選取K個(gè)對(duì)象作為初始的聚類(lèi)中心
- 分別計(jì)算各個(gè)樣本到各個(gè)聚類(lèi)中心的距離,將對(duì)象分配到最近的聚類(lèi)中种樱。
- 所有對(duì)象分配完后蒙袍,重新計(jì)算K個(gè)聚類(lèi)的中心。
- 與前一次計(jì)算得到的K個(gè)聚類(lèi)中心比較嫩挤,如果聚類(lèi)中心發(fā)生變化害幅,轉(zhuǎn)過(guò)程2,否則轉(zhuǎn)過(guò)程5
- 當(dāng)質(zhì)心不發(fā)生變化時(shí)岂昭,停止并輸出聚類(lèi)結(jié)果
連續(xù)屬性
要先對(duì)各個(gè)屬性值進(jìn)行 零 - 均值規(guī)范以现,再進(jìn)行距離計(jì)算。在K-Means中聚類(lèi)算法中,一般需要度量樣本之間的距離邑遏、樣本與簇之間的距離佣赖、簇與簇之間的距離
零-均值規(guī)范化
也稱(chēng)為標(biāo)準(zhǔn)差標(biāo)準(zhǔn)化,經(jīng)過(guò)處理的數(shù)據(jù)的均值為0记盒,標(biāo)準(zhǔn)差為1憎蛤。
轉(zhuǎn)化公式:當(dāng)前使用最多的數(shù)據(jù)標(biāo)準(zhǔn)化方法
實(shí)踐中纪吮,為得到較好的結(jié)果俩檬,通常選擇不同初始聚類(lèi)中心,多次運(yùn)行K-Means算法碾盟。
在所有對(duì)象分配完成后棚辽,重新計(jì)算K個(gè)聚類(lèi)的中心時(shí),對(duì)于連續(xù)數(shù)據(jù)冰肴,聚類(lèi)中心取該簇的均值晚胡,但當(dāng)樣本的某些屬性是分類(lèi)變量時(shí),均值可能無(wú)定義嚼沿,可以使用K-眾數(shù)方法估盘。
使用誤差平法和SSE(sum of squared errors)作為度量聚類(lèi)質(zhì)量的目標(biāo)函數(shù),對(duì)于兩種不同的聚類(lèi)結(jié)果骡尽,選擇誤差平方和較小的分類(lèi)結(jié)果
案例
消費(fèi)行為特征數(shù)據(jù) 聚類(lèi)分析
采用K-Means算法遣妥,設(shè)定聚類(lèi)個(gè)數(shù)K為3,最大迭代次數(shù)為500次攀细,距離函數(shù)區(qū)歐式距離
import pandas as pd
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
# 初始化參數(shù)
inputfile = './data/consumption_data.xls' # 銷(xiāo)量及其他屬性數(shù)據(jù)
outputfile = './data/data_type_2.xls' # 保存結(jié)果
k = 3
iteration = 500
data = pd.read_excel(inputfile, index_col = 'Id') # 讀取數(shù)據(jù)
data_zs = 1.0 * (data - data.mean()) / data.std() # 數(shù)據(jù)標(biāo)準(zhǔn)化
model = KMeans(n_clusters=k, n_jobs=4, max_iter=iteration)
model.fit(data_zs)
# 打印結(jié)果
r1 = pd.Series(model.labels_).value_counts() # 統(tǒng)計(jì)各個(gè)類(lèi)別數(shù)目
r2 = pd.DataFrame(model.cluster_centers_) # 找出聚類(lèi)中心
r = pd.concat([r1, r2], axis=1) # 橫向連接(0是縱向), 得到聚類(lèi)中心對(duì)應(yīng)得類(lèi)別下的數(shù)目
r.columns = list(data.columns) + [u'類(lèi)別數(shù)目'] # 重命名表頭
# 詳細(xì)輸出原始數(shù)據(jù)及其類(lèi)別
r = pd.concat([data, pd.Series(model.labels_, index = data.index )], axis=1)
r.columns = list(data.columns) + [u'聚類(lèi)類(lèi)別'] # 重命名表頭
r.to_excel(outputfile) # 保存結(jié)果
def density_plot(data):
plt.figure(figsize=(12, 6)) # 設(shè)置畫(huà)布大小
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用來(lái)正常顯示中文標(biāo)簽
plt.rcParams['axes.unicode_minus'] = False # 用來(lái)正常顯示負(fù)號(hào)
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 = './data/pd_' # 概率密度圖文件名前綴
for i in range(k):
density_plot(data[r[u'聚類(lèi)類(lèi)別'] == i]).savefig(u'%s%s.png' %(pic_output, i))
總結(jié)
分群1特點(diǎn):R間隔相對(duì)較大箫踩,主要集中在3080天;消費(fèi)次數(shù)集中在015次谭贪;消費(fèi)金額在:0~2000;
分群2特點(diǎn):R間隔相對(duì)較小境钟,主要集中在030天;消費(fèi)次數(shù)集中在010次俭识;消費(fèi)金額在:0~1800;
分群3特點(diǎn):R間隔相對(duì)較小慨削,主要集中在030天;消費(fèi)次數(shù)集中在1025次套媚;消費(fèi)金額在:500~2000;
對(duì)比分析
分群3時(shí)間間隔短缚态,消費(fèi)次數(shù)多,消費(fèi)金額大堤瘤,是高消費(fèi)玫芦、高價(jià)值人群。
分群2時(shí)間間隔本辐、消費(fèi)次數(shù)桥帆、消費(fèi)金額中等水平医增,代表著一般價(jià)值客戶(hù)。
分群1時(shí)間間隔長(zhǎng)老虫、消費(fèi)次數(shù)較少叶骨、消費(fèi)金額不是特別高,價(jià)值較低的客戶(hù)群體张遭。
聚類(lèi)分析算法評(píng)價(jià)
- purity 評(píng)價(jià)法
- RI 評(píng)價(jià)法
- F 值評(píng)價(jià)法