找回密码
 立即注册
搜索

数据发掘——聚类分析总结(建议收藏)

聚类分析

一、概念

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

聚类分析属于无监督学习

聚类对象可以分为Q型聚类和R型聚类

Q型聚类:样本/记录聚类 间隔为相似性目的 (欧氏间隔、欧氏平方间隔、马氏间隔、明式间隔等)

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

二、常用的聚类算法
    K-Means划分法层次聚类法DBSCAN密度法

1、K-Means划分法

K表示聚类算法中类的个数,Means表示均值算法,K-Means即是用均值算法把数据分成K个类的算法。

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)

2、 层次聚类法

层次聚类算法又称为树聚类算法,它根据数据之间的间隔,透过一种层次架构方式,反复将数据停止聚合,创建一个层次以分解给定的数据集。层次聚类算法常用于一维数据的自动分组。

层次聚类算法是一种很直观的聚类算法,基本思想是经过数据间的相似性,按相似性由高到低排序后重新衔接各个节点,整个过程就是建立一个树结构,如下图:

层次聚类算法的步骤:
    每个数据点单独作为一个类计算各点之间的间隔(相似度)按照间隔从小到大(相似度从强到弱)衔接成对(衔接后按两点的均值作为新类继续计算),得到树结构

基于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) #绘制图形

3、 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(rowMinPts:    #核心点,密度大于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 = numpy.where(row0 and i!=j:
            cluster = list(set(cluster) | set(cluster[j]))
            cluster[j] = list()
最后,找出独立(也就是没有交集)的邻域,就是我们最后的聚类的结果了
result = dict()
j = 0
for i in range(len(cluster)):
  if len(cluster)>0:
    result[j] = cluster
    j = j + 1

#找出每个点所在范畴的序号,作为他们最后聚类的结果标记
for i in range(len(result)):
    for j in result:
        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'])
end.

来源:博客园

关注我们吧,查看更多干货文章,视频。回复“数据”还有数据分析相关材料支付,每周更有收费直播课,有成绩也可私信咨询小编哦!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

大神点评4

小仙子哒 2020-3-12 09:04:44 显示全部楼层
分享了
回复

使用道具 举报

妹抖骑士囧方 2020-3-12 20:58:39 来自手机 显示全部楼层
厉害啊!
回复

使用道具 举报

飘雪寒月 2020-3-13 19:26:39 显示全部楼层
为了三千积分!
回复

使用道具 举报

梦恋米兰 2020-3-14 21:41:42 显示全部楼层
元芳你怎么看?
回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies