(python)几种方法的训练和对比

几种方法的训练和对比

概述

聚类算法,将数据重组为按某种方式排列的多个子集,以便从数据中推断出有意义的结构。
根据处理数据时所使用的度量方法或作出的假设,我们可以将聚类算法分成不同的种类。
这次我们python测试的为:k均值,觉知漂移,高斯混合,层次算法(Ward链接)

测试数据集

我们生成一个数据集,用于比较几种聚类方法。
我们从均值为u1=[10,0],u2=[0,10],方差为δ1=δ2=[[3,1],[1,4]]的两个二维正态分布,随机选取数据点形成数据集

python代码为:

from matplotlib import pyplot as plt
import numpy as np
np.random.seed(4711) # for repeatability
c1=np.random.multivariate_normal([10,0],[[3,1],[1,4]],size=[100,])
l1=np.zeros(100)
l2=np.ones(100)
c2=np.random.multivariate_normal([0,10],[[3,1],[1,4]],size=[100,])
#add noise:
np.random.seed(1) # for repeatability
noiselx=np.random.normal(0,2,100)
noisely=np.random.normal(0,8,100)
noise2=np.random.normal(0,8,100)
c1[:,0]+=noiselx
c1[:,1]+=noisely
c2[:,1]+=noise2

fig=plt.figure(figsize=(20,15))
ax=fig.add_subplot(111)
ax.set_xlabel('x',fontsize=30)
ax.set_ylabel('y',fontsize=30)
fig.suptitle('classes',fontsize=30)
labels=np.concatenate((l1,l2),)
X=np.concatenate((c1,c2),)
pp1=ax.scatter(c1[:,0],c1[:,1],cmap='prism',s=50,color='r')
pp2=ax.scatter(c2[:,0],c2[:,1],cmap='prism',s=50,color='g')
ax.legend((pp1,pp2),('class1','class2'),fontsize=35)
fig.savefig('classes.png')

我们为两个类别分别添加了服从正态分布的噪声,使得列子看起来更加真实。

我们得到了如下的图形
这里写图片描述

k均值,觉知漂移,高斯混合,层次算法(Ward链接)的比较

下面,我们分别用代码来比较几种方法。
k均值函数和高斯混合模型为指定簇的数量(n_clusters=2,n_component=2),将均值漂移算法的带宽设置为7(bandwidth=7)。层次聚类算法使用Ward链接来定义拘礼,终止层次算法的最大距离max_ d,我们设置为110。fcluster函数预测每个数据点属于哪个簇。k均值和均值漂移方法的聚类结果用labels_ 属性就能够获取到,而高斯混合模型则需要使用predict函数。k均值、均值漂移和高斯混合方法用fit函数训练,而层次聚类算法用linkage函数训练

代码如下

import numpy as np
from sklearn import mixture
from scipy.cluster.hierarchy import linkage
from scipy.cluster.hierarchy import fcluster
from sklearn.cluster import KMeans
from sklearn.cluster import MeanShift
from matplotlib import pyplot as plt

np.random.seed(4711) # for repeatability
c1=np.random.multivariate_normal([10,0],[[3,1],[1,4]],size=[100,])
l1=np.zeros(100)
l2=np.ones(100)
c2=np.random.multivariate_normal([0,10],[[3,1],[1,4]],size=[100,])
#add noise:
np.random.seed(1) # for repeatability
noiselx=np.random.normal(0,2,100)
noisely=np.random.normal(0,8,100)
noise2=np.random.normal(0,8,100)
c1[:,0]+=noiselx
c1[:,1]+=noisely
c2[:,1]+=noise2

fig=plt.figure(figsize=(20,15))
labels=np.concatenate((l1,l2),)
X=np.concatenate((c1,c2),)



fig.clf() #reset plt
fig,((axis1,axis2),(axis3,axis4))=plt.subplots(2,2,sharex='col',sharey='row')

#K-means
kmeans= KMeans(n_clusters=2)
kmeans.fit(X)
pred_kmeans=kmeans.labels_
plt.scatter(X[:,0],X[:,1],c=kmeans.labels_,cmap='prism')#plot

axis1.scatter(X[:,0],X[:,1],c=kmeans.labels_,cmap='prism')
axis1.set_ylabel('y',fontsize=40)
axis1.set_title('k_means',fontsize=20)

#mean_shift
ms=MeanShift(bandwidth=7)
ms.fit(X)
pred_ms=ms.labels_
axis2.scatter(X[:,0],X[:,1],c=pred_ms,cmap='prism')
axis2.set_ylabel('y',fontsize=40)
axis2.set_title('mean_shift',fontsize=20)

#gaussian mixture
g=mixture.GMM(n_components=2)
g.fit(X)
pred_gmm=g.predict(X)
axis3.scatter(X[:,0],X[:,1],c=pred_gmm,cmap='prism')
axis3.set_xlabel('x',fontsize=40)
axis3.set_ylabel('y',fontsize=40)
axis3.set_title('gaussian mixture',fontsize=20)

#hierarchical
Z=linkage(X,'ward')
max_d=110
pred_h=fcluster(Z,max_d,criterion='distance')
axis4.scatter(X[:,0],X[:,1],c=pred_h,cmap='prism')
axis4.set_xlabel('x',fontsize=40)
axis4.set_title('hierachical ward',fontsize=20)
fig.set_size_inches(18.5,10.5)

fig.savefig('comp_clustering.png',dpi=100)

结果图:
这里写图片描述

我们可以发现,出了高斯混合模型之外,其他3中算法将一些数据点分错簇,这一点k均值和层次聚类方法表现最为突出。
高斯混合模型是鲁棒性最好的方法,因为数据集所属的分布和假设相同。

猜你喜欢

转载自blog.csdn.net/qq_40162797/article/details/80437449
今日推荐