数据挖掘——聚类分析总结

聚类分析html

1、概念python

  聚类分析是按照个体的特征将他们分类,让同一个类别内的个体之间具备较高的类似度,不一样类别之间具备较大的差别性算法

  聚类分析属于无监督学习架构

  聚类对象能够分为Q型聚类和R型聚类app

    Q型聚类:样本/记录聚类   距离为类似性指标   (欧氏距离、欧氏平方距离、马氏距离、明式距离等)ide

    R型聚类:指标/变量聚类    类似系数为类似性指标   (皮尔逊相关系数、夹角余弦、指数相关系数等)学习

 

2、经常使用的聚类算法idea

  • K-Means划分法
  • 层次聚类法
  • DBSCAN密度法

一、K-Means划分法spa

  K表示聚类算法中类的个数,Means表示均值算法,K-Means便是用均值算法把数据分红K个类的算法。3d

K-Means算法的目标,是把n个样本点划分到k个类中,使得每一个点都属于离它最近的质心(一个类内部全部样本点的均值)对应的类,以之做为聚类的标准。

算法原理见 http://www.aboutyun.com/thread-18178-1-1.html【转】

K-Means算法的计算步骤

  • 取得k个初始质心:从数据中随机抽取k个点做为初始聚类的中心,来表明各个类
  • 把每一个点划分进相应的类:根据欧式距离最小原则,把每一个点划分进距离最近的类中
  • 从新计算质心:根据均值等方法,从新计算每一个类的质心
  • 迭代计算质心:重复第二步和第三步,迭代计算
  • 聚类完成:聚类中心再也不发生移动

基于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')

  method 类距离计算公式有三种参数: 
    single  两个类之间最短距离的点的距离
    complete  两个类之间最长距离的点的距离
    centroid  两个类全部点的中点的距离
#层次聚类绘图
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算法的步骤:

  • 经过检查数据集中每点的Eps邻域来搜索簇,若是点p的Eps邻域内包含的点多于MinPts个,则建立一个以p为核心的簇
  • 经过迭代汇集这些核心点p距离Eps内的点,而后合并成为新的簇(可能)
  • 当没有新点添加到新的簇时,聚类完成

DBSCAN算法优势:

  • 聚类速度快且可以有效处理噪声点发现任意形状的空间聚类
  • 不须要输入要划分的聚类个数
  • 聚类簇的形状没有偏倚
  • 能够在须要是过滤噪声

DBSCAN算法缺点:

  • 数据量大时,须要较大的内存和计算时间
  • 当空间聚类的密度不均匀、聚类间距差较大时,获得的聚类质量较差(MinPts与Eps选取困难)
  • 算法效果依赖距离公式选择,实际应用中常使用欧式距离,对于高纬度数据,存在“维度灾难” https://baike.baidu.com/item/维数灾难/6788619?fr=aladdin

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'])
相关文章
相关标签/搜索