机器学习-->无监督学习-->聚类

本篇博文将详细总结机器学习里面的一个很重要的内容-聚类

聚类定义

定义

聚类就是对大量未知标注 的数据集,按数据 的内在相似性将数据集划分为多个类别,使 类别内的数据相似度较大而类别间的数据相 似度较小。是无监督的分类方式。

聚类思想

给定一个有N个对象的数据集,构造数据的k 个簇,k≤n。满足下列条件:

  • 每一个簇至少包含一个对象
  • 每一个对象属于且仅属于一个簇
  • 将满足上述条件的k个簇称作一个合理划分

基本思想:对于给定的类别数目k,首先给出初始划分,通过迭代改变样本和簇的隶属关系,使得每一次改进之后的划分方案都较前一次好。

聚类与降维

有时候,聚类可以起到降维的效果。在有些领域,降维和聚类是同义词。

例如,有以下数据样本,m个样本,n个特征

这里写图片描述

假定通过聚类,将上面m个样本聚类成3类,然后经过one-hot得:

这里写图片描述

这就相当于对原始数据进行了降维。

相似度度量方式

显然,我们对无标识 的样本进行聚类时,必须有一种衡量样本之间相似度的方法或者是标准,通过这种标准来判断不同样本之间距离的远近,进而来进行聚类。那么有哪些方法可以判断样本之间相似程度或者是距离远近呢?

欧式距离

这里写图片描述

p=1,dist(X,Y)=|x1-x2|+|y1-y2|,这时称为曼哈顿距离。
p=2,dist(X,Y)=||X-Y||的二范式。
p=无穷大呢?这里假定样本特征有三维x,y,z那么p次方的欧式距离为:

这里写图片描述

然后在假定
这里写图片描述

那么可推得:

这里写图片描述

在实际场景中,我们常常选用p=2来定义欧式距离。
sklearn.metrics.silhouette_score

杰卡德相似系数(Jaccard)

这里写图片描述

A,B可以看着两个集合。
杰卡德相似系数常常用于度量推荐系统里面度量商品或者用户的相似度。
skearn中Jaccard系数

余弦相似度(cosine similarity)

这里写图片描述

这里写图片描述

显然对于向量a,b,夹角越小距离越近。夹角越大距离越远。
sklearn.metrics.pairwise.cosine_similarity

Pearson相似系数

这里写图片描述

显然当这里写图片描述时有:
这里写图片描述

这就和余弦相似度等价了。

就是将两个向量当做随机变量来进行比较相似度。
scipy.stat.pearson

相对熵(K-L距离)

这里写图片描述

Hellinger距离

这里写图片描述

k-Means算法

k-Means算法,也被称为k-平均或k-均值,是一种广泛使用的聚类算法, 或者成为其他聚类算法的基础。

k-Means算法步骤

假定输入样本为S=x1,x2,…,xm,则算法步骤为:

  1. 选择初始的k个类别中心μ1μ2…μk
  2. 对于每个样本xi,将其标记为距离类别中心最近的类别,即:
    这里写图片描述
  3. 将每个类别中心更新为隶属该类别的所有样本的均值
    这里写图片描述
  4. 重复最后两步,直到类别中心的变化小于某阈值。

中止条件:迭代次数/簇中心变化率/最小平方误差MSE(Minimum Squared Error)。

k-Means聚类过程

这里写图片描述

k-Means初值敏感性

k-Means将簇中所有点的均值作为新质心, 若簇中含有异常点,将导致均值偏离严重。 以一维数据为例:

  1. 数组1、2、3、4、100的均值为22,显然距离 “大多数”数据1、2、3、4比较远
  2. 改成求数组的中位数3,在该实例中更为稳妥。这种聚类方式即k-Mediods聚类(K中值距离)

初值的选择对聚类结果有着很大的影响,那么如何避免呢?

这里写图片描述

解决方案一:选择较好的聚类初值 :K-Means++算法

不同与K-Means算法随机选择聚类中心,K-Means++算法按距离加权来初始化聚类中心。
假定我们选择k>=2

  1. 首先随机选择第一个聚类中心μ1。
  2. 计算其他样本到第一个聚类中心μ1的距离,分别为[d1,d2,d3,..],d=d1+d2+d3+..。
  3. 设置每一个样本被选为第二个聚类中心μ2的概率分别为[d1/d,d2/d,/d3/d,….]。
  4. 按照概率随机选择其中一个样本为第二个聚类中心μ2。
  5. 计算其他样本分别到第一,第二聚类中心的距离,以其最短距离为准。重复以上步骤3,步骤4,来计算剩余的聚类中心。

这样初始化的各个聚类中心不一定是距离最远(因为是每次是以概率的来选聚类中心),但肯定不近。

解决方案二:多做几回

多做几回k-Means算法,每次随机的选用不同的聚类中心来进行迭代,然后选择聚类效果最好的那次。

k-Means++算法测试
下图为做六次k-Means++,并且每次k值都为7。有六张聚类图可知,每次聚类效果都不一样。因为每次聚类中心的选取不一样。多做几次,选择上述目标函数值最小的,或者根据实际业务选择效果最好的效果图。

这里写图片描述

k-Means的公式化解释

记K个簇中心为 μ1μ2…μk,每个簇的样本数目为N1,N2,N3,….。

使用平方误差作为目标函数:

这里写图片描述

对关于μ1μ2…μk的函数求偏导,其驻点为:
这里写图片描述

用极大似然估计解释目标函数:

这里假定聚类后有三个簇的样本X1,X2,X3,假设这里写图片描述,即均值各不同,但是有着相同的方差。

那么第一个簇的样本概率密度函数为:这里写图片描述

第二个簇的样本概率密度函数为:这里写图片描述

第三个簇的样本概率密度函数为:这里写图片描述

那么似然函数为:
这里写图片描述

对数似然函数为:
这里写图片描述

极大似然函数即是求:

这里写图片描述

和上面的目标函数一致。其实就是MSE。MSE均值最优。

其中μ是估计参数。
以上说明了k-Means算法对样本的分布有要求的,我们认为样本是由k个高斯混合(GMM)得到的,并且认为所有簇的方差是相同的。

Mini-batch k-Means算法

之前求得对关于μ1μ2…μk的函数求偏导,其驻点为:

这里写图片描述

那么需要把所有属于第j个类的Nj个样本求个均值吗?其实我们可以利用SGD思想,每次从第j个类的Nj个样本中随机选取一部分mini-batch样本来求均值来更新μj。

K-Means算法总结

优点:

  • 是解决聚类问题的一种经典算法,简单、快速。
  • 对处理大数据集,该算法保持可伸缩性和高效率。
  • 当簇近似为高斯分布时,它的效果较好。

缺点:

  • 在簇的平均值可被定义的情况下才能使用,可能不适用 于某些应用
  • 必须事先给出k(要生成的簇的数目),而且对初值敏感, 对于不同的初始值,可能会导致不同结果。
  • 不适合于发现非凸形状的簇或者大小差别很大的簇。
  • 对躁声和孤立点数据敏感 。

相关代码

cls = KMeans(n_clusters=4, init='k-means++',n_init=10)## 采样k-means++进行聚类,做10回k-Means算法,每次随机的选用不同的聚类中心来进行迭代,然后选择聚类效果最好的那次。
y_hat = cls.fit_predict(data)

聚类的衡量指标

均一性

  • Homogeneity
  • 一个簇只包含一个类别的样本,则满足均一性。

    这里写图片描述

H(C):在已知样本原始的类别标记,计算其熵值。
H(C|K):在给定聚类结果为第K个簇时,计算其第k个簇内在真实类别标记中的熵值。

完整性

  • Completeness
  • 同类别样本被归类到相同簇中,则满足完整性。

    这里写图片描述

H(K):第k个簇的熵值。
H(K|C):给定某个真实的类别C,计算类别C的样本聚类为不同的簇的熵值。

均一性和完整性类似于precision,recall,两者一高一低或者一低一高,很难同时很好。

V-measure (均一性和完整性的加权平均)

这里写图片描述

ARI

数据集S共有N个元素, 两次 聚类结果分别是X,Y
这里我们假定Y为样本真实的分类标签,X是聚类结果。

这里写图片描述

X和Y的元素个数为:
这里写图片描述

记:
这里写图片描述

这里写图片描述

则有:
这里写图片描述

这里写图片描述

ARI越小,两次聚类结果越相似,反正越不相似。

相关代码实现:

y = [0, 0, 0, 1, 1, 1]
y_hat = [0, 0, 1, 1, 2, 2]
h = metrics.homogeneity_score(y, y_hat)
c = metrics.completeness_score(y, y_hat)
print u'同一性(Homogeneity):', h
print u'完整性(Completeness):', c
v2 = 2 * c * h / (c + h)
v = metrics.v_measure_score(y, y_hat)
print u'V-Measure:', v2, v

y = [0, 0, 1, 1]
y_hat = [0, 1, 0, 1]
ari = metrics.adjusted_rand_score(y, y_hat)
print ari

AMI

使用与ARI相同的记号,根据信息熵,得:
互信息/正则化互信息:

这里写图片描述

X服从超几何分布,求互信息期望:

这里写图片描述

这里写图片描述

轮廓系数(Silhouette)

上面都是在已知样本类别标签的情况下,来对聚类结果进行衡量。那么如果不知道样本的类别标签如何衡量聚类效果呢?

计算样本i到同簇其他样本的平均距离ai。ai越小, 说明样本i越应该被聚类到该簇。将 ai 称为样本i的簇内不相似度

簇C中所有样本的 ai 均值称为簇C的簇不相似度。

计算样本i到其他某簇 Cj 的所有样本的平均距离 bij, 称为样本i与簇Cj的不相似度。定义为样本i的簇间 不相似度这里写图片描述

bi越大,说明样本i越不属于其他簇。

根据样本i的簇内不相似度ai 和簇间不相似度bi,定义样本i的轮廓系数:

这里写图片描述

这里写图片描述

si接近1,则说明样本i聚类合理;si 接近-1,则说明 样本i更应该分类到另外的簇;若si近似为0,则说 明样本i在两个簇的边界上。

所有样本的si的均值称为聚类结果的轮廓系数,是该聚类是否合理、有效的度量。

>>> from sklearn import metrics
>>> from sklearn.metrics import pairwise_distances
>>> from sklearn import datasets
>>> dataset = datasets.load_iris()
>>> X = dataset.data
>>> y = dataset.target
>>>> import numpy as np
>>> from sklearn.cluster import KMeans
>>> kmeans_model = KMeans(n_clusters=3, random_state=1).fit(X)
>>> labels = kmeans_model.labels_
>>> metrics.silhouette_score(X, labels, metric='euclidean')
...                                                      
0.55...

sklearn中更详细的说明请看sklearn.metrics.silhouette_score

层次聚类方法

层次聚类方法对给定的数据集进行层次的分解,直到某种条件满足为止。具体又可分为:

凝聚 的层次聚类:AGNES算法

一种自底向上的策略,首先将每个对象作为一个簇,然 后合并这些原子簇为越来越大的簇,直到某个终结条件 被满足。AGNES (AGglomerative NESting)算法最初将每个对 象作为一个簇,然后这些簇根据某些准则被一步步 地合并。两个簇间的距离由这两个不同簇中距离最 近的数据点对的相似度来确定;聚类的合并过程反 复进行直到所有的对象最终满足簇数目。

分裂 的层次聚类:DIANA算法

采用自顶向下的策略,它首先将所有对象臵于一个簇中, 然后逐渐细分为越来越小的簇,直到达到了某个终结条件。DIANA (DIvisive ANAlysis)算法是上述过程的反过程,属于分裂的层次聚类,首先将所有的对象初始化到一个簇中,然后根据一些原则(比如最大的欧式距离),将该簇分类。直到到达用户指定的簇数目或者两个簇之间的距离超过了某个阈值。

这里写图片描述

上面两种方法,凝聚 的层次聚类使用的较多。

AGNES中簇间距离的不同定义

最小距离 :

  • 两个集合中最近的两个样本的距离。
  • 容易形成链状结构。

最大距离 :

  • 两个集合中最远的两个样本的距离complete。
  • 若存在异常值则不稳定。

平均距离 :

  • 两个集合中样本间两两距离的平均值average。
  • 两个集合中样本间两两距离的平方和ward。

sklearn中凝聚 的层次聚类

from sklearn.cluster import AgglomerativeClustering
ac = AgglomerativeClustering(n_clusters=n_clusters, affinity='euclidean',
                                         connectivity=connectivity, linkage=linkage)
ac.fit(data)
y = ac.labels_

密度聚类方法

密度聚类思想

密度聚类方法的指导思想是,只要样本点的密度 大于某阈值,则将该样本添加到最近的簇中。

这类算法能克服基于距离的算法只能发现“类圆形”(凸)的聚类的缺点,可发现任意形状的聚类, 且对噪声数据不敏感。但计算密度单元的计算复杂度大,需要建立空间索引来降低计算量。

  • DBSCAN
  • 密度最大值算法

DBSCAN算法

DBSCAN(Density-Based Spatial Clustering of Applications with Noise)

一个比较有代表性的基于密度的聚类算法。 与划分和层次聚类方法不同,它将簇定义为密度相连的点的最大集合,能够把具有足够 高密度的区域划分为簇,并可在有“噪声” 的数据中发现任意形状的聚类。

对象的ε-邻域:给定对象在半径ε内的区域。
核心对象:对于给定的数目m,如果一个对象的ε邻域至少包含m个对象,则称该对象为核心对象。
直接密度可达:给定一个对象集合D,如果p是在q 的ε-邻域内,而q是一个核心对象,我们说对象p从对象q出发是直接密度可达的。

如图ε=1cm,m=5,q是一个核 心对象,从对象q出发到对象p是 直接密度可达的。
这里写图片描述

密度可达:如果存在一个对象链 p1p2…pn,这里写图片描述,对 这里写图片描述,(1≤i ≤n),这里写图片描述是从pi关于ε和m直接密度可达 的,则对象p是从对象q关于 ε 和m密度可达的。
这里写图片描述

密度相连:如果对象集合D中存在一个对象o,使得对象p和q 是从o关于ε和m 密度可达 的(即o点可密度可达p点,o点也可密度可达q点),那么对象p和q是关于ε和m密度 相连的。
这里写图片描述

:一个基于密度的簇是最大的密度相连对象的集合
噪声:不包含在任何簇中的对象称为噪声。 (不是核心对象,且不能被其他对象密度可达)

DBSCAN算法流程:

  1. 如果一个点p的ε-邻域包含多于m个对象,则创建一个p作为核心对象的新簇
  2. 寻找并合并核心对象直接密度可达的对象;(判断与p直接密度可达的对象是否是核心对象,如果是,那么合并该核心对象,并继续寻找与该核心对象直接密度可达的对象,不断的重复以上操作。)
  3. 没有新点可以更新簇时,算法结束。

有上述算法可知:

  • 每个簇至少包含一个核心对象;
  • 非核心对象可以是簇的一部分,构成了簇的边缘(edge);
  • 包含过少对象的簇被认为是噪声。
  • 不同于K-Means,DBSCAN不需要事先确定簇的个数。

DBSCAN 代码举例

import numpy as np
import matplotlib.pyplot as plt
import sklearn.datasets as ds
import matplotlib.colors
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler


def expand(a, b):
    d = (b - a) * 0.1
    return a-d, b+d


if __name__ == "__main__":
    N = 1000
    centers = [[1, 2], [-1, -1], [1, -1], [-1, 1]]
    data, y = ds.make_blobs(N, n_features=2, centers=centers, cluster_std=[0.5, 0.25, 0.7, 0.5], random_state=0)
    data = StandardScaler().fit_transform(data)
    # 数据1的参数:(epsilon, min_sample)
    params = ((0.2, 5), (0.2, 10), (0.2, 15), (0.3, 5), (0.3, 10), (0.3, 15))

    # 数据2
    # t = np.arange(0, 2*np.pi, 0.1)
    # data1 = np.vstack((np.cos(t), np.sin(t))).T
    # data2 = np.vstack((2*np.cos(t), 2*np.sin(t))).T
    # data3 = np.vstack((3*np.cos(t), 3*np.sin(t))).T
    # data = np.vstack((data1, data2, data3))
    # # # 数据2的参数:(epsilon, min_sample)
    # params = ((0.5, 3), (0.5, 5), (0.5, 10), (1., 3), (1., 10), (1., 20))

    matplotlib.rcParams['font.sans-serif'] = [u'Droid Sans Fallback']
    matplotlib.rcParams['axes.unicode_minus'] = False

    plt.figure(figsize=(12, 8), facecolor='w')
    plt.suptitle(u'DBSCAN聚类', fontsize=20)

    for i in range(6):
        eps, min_samples = params[i]
        model = DBSCAN(eps=eps, min_samples=min_samples)
        model.fit(data)
        y_hat = model.labels_

        core_indices = np.zeros_like(y_hat, dtype=bool)
        core_indices[model.core_sample_indices_] = True

        y_unique = np.unique(y_hat)
        n_clusters = y_unique.size - (1 if -1 in y_hat else 0)## y_hat=-1为聚类后的噪声类
        print y_unique, '聚类簇的个数为:', n_clusters


        plt.subplot(2, 3, i+1)
        clrs = plt.cm.Spectral(np.linspace(0, 0.8, y_unique.size))##指定聚类后每类的颜色
        print clrs
        for k, clr in zip(y_unique, clrs):
            cur = (y_hat == k)
            if k == -1:
                plt.scatter(data[cur, 0], data[cur, 1], s=20, c='k')
                continue
            plt.scatter(data[cur, 0], data[cur, 1], s=30, c=clr, edgecolors='k')
            #plt.scatter(data[cur & core_indices][:, 0], data[cur & core_indices][:, 1], s=60, c=clr, marker='o', edgecolors='k')
        x1_min, x2_min = np.min(data, axis=0) ## 两列的最小值
        x1_max, x2_max = np.max(data, axis=0)## 两列的最大值
        x1_min, x1_max = expand(x1_min, x1_max)
        x2_min, x2_max = expand(x2_min, x2_max)
        plt.xlim((x1_min, x1_max))
        plt.ylim((x2_min, x2_max))
        plt.grid(True)
        plt.title(ur'$\epsilon$ = %.1f  m = %d,聚类数目:%d' % (eps, min_samples, n_clusters), fontsize=16)
    plt.tight_layout()
    plt.subplots_adjust(top=0.9)
    plt.show()

密度最大值聚类

密度最大值聚类是一种简洁优美的聚类算法, 可以 识别各种形状的类簇, 并且参数很容易确定。

局部密度ρi:
这里写图片描述

dc是一个截断距离, ρi即到对象i的距离小于dc的对象的个 数。由于该算法只对ρi的相对值敏感, 所以对dc的选择是 稳健的,一种推荐做法是选择dc,使得平均每个点的邻 居数为所有点的1%-2%。

局部密度的其他定义:

截断值:
这里写图片描述

高斯核相似度:距离越近,权值越大
这里写图片描述

K近邻均值:
这里写图片描述

高局部密度点距离

定义:假定求得第i个样本的局部密度为这里写图片描述,第1个样本,第二个样本直到第n个样本的局部密度分别为:这里写图片描述,找出其局部密度大于这里写图片描述的所有样本 j,然后再求出第i个样本到第j个样本的距离这里写图片描述,选出最小的那个这里写图片描述作为样本i的高局部密度点距离这里写图片描述

即是:在密度高于对象i的所有对象中,到对象i最近的距离,即高局部密度点距离。

这里写图片描述

对于密度最大的对象,设置δi=max(dij)(即:该问题中的无穷大)。
只有那些密度是局部或者全局最大的点才会有远 大于正常值的高局部密度点距离。

簇中心的识别

由上面可以分析得:

  • 这里写图片描述比较大,这里写图片描述也比较大,那么第i的样本对象可能是一个簇的中心。
  • 这里写图片描述比较小,这里写图片描述比较大,那么第i的样本对象可能是噪声。
  • 这里写图片描述比较大,这里写图片描述比较小,那么第i的样本是一个簇里面很普通的样本。

那些有着比较大的局部密度ρi和很大的高密 距离δi的点被认为是簇的中心;
高密距离δi较大但局部密度ρi较小的点是异 常点;
确定簇中心之后,其他点按照距离已知簇的中心最近进行分类 。

这里写图片描述

谱和谱聚类

定义

方阵作为线性算子,它的所有特征值 的全体,统称方阵的

  • 方阵 的谱半径为最大的特征值。
  • 矩阵 A的谱半径:(ATA)的最大特征值。

谱聚类是一种基于图论的聚类方法,通过对样本数据的拉普拉斯矩阵的特征向量 进行聚类,从而达到对样本数据聚类的目的。

谱分析的整体过程

给定一组数据x1,x2,…xn,记任意两个点之间 的相似度 (―距离”的减函数,如高斯相似度度量方式 )为sij= < xi,xj >,形成相似度图(similarity graph):G=(V,E) 。这里把sii(即对角线上)全部设为0。这样就得出了邻接矩阵。

  1. 无向图G=(V,E)
  2. 邻接矩阵

    这里写图片描述
    高斯相似度:
    这里写图片描述
    其中这里写图片描述是超参数,事先给定的。

  3. 顶点的度di–>度矩阵D (对角阵)。(邻接矩阵中第i行数据求和即为第i个样本的度di,形成的矩阵D对角线上每个元素即为d1,d2,…,dn,其余位置全为0)
    这里写图片描述

未正则的拉普拉斯矩阵:

L = D – W

这里写图片描述

L是对称半正定矩阵,最小特征值是0,相应的特征向量是全1向量。

算法步骤:

  1. 输入:n个点{pi},簇的数目k
  2. 计算n×n的相似度矩阵W和度矩阵D;
  3. 计算拉普拉斯矩阵L=D-W;
  4. 计算L的前k个特征向量u1,u2,…,uk,对应的特征值分别为 这里写图片描述如果定义的L=D-W,特征值是从小到大排序的
  5. 将k个列向量u1,u2,…,uk组成矩阵U,U∈Rn×k;
  6. 对于i=1,2,…,n,令yi∈Rk是U的第i行的向量;
  7. 使用k-means算法将点(yi)i=1,2,…,n聚类成簇 C1,C2,…Ck;
  8. 输出簇A1,A2,…Ak,其中,Ai={j|yj∈Ci}

个人感觉就是对拉普拉斯矩阵L做主成分分析,然后做K-Means。

正则拉普拉斯矩阵

对称拉普拉斯矩阵
这里写图片描述

算法步骤:

  1. 输入:n个点{pi},簇的数目k
  2. 计算n×n的相似度矩阵W和度矩阵D;
  3. 计算正则拉普拉斯矩阵 这里写图片描述
  4. 计算Lsym的前k个特征向量u1,u2,…,uk;
  5. 将k个列向量u1,u2,…,uk组成矩阵U,U∈Rn×k,对应的特征值分别为 这里写图片描述特征值是从小到大排序的
  6. 对于i=1,2,…,n,令yi∈Rk是U的第i行的向量;
  7. 对于i=1,2,…,n,将yi∈Rk依次单位化,使得|yi|=1;(单位化)
  8. 使用k-means算法将点(yi)i=1,2,…,n聚类成簇C1,C2,…Ck;
  9. 输出簇A1,A2,…Ak,其中,Ai={j|yj∈Ci} 。

随机游走拉普拉斯矩阵:

图论中的随机游走是一个随机过程,它从一 个顶点跳转到另外一个顶点。谱聚类即找到 图的一个划分,使得随机游走在相同的簇中 停留而几乎不会游走到其他簇。

这里写图片描述

算法步骤:

  1. 输入:n个点{pi},簇的数目k
  2. 计算n×n的相似度矩阵W和度矩阵D;
  3. 计算正则拉普拉斯矩阵这里写图片描述
  4. 计算Lrw的前k个特征向量u1,u2,…,uk,对应的特征值分别为 这里写图片描述特征值是从小到大排序的;;
  5. 将k个列向量u1,u2,…,uk组成矩阵U,U∈ Rn×k ;
  6. 对于i=1,2,…,n,令yi∈Rk是U的第i行的向量;
  7. 使用k-means算法将点(yi)i=1,2,…,n聚类成簇 C1,C2,…Ck ;
  8. 输出簇A1,A2,…Ak,其中,Ai={j|yj∈Ci}

上面三个拉普拉斯矩阵,在没有先验知识情况下,优先选择随机游走拉普拉斯矩阵。

谱聚类中的K如何确定? 将拉普拉斯矩阵的特征值从小到大排序,选择相邻特征值差值最大的索引。
这里写图片描述

谱聚类代码举例

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
from sklearn.cluster import spectral_clustering
from sklearn.metrics import euclidean_distances


def expand(a, b):
    d = (b - a) * 0.1
    return a-d, b+d


if __name__ == "__main__":
    matplotlib.rcParams['font.sans-serif'] = [u'Droid Sans Fallback']
    matplotlib.rcParams['axes.unicode_minus'] = False

    t = np.arange(0, 2*np.pi, 0.1)
    data1 = np.vstack((np.cos(t), np.sin(t))).T ##在行上做连接堆积,相当与np.concatenate(tup,axis=0)
    data2 = np.vstack((2*np.cos(t), 2*np.sin(t))).T
    data3 = np.vstack((3*np.cos(t), 3*np.sin(t))).T
    data = np.vstack((data1, data2, data3))

    n_clusters = 3
    m = euclidean_distances(data, squared=True) ##计算两两样本之间的欧式距离
    print "m",m.shape


    plt.figure(figsize=(12, 8), facecolor='w')
    plt.suptitle(u'谱聚类', fontsize=20)
    clrs = plt.cm.Spectral(np.linspace(0, 0.8, n_clusters))##指定聚类后每类的颜色
    for i, s in enumerate(np.logspace(-2, 0, 6)):
        print s
        af = np.exp(-m ** 2 / (s ** 2)) + 1e-6 ##利用data中两两样本距离,计算两两样本的高斯相似度,其中s为超参数sigma
        y_hat = spectral_clustering(af, n_clusters=n_clusters, assign_labels='kmeans', random_state=1)#谱聚类以后每个样本所属的簇
        plt.subplot(2, 3, i+1)
        for k, clr in enumerate(clrs):
            cur = (y_hat == k)
            plt.scatter(data[cur, 0], data[cur, 1], s=40, c=clr, edgecolors='k')
        x1_min, x2_min = np.min(data, axis=0)
        x1_max, x2_max = np.max(data, axis=0)
        x1_min, x1_max = expand(x1_min, x1_max)
        x2_min, x2_max = expand(x2_min, x2_max)
        plt.xlim((x1_min, x1_max))
        plt.ylim((x2_min, x2_max))
        plt.grid(True)
        plt.title(ur'$\sigma$ = %.2f' % s, fontsize=16)
    plt.tight_layout()
    plt.subplots_adjust(top=0.9)
    plt.show()

标签传递算法

对于部分样本的标记给定,而大多数样本的 标记未知的情形,是半监督学习问题。

标签传递算法(Label Propagation Algorithm,LPA),将标记样本的标记通过一定的概率传递给未标记样本,直到最终收敛。

即在一批无标记的样本中随机选取一部分样本进行标记,然后根据样本之间的相似度,进行概率化的传递,给其他无标记的样本自动打上标记。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值