"""
聚类是在没有给定划分类别的情况下,根据数据相似度进行样本分组的一种方法,聚类模型可以将
无标记的数据聚类为多个簇,分别视为一类,是一种非监督的学习算法。在商业上,聚类可以帮助
市场分析人员从消费者库中区分出不同的消费群体,并概括出每一类消费者的消费模式或消费习惯。
同时,聚类也可以作为其它机器学习算法的一个预处理步骤,如异常值识别、连续型特征离散化等
聚类的输入是一组未被标记的样本,聚类根据数据自身的距离或相似度将他们划分为若干组,划分
的原则是组内样本最小化而组间(外部)距离最大化
"""
#1.使用iris数据集,设定聚类数为3,生成K-Means聚类模型
#生成K-Means聚类模型并训练模型
from sklearn import datasets
from sklearn.cluster import KMeans
#导入数据
iris = datasets.load_iris()
x = iris.data
y = iris.target
#构建并训练K-means模型
kmeans = KMeans(n_clusters = 3,random_state=0).fit(x)
print('K-means模型为:\n',kmeans)
"""
通过cluster_centers_属性查看各个簇的质心,通过labels_属性查看每个样本所属的簇的类别
,通过inertia_属性查看每个点到其簇的质心的距离之和
"""
#查看簇的质心、簇的类别和点到簇的质心的距离之和
print('簇的质心为:\n',kmeans.cluster_centers_)
print('样本所属的簇为:\n',kmeans.labels_)
print('样本到类中心的距离之和为:',kmeans.inertia_)
#使用predict方法预测样本所属类别,并绘制iris原本的类别和K-Means聚类结果
import matplotlib.pyplot as plt
#获取模型聚类结果
y_pre = kmeans.predict(x)
#绘制iris原本的类别
plt.scatter(x[: ,0],x[: ,1],c=y)
plt.show()
#绘制kmeans聚类结果
plt.scatter(x[: ,0], x[: ,1], c=y_pre)
plt.show()
#2.层次聚类
"""
层次聚类可在不同层次上对数据集进行划分,形成树状的聚类结构,该算法将每一个样本是为同一类,
之后按聚类间的相似度进行聚类,直至全部样本聚为一类
层次聚类计算一次便能得到完整的聚类树,无须重复计算,且可以发现类别的层次关系,但计算的发
杂度较高,不适合大型数据集
"""
#使用单链接single-linkage算法进行层次聚类
from sklearn.cluster import AgglomerativeClustering
#单链接层次聚类
clusing_ward = AgglomerativeClustering(n_clusters = 3).fit(x)
print('单链接层次聚类模型为:\n',clusing_ward)
#查看簇类别标签和叶节点数量
print('簇类别标签为:\n',clusing_ward.labels_)
print('叶节点数量为:',clusing_ward.n_leaves_)
"""
使用fit_predict方法获取单链接层次聚类模型的聚类结果,并于使用均链接Average-linkage
算法和全链接complete-linkage算法的层次聚类模型的聚类效果做对比
"""
#对比单链接、均链接和全链接层次聚类模型的聚类结果
#绘制单链接聚类结果
cw_ypre = AgglomerativeClustering(n_clusters = 3).fit_predict(x)
plt.scatter(x[: , 0],x[: ,1],c=cw_ypre)
plt.title('war linkage',size = 17)
plt.show()
#绘制均链接聚类结果
cw_ypre = AgglomerativeClustering(linkage='average',n_clusters=3).fit_predict(x)
plt.scatter(x[: ,0],x[: ,1],c=cw_ypre)
plt.title('averge linkage',size=17)
plt.show()
#绘制全链接聚类结果
cw_ypre = AgglomerativeClustering(linkage='complete',n_clusters = 3).fit_predict(x)
plt.scatter(x[: , 0],x[: ,1],c = cw_ypre)
plt.title('complete linkage',size=17)
plt.show()
#3中链接算法中,单链接与均链接层次聚类的类别大小较为规则,而全连接层次聚类的类别大小的差异最大
#3.DBSCAN
"""
DBSCAN是一种基于密度的空间聚类算法,该算法利用基于密度的聚类的概念,即要求聚类空间中的一定区域内所包
含对象的数目不小于给定的阈值,该算法将每个具有足够密度的区域划分为一个簇,能在具有噪声的空间中发现任意
形状的簇,其中簇的定义为密度相连的点的最大集合,DBSCAN算法聚类速度快,且能够有效处理噪声点和发现任意
形状的空间聚类,在当数据量增大时,算法所消耗的内存及I/O也很大,且对于分布密度不均匀的空间的聚类效果较差
DBSCAN函数主要通过调整eps参数和min_samples参数优化聚类效果,eps参数越小且min_samples参数越大,则密
度越大,即分布更为集中的样本将聚为一类;反之,则密度越小,即分布更为分散的样本将聚为一类。生成3簇样本数据
,其中两簇为非凸数据,另一簇为对比数据,使用默认参数的DBSCAN函数构建模型并使用fit方法训练模型
"""
#使用DBSCAN函数构建并训练模型
import numpy as np
from sklearn.cluster import DBSCAN
#生成两簇非凸数据
x1,y2 = datasets.make_blobs(n_samples = 1000,n_features=2,centers = [[1.2,1.2]],
cluster_std=[[.1]],random_state=9)
#一簇对比数据
x2,y1 = datasets.make_circles(n_samples = 5000,factor=.6,noise =.05)
x = np.concatenate((x1,x2))
plt.scatter(x[: , 0], x[: , 1], marker = 'o')
plt.show()
#生成DBSCAN模型,使用默认参数
dbs = DBSCAN().fit(x)
print('默认参数的DBSCAN模型:\n',dbs)
#查看样本的簇标记和核心样本的位置
print('DBSCAN模型的簇标签为:',dbs.labels_)
print('核心样本的位置为:',dbs.core_sample_indices_)
#使用fit_predict方法得到聚类结果并与K-means聚类对比
#调整eps参数和min_samples参数
ds_pre = DBSCAN(eps = 0.1,min_samples = 12).fit_predict(x)
plt.scatter(x[: , 0],x[: , 1],c=ds_pre)
plt.title('DBSCAN',size=17)
plt.show()
#K-means聚类
km_pre = KMeans(n_clusters = 3,random_state=9).fit_predict(x)
plt.scatter(x[: ,0],x[: , 1],c=km_pre)
plt.title('K-means',size =17)
plt.show()
#4.高斯混合模型
"""
高斯混合模型算法由多个高斯模型线性叠加混合而成,是单一高斯概率密度函数的
延伸,每一个高斯模型对应一个类别,通过EM最大期望算法进行训练得到样本的类别
能够平滑地近似任意形状的密度分布
GMM算法是混合模型中计算速度最快的算法,其得到的不是一个确定的分类标记而是每个
类的概率。由于每一步迭代计算量较大,将会占用更多的计算资源,且由于使用EM算法,
容易陷入局部最优
"""
#通过GaussianMixture函数构建GMM模型并训练模型
#导入数据
iris =datasets.load_iris()
x = iris.data
y = iris.target
#绘制样本数据
plt.scatter(x[: ,0],x[: , 1],c=y)
plt.title('iris',size=17)
plt.show()
#构建聚类数为3的GMM模型
from sklearn.mixture import GaussianMixture
gmm = GaussianMixture(n_components=3).fit(x)
print('GMM模型:\n',gmm)
#查看GMM模型中各高斯模型的权重和均值
print('GMM模型的权重为:',gmm.weights_)
print('GMM模型的均值为:\n',gmm.means_)
#获取模型的聚类结果并与K-means聚类结果对比
#获取GMM模型聚类结果
gmm_pre = gmm.predict(x)
plt.scatter(x[: , 0],x[: , 1],c=gmm_pre)
plt.title('GMM',size=17)
plt.show()
#K-means聚类
km_pre = KMeans(n_clusters =3).fit_predict(x)
plt.scatter(x[: , 0], x[: , 1], c = km_pre)
plt.title('K-means',size=17)
plt.show()