機器學習-聚類分析代碼解析

01 概念

聚類與分類的不同在於,聚類所要求劃分的類是未知的。

聚類是將數據分類到不同的類或者簇這樣的一個過程,所以同一個簇中的對象有很大的相似性,而不同簇間的對象有很大的相異性。

從機器學習的角度講,簇相當於隱藏模式。聚類是搜索簇的無監督學習過程。與分類不同,無監督學習不依賴預先定義的類或帶類標記的訓練實例,需要由聚類學習算法自動確定標記,而分類學習的實例或數據對象有類別標記。聚類是觀察式學習,而不是示例式的學習。

聚類分析是一種探索性的分析,在分類的過程中,人們不必事先給出一個分類的標準,聚類分析能夠從樣本數據出發,自動進行分類。聚類分析所使用方法的不同,常常會得到不同的結論。不同研究者對於同一組數據進行聚類分析,所得到的聚類數未必一致。

從實際應用的角度看,聚類分析是數據挖掘的主要任務之一。而且聚類能夠作為一個獨立的工具獲得數據的分佈狀況,觀察每一簇數據的特徵,集中對特定的聚簇集合作進一步地分析。聚類分析還可以作為其他算法(如分類和定性歸納算法)的預處理步驟。

聚類分析(cluster analysis)是一組將研究對象分為相對同質的群組(clusters)的統計分析技術。

聚類分析也叫分類分析(classification analysis)或數值分類(numerical taxonomy)

變量類型:定類變量、定量(離散和連續)變量


02 聚類方法分類


1,層次聚類

合併法、分解法、樹狀圖

2. 非層次聚類

劃分聚類、譜聚類


03 代碼解析


使用kmeans算法

<code>### 產生三類隨機樣本# In[]:from sklearn.datasets import make_blobs# 隨機產生150個樣本,每個樣本有兩個特徵,形成3個簇# cluster_std 是簇內特徵值的標準差X, y = make_blobs(n_samples=150,                   n_features=2,                   centers=3,                   cluster_std=0.5,                   shuffle=True,                   random_state=0)# In[]:X.shape,y.shape# In[]:# y的範圍是0,1,2,表示每個x樣本所屬的簇y# In[]:# 查看X的5個值,X是二維,150行2列,行表示樣本個數# 列表示特徵個數# i是行索引,表示樣本索引,第0列是特徵1,第1列是特徵2for i in range(5):    print("%f,%f" % (X[i,0], X[i,1]))# In[]:import matplotlib.pyplot as plt# 畫散點圖,橫座標和縱座標分別對應兩個不同的特徵# X[:, 0]表示所有的特徵1值# X[:, 1]表示所有的特徵2值,兩個特徵值對應座標一個點# s是size的意思,表示點的大小,可以改變50到100嘗試plt.scatter(X[:, 0], X[:, 1],             c='white', marker='o', edgecolor='black', s=50)# 顯示網格plt.grid()# tight_layout會自動調整子圖參數,使之填充整個圖像區域# 具體例子可以看下:# https://blog.csdn.net/du_shuang/article/details/84139716plt.tight_layout()# 也可以將圖像保存#plt.savefig('path/e1.png', dpi=300)plt.show()### 使用sklearn的kmeans方法# In[]:from sklearn.cluster import KMeanskm = KMeans(n_clusters=3,             init='random',             n_init=10,             max_iter=300,            tol=1e-04,            random_state=0)y_km = km.fit_predict(X)# 每個樣本所屬於的簇,0,1,2三個簇y_km# In[]:# 對三簇進行畫圖# In[]:y_km.shape, type(y_km)# In[]:# y_km是一個一維數組,有0,1,2三個值# y_km == 0返回值是一個bool數組,0值位置是Truey_km == 0# In[]:# 下面方法是數組的過濾功能,將y_km == 0返回True# 的值保留,就是說只是保留150行中y值是0的樣本X[y_km == 0, 0]# In[]:# 分別對3個不同簇的樣本進行繪製plt.scatter(X[y_km == 0, 0],            X[y_km == 0, 1],            s=50, c='lightgreen',            marker='s', edgecolor='black',            label='cluster 1')plt.scatter(X[y_km == 1, 0],            X[y_km == 1, 1],            s=50, c='orange',            marker='o', edgecolor='black',            label='cluster 2')plt.scatter(X[y_km == 2, 0],            X[y_km == 2, 1],            s=50, c='lightblue',            marker='v', edgecolor='black',            label='cluster 3')plt.scatter(km.cluster_centers_[:, 0],            km.cluster_centers_[:, 1],            s=250, marker='*',            c='red', edgecolor='black',            label='centroids')# legend是圖標說明的意思,一般顯示在右上角或右下角# 對不同形狀顏色圖標進行一個解釋plt.legend(scatterpoints=1)plt.grid()plt.tight_layout()#plt.savefig('path/2.png', dpi=300)plt.show()/<code> 


基於距離矩陣進行層次聚類算法


<code># In[]:import pandas as pdimport numpy as npimport matplotlib.pyplot as pltnp.random.seed(123)variables = ['X', 'Y', 'Z']labels = ['ID_0', 'ID_1', 'ID_2', 'ID_3', 'ID_4']# 生成5個樣本,每個樣本3個特徵# 一般來說,行表示樣本索引,列表示特徵索引X = np.random.random_sample([5, 3])*10df = pd.DataFrame(X, columns=variables, index=labels)df# ## Performing hierarchical clustering on a distance matrix# In[]:from scipy.spatial.distance import pdist, squareform# 生成所有樣本的距離矩陣,歐式距離進行度量row_dist = pd.DataFrame(squareform(pdist(df, metric='euclidean')),                        columns=labels,                        index=labels)# 注意!這是一個對稱矩陣,上三角與下三角值一樣row_dist# We can either pass a condensed distance matrix (upper triangular) from the `pdist` function, or we can pass the "original" data array and define the `metric='euclidean'` argument in `linkage`. However, we should not pass the squareform distance matrix, which would yield different distance values although the overall clustering could be the same.# In[]:# 1. incorrect approach: Squareform distance matrix# 這是一個錯誤的調用方法,不能把整個的距離矩陣row_dist作為輸入參數from scipy.cluster.hierarchy import linkagerow_clusters = linkage(row_dist, method='complete', metric='euclidean')pd.DataFrame(row_clusters,             columns=['row label 1', 'row label 2',                      'distance', 'no. of items in clust.'],             index=['cluster %d' % (i + 1)                    for i in range(row_clusters.shape[0])])# In[]:# 正確的調用方法1from scipy.cluster.hierarchy import linkage# 2. correct approach: Condensed distance matrix# 這裡的method='complete',指的就是度量簇之間距離的方法# complete就是全鏈接的方式row_clusters = linkage(pdist(df, metric='euclidean'), method='complete')pd.DataFrame(row_clusters,             columns=['row label 1', 'row label 2',                      'distance', 'no. of items in clust.'],             index=['cluster %d' % (i + 1)                     for i in range(row_clusters.shape[0])])# In[]:# 正確的調用方法2# 3. correct approach: Input sample matrixrow_clusters = linkage(df.values, method='complete', metric='euclidean')pd.DataFrame(row_clusters,             columns=['row label 1', 'row label 2',                      'distance', 'no. of items in clust.'],             index=['cluster %d' % (i + 1)                    for i in range(row_clusters.shape[0])])# In[]:# 對分層聚類進行可視化from scipy.cluster.hierarchy import dendrogram# make dendrogram black (part 1/2)# from scipy.cluster.hierarchy import set_link_color_palette# set_link_color_palette(['black'])# 下面函數會產生一個樹狀的分層聚類圖row_dendr = dendrogram(row_clusters,                        labels=labels,                       # make dendrogram black (part 2/2)                       # color_threshold=np.inf                       )# plt函數可以對上面的圖進行添加相關的內容和調整# 比如下面對圖的佈局進行自動調整,以及增加y軸的文字說明等# 也可以對產生的圖像進行保存等,就是說plt可以增加更多對生成圖的操作plt.tight_layout()plt.ylabel('Euclidean distance')#plt.savefig('images/xxx.png', dpi=300, #            bbox_inches='tight')# 如果不使用jupiter notebook的交互式操作,而是在命令行下運行# 必須調用下面命令才會顯示圖像,但是在交互模式下,可以直接顯示圖像對象的。plt.show()# ## 將熱圖與分層聚類的樹狀圖進行結合# ## Attaching dendrograms/樹狀圖 to a heat map# In[]:# 先產生一個圖的對象fig = plt.figure(figsize=(8, 8), facecolor='white')# 關於建立座標軸的概念,參考example3-1.py例子# 在圖像的對象中增加一個座標系,注意在一個圖中是可以增加多個座標系的# 這個座標系是用來顯示聚類樹狀圖的axd = fig.add_axes([0.09, 0.1, 0.2, 0.6])# 對原有的樹狀圖進行旋轉,旋轉的目的是為了和產生的熱圖對應起來# 並且顯示到同一個figure對象row_dendr = dendrogram(row_clusters, orientation='left')# 獲取聚類後樣本的數據,數據的排序順序和樹狀圖從上向下的順序是一致的df_rowclust = df.iloc[row_dendr['leaves'][::-1]]df_rowclust.shape, df_rowclust"""將下面數據與dendrogram旋轉後的樹狀圖數據進行對照,樣本順序是一致的,這個結果是一個dataframe格式,下面將這些數據以熱圖的方式展示,並於對應樹狀分支進行對應           X           Y          ZID_44.3857220.5967793.980443ID_06.9646922.8613932.268515ID_33.9211753.4317807.290497ID_29.8076426.8482974.809319ID_15.5131487.1946904.231065"""# 設置座標軸相關屬性axd.set_xticks([])axd.set_yticks([])# 隱藏刻度值for i in axd.spines.values():    i.set_visible(False)# 在figure對象中增加一個新的座標系畫熱圖,位於樹狀圖的右邊# 分析下第一個圖的位置:axd = fig.add_axes([0.09, 0.1, 0.2, 0.6])# 第一個圖佔的寬度是figure的0.2,所以下面熱圖的起始x是0.23,在樹狀圖右邊# 中間還有figure寬度0.03的間隙axm = fig.add_axes([0.23, 0.1, 0.6, 0.6])  # x-pos, y-pos, width, height# 下面是把熱圖畫出cax = axm.matshow(df_rowclust, interpolation='nearest', cmap='hot_r')fig.colorbar(cax)axm.set_xticklabels([''] + list(df_rowclust.columns))axm.set_yticklabels([''] + list(df_rowclust.index))plt.show()# ## Applying agglomerative clustering via scikit-learn# In[]:from sklearn.cluster import AgglomerativeClusteringac = AgglomerativeClustering(n_clusters=3,                              affinity='euclidean',                              linkage='complete')labels = ac.fit_predict(X)print('Cluster labels: %s' % labels)# In[]:ac = AgglomerativeClustering(n_clusters=2,                              affinity='euclidean',                              linkage='complete')labels = ac.fit_predict(X)print('Cluster labels: %s' % labels)/<code> 


機器學習-聚類分析代碼解析


DBSCAN

<code># # Locating regions of high density via DBSCAN# In[]:import matplotlib.pyplot as pltfrom sklearn.datasets import make_moonsX, y = make_moons(n_samples=200, noise=0.05, random_state=0)plt.scatter(X[:, 0], X[:, 1])plt.tight_layout()plt.show()# K-means and hierarchical clustering:# In[]:from sklearn.cluster import KMeansfrom sklearn.cluster import AgglomerativeClusteringf, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 3))km = KMeans(n_clusters=2, random_state=0)y_km = km.fit_predict(X)ax1.scatter(X[y_km == 0, 0], X[y_km == 0, 1],            edgecolor='black',            c='lightblue', marker='o', s=40, label='cluster 1')ax1.scatter(X[y_km == 1, 0], X[y_km == 1, 1],            edgecolor='black',            c='red', marker='s', s=40, label='cluster 2')ax1.set_title('K-means clustering')ac = AgglomerativeClustering(n_clusters=2,                             affinity='euclidean',                             linkage='complete')y_ac = ac.fit_predict(X)ax2.scatter(X[y_ac == 0, 0], X[y_ac == 0, 1], c='lightblue',            edgecolor='black',            marker='o', s=40, label='cluster 1')ax2.scatter(X[y_ac == 1, 0], X[y_ac == 1, 1], c='red',            edgecolor='black',            marker='s', s=40, label='cluster 2')ax2.set_title('Agglomerative clustering')plt.legend()plt.tight_layout()plt.show()# Density-based clustering:# In[]:from sklearn.cluster import DBSCAN# eps就是指定的半徑距離,min_samples為範圍內指定樣本數量db = DBSCAN(eps=0.2, min_samples=5, metric='euclidean')y_db = db.fit_predict(X)plt.scatter(X[y_db == 0, 0], X[y_db == 0, 1],            c='lightblue', marker='o', s=40,            edgecolor='black',             label='cluster 1')plt.scatter(X[y_db == 1, 0], X[y_db == 1, 1],            c='red', marker='s', s=40,            edgecolor='black',             label='cluster 2')plt.legend()plt.tight_layout()plt.show()/<code>


機器學習-聚類分析代碼解析

figure對象

<code># In[]:import matplotlib.pyplot as plt# 產生一個畫圖對象,就是右邊演示顯示的黑色背景區域fig    = plt.figure()# 生成座標軸的位置,就是說在同一個圖像figure對象中,# 是可以有多個座標系的,添加座標系的四個參數都是比例值,都是# figure對象,即顯示的黑色底色的比例值,建設圖像對象的寬是w,高是h,# 0.1, 0.1 表示建立座標系的原點位置為圖像對象大小的0.1*w和0.1h,# 0.8, 0.8 表示建立座標系的空間區域大小(寬和高),0.8*w和0.8h# 這四個值都是圖像空間大小(寬和高)的比例值,0-1之間。ax1     = fig.add_axes([0.1, 0.1, 0.8, 0.8])ax2     = fig.add_axes([0.05, 0.2, 0.5, 0.5])line1  = ax1.plot([0,1], [0,1])ax1.set_title("a straight line (OO)")ax1.set_xlabel("x value")ax1.set_ylabel("y value")line2  = ax2.plot([0,1], [0,1])plt.show()/<code>


分享到:


相關文章: