机器学习-聚类分析代码解析

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>


分享到:


相關文章: