聚類分析html
1、概念python
聚類分析是按照個體的特徵將他們分類,讓同一個類別內的個體之間具備較高的類似度,不一樣類別之間具備較大的差別性算法
聚類分析屬於無監督學習架構
聚類對象能夠分爲Q型聚類和R型聚類app
Q型聚類:樣本/記錄聚類 以距離爲類似性指標 (歐氏距離、歐氏平方距離、馬氏距離、明式距離等)ide
R型聚類:指標/變量聚類 以類似係數爲類似性指標 (皮爾遜相關係數、夾角餘弦、指數相關係數等)學習
2、經常使用的聚類算法idea
一、K-Means劃分法spa
K表示聚類算法中類的個數,Means表示均值算法,K-Means便是用均值算法把數據分紅K個類的算法。3d
K-Means算法的目標,是把n個樣本點劃分到k個類中,使得每一個點都屬於離它最近的質心(一個類內部全部樣本點的均值)對應的類,以之做爲聚類的標準。
算法原理見 http://www.aboutyun.com/thread-18178-1-1.html【轉】
K-Means算法的計算步驟
基於sklearn包的實現
導入一份以下數據,通過各變量間的散點圖和相關係數,發現工做日上班電話時長與總電話時長存在強正相關關係
選擇可建模的變量並降維
cloumns_fix1 = ['工做日上班時電話時長', '工做日下半時電話時長', '週末電話時長', '國際電話時長', '平均每次通話時長'] #數據降維 pca_2 = PCA(n_components=2) data_pca_2 = pd.DataFrame(pca_2.fit_transform(data[cloumns_fix1]))
經過sklearn包中的K-Means方法構建模型
#繪製散點圖查看數據點大體狀況 plt.scatter(data_pca_2[0],data_pca_2[1])
#預計將數據點分類爲3類 kmmodel = KMeans(n_clusters=3) #建立模型 kmmodel = kmmodel.fit(data[cloumns_fix1]) #訓練模型 ptarget = kmmodel.predict(data[cloumns_fix1]) #對原始數據進行標註 pd.crosstab(ptarget,ptarget) #交叉表查看各個類別數據的數量
plt.scatter(data_pca_2[0],data_pca_2[1],c=ptarget)#查看聚類的分佈狀況
最後,能夠經過直方圖查看各聚類間的差別
#查看各種之間的差別 dMean = pd.DataFrame(columns=cloumns_fix1+['分類']) #獲得每一個類別的均值 data_gb = data[cloumns_fix1].groupby(ptarget) #按標註進行分組 i = 0 for g in data_gb.groups: rMean = data_gb.get_group(g).mean() rMean['分類'] = g; dMean = dMean.append(rMean, ignore_index=True) subData = data_gb.get_group(g) for column in cloumns_fix1: i = i+1; p = plt.subplot(3, 5, i) p.set_title(column) p.set_ylabel(str(g) + "分類") plt.hist(subData[column], bins=20)
二、 層次聚類法
層次聚類算法又稱爲樹聚類算法,它根據數據之間的距離,透過一種層次架構方式,反覆將數據進行聚合,建立一個層次以分解給定的數據集。層次聚類算法經常使用於一維數據的自動分組。
層次聚類算法是一種很直觀的聚類算法,基本思想是經過數據間的類似性,按類似性由高到低排序後從新鏈接各個節點,整個過程就是創建一個樹結構,以下圖:
層次聚類算法的步驟:
基於sklearn包的實現
使用K-Means聚類案例中的數據
cloumns_fix1 = ['工做日上班時電話時長', '工做日下半時電話時長', '週末電話時長', '國際電話時長', '平均每次通話時長'] linkage = hcluster.linkage(data[cloumns_fix1], method='centroid') #中心點距離計算,獲得矩陣
linkage = scipy.cluster.hierarchy.linkage(data, method='single')
#層次聚類繪圖 hcluster.dendrogram(linkage) #不設置參數時會將全部點作爲一個基礎的類進行樹結構的繪製
#因爲數據量大,限制類的個數,保留12個節點,有括號表示副節點,括號內的數字爲該節點內部包含的子節點
hcluster.dendrogram(linkage, truncate_mode='lastp', p=12, leaf_font_size=12.)
#對聚類獲得的類進行標註 層次聚類的結果,要聚類的個數,劃分方法(maxclust,最大劃分法)
ptarget = hcluster.fcluster(linkage, 3, criterion='maxclust')
#查看各種別中樣本含量
pd.crosstab(ptarget,ptarget)
繪製圖形
#使用主成分分析進行數據降維 pca_2 = PCA(n_components=2) data_pca_2 = pd.DataFrame(pca_2.fit_transform(data[cloumns_fix1])) plt.scatter(data_pca_2[0], data_pca_2[1], c=ptarget) #繪製圖形
三、 DBSCAN密度法
概念:
中文全稱:基於密度的帶噪聲的空間聚類應用算法,它是將簇定義爲密度相聯的點的最大集合,可以把具備足夠高密度的區域劃分爲簇,並可在噪聲的空間數據集中發現任意形狀的聚類。
密度:空間中任意一點的密度是以該點爲圓心,以Eps爲半徑的園區域內包含的點數目。
鄰域:空間中任意一點的鄰域是以該店爲圓心,以Eps爲半徑的園區域內包含的點集合。
核心點:空間中某一點的密度,若是大於某一給定閾值MinPts,則稱該點爲核心點。(小於MinPts則稱邊界點)
噪聲點:既不是核心點,也不是邊界點的任意點
DBSCAN算法的步驟:
DBSCAN算法優勢:
DBSCAN算法缺點:
python中的實現
1)數學原理實現
導入一份以下分佈的數據點的集合
#計算獲得各點間距離的矩陣 from sklearn.metrics.pairwise import euclidean_distances dist = euclidean_distances(data)
將全部點進行分類,獲得核心點、邊界點和噪聲點
#設置Eps和MinPts
eps = 0.2
MinPts = 5
ptses = [] for row in dist: #密度
density = np.sum(row<eps) pts = 0 if density>MinPts: #核心點,密度大於5
pts = 1 elif density>1 : #邊界點,密度大於1小於5 pts = 2 else: #噪聲點,密度爲1 pts = 0 ptses.append(pts)
#獲得每一個點的分類
以防萬一,將噪聲點進行過濾,並計算新的距離矩陣
#把噪聲點過濾掉,由於噪聲點沒法聚類,它們獨自一類 corePoints = data[pandas.Series(ptses)!=0] coreDist = euclidean_distances(corePoints)
以每一個點爲核心,獲得該點的鄰域
cluster = dict() i = 0 for row in coreDist: cluster[i] = numpy.where(row<eps)[0] i = i + 1
而後,將有交集的鄰域,都合併爲新的領域
for i in range(len(cluster)): for j in range(len(cluster)): if len(set(cluster[j]) & set(cluster[i]))>0 and i!=j: cluster[i] = list(set(cluster[i]) | set(cluster[j])) cluster[j] = list()
最後,找出獨立(也就是沒有交集)的鄰域,就是咱們最後的聚類的結果了
result = dict() j = 0 for i in range(len(cluster)): if len(cluster[i])>0: result[j] = cluster[i] j = j + 1 #找出每一個點所在領域的序號,做爲他們最後聚類的結果標記 for i in range(len(result)): for j in result[i]: data.at[j, 'type'] = i plt.scatter(data['x'], data['y'], c=data['type'])
2)基於sklearn包的實現
eps = 0.2 MinPts = 5 model = DBSCAN(eps, MinPts) data['type'] = model.fit_predict(data) plt.scatter(data['x'], data['y'], c=data['type'])