sklearn中聚类(部分)

下图为主要介绍的几个聚类方法:

1、 k均值(K-means

在指定n个类别后,最小化类别中样本到类别均值样本的距离,公式如下:


其中,Ci为划分,ui为每个划分的均值向量,k=nK-均值是相当于一个小、 全等、 对角协方差矩阵的期望最大化算法。

该方法有以下缺点:

  • 有个前提:集群是凸和各向同性的。对长条形、流行以及不规则形的集群响应不好。
  • 惯性不是归一化的度量:仅仅知道值越低越好。但是在高维空间中,欧几里得距离会有所变化。因此在使用k均值方法前,可以利用PCA算法对数据降维,不仅可缓解这一问题,而且还可以加快计算。

▲k均值的算法如下:(参考周志华老师的《机器学习》:203

***********************************************************

输入:样本集D={x1x2x3xm}

              聚类簇数:k

过程:

              D中随机选择k个样本{u1u2u3uk}

              repeat

                   Ci={}1<=i<=k

              计算每个样本到{u1u2u3uk}的距离,将距离最近的加入对应的集合中

                  计算对应集合的均值向量

                  更新随机选择的k个样本

             until 当前均值样本向量均未更新

输出:划分

***********************************************************

理论上k-均值总会收敛(可能收敛于一个局部最小值),这依赖于初始化的质心。因此k-均值算法常常会以不同初始化的质心计算几次。在sklearn中可设置init=kmeans++解决这一问题。

▲n_jobs参数可以实现并行处理。通常需要计算机有多的处理器,当n_jobs=-1时,表示使用全部的处理器,-2时减少一个,以此类推。处理器使用的越多内存消耗越大。

下面的例子为:k均值算法在不同数据集上的表现,其中前三个为输入数据不符合前提假设,最后一个为每个集群大小不应的情况。如下图:


相关代码如下:

# -*- coding: utf-8 -*-
"""
Created on Wed Feb  8 14:15:41 2017

@author: ZQ
"""
import numpy as np
import matplotlib.pyplot as plt

from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs

plt.figure(figsize=(12,12))

n_samples = 1500
random_state = 170
X,y = make_blobs(n_samples=n_samples,random_state=random_state)

#第一幅图,不正确的聚类参数
y_pred = KMeans(n_clusters=2,random_state=random_state).fit_predict(X)
plt.subplot(221)
plt.scatter(X[:,0],X[:,1],c=y_pred)
plt.title("Incorrect Number of Blobs")

#各向异性数据
transformation = [[0.60834549,-0.63667341],[-0.40887718,0.85253229]]
X_aniso = np.dot(X,transformation)
y_pred = KMeans(n_clusters=3,random_state=random_state).fit_predict(X_aniso)
plt.subplot(222)
plt.scatter(X_aniso[:,0],X_aniso[:,1],c=y_pred)
plt.title("Anisotropicly Distributed Blobs")

#不同方差
X_varied,y_varied = make_blobs(n_samples=n_samples,
                               cluster_std=[1.0,2.5,0.5],
                               random_state=random_state)
y_pred = KMeans(n_clusters=3,random_state=random_state).fit_predict(X_varied)

plt.subplot(223)
plt.scatter(X_varied[:,0],X_varied[:,1],c=y_pred)
plt.title("Unequal Variance")
#不同大小的聚类,选取标签为0的500个。。。。
X_filtered = np.vstack((X[y==0][:500],X[y==1][:100],X[y==2][:10]))
y_pred = KMeans(n_clusters=3,random_state=random_state).fit_predict(X_filtered)
plt.subplot(224)
plt.scatter(X_filtered[:,0],X_filtered[:,1],c=y_pred)
plt.title("Unevenly Sized Blobs")
plt.show()

1.1、Mini Batch K-Means

MiniBatchKMeansk均值算法的变种,可减少收敛时间,但是其结果与标准的k均值算法较差。每次迭代中选取的数据集为原始数据集的子集。

该算法主要分为两步:

  • 在原始数据集中选取b个样本作为小批量,并将其分配到最近的质心(质心的选取不太清楚,有两种可能,1随机在样本集中选取,2在小批量中选取。不清楚)
  • 更新质心

虽然说MiniBatchKmeans不如标准的K均值算法,但是其差异很小,如下例子:相关代码可查询http://scikit-learn.org/stable/auto_examples/cluster/plot_mini_batch_kmeans.html

2、 层次聚类(Hierarchical clustering

该聚类算法试图在不同层次对数据集进行划分,从而形成树形的聚类结构。划分方法可采用自上而下和自下而上的方法。


AgglomerativeClustering采用自下而上的方法。首先将每个样本作为一个类,然后按照距离度量的方法将其合并到需要的聚类数。根据距离度量方法可分为:Ward方差和最小(距离最小)、complete聚类中最大或最小距离、average平均距离。

下面的例子说明了这三个方法的优缺点,该聚类方法具有一定的富集性,选择其中的average较好。如下图:http://scikit-learn.org/stable/auto_examples/cluster/plot_digits_linkage.html


3、DBSCAN

该算法通过样本的紧密程度来确定样本的分布,该算法可适用于集群在任何形状的情况下。DBSCAN算法中一个重要的概念为核心样本(具有较高的紧密度)。该算法有两个参数min_sampleseps,高min_samples或者低eps代表着在形成聚类时,需要较高的紧密度。

该算法简单的描述:先任意选择数据集中的一个核心对象为种子,在由此出发确定相应的聚类簇,在根据给定的领域参数(min_sampleseps)找出所有核心对象,在以任意一个核心对象出发,找出由其密度可达的样本生产聚类簇,直到所有核心对象均被访问为止。(更多参考周志华老师《机器学习》P212

下图为一个例子:使用DBSCAN算法,大圈为找到了核心样本,带颜色的小点位非核心样本,黑色的为异常值。


相关代码:
# -*- coding: utf-8 -*-
"""
Created on Sun Feb 12 10:49:05 2017

@author: ZQ
"""

import numpy as np
import matplotlib.pyplot as plt

from sklearn.cluster import DBSCAN
from sklearn import metrics
from sklearn.datasets.samples_generator import make_blobs
from sklearn.preprocessing import StandardScaler

#生产数据
centers = [[1,1],[-1,-1],[1,-1]]
X,labels_true = make_blobs(n_samples=750,
                           centers=centers,
                           cluster_std=0.4,
                           random_state=0)
#对数据进行标准化
X = StandardScaler().fit_transform(X)

#计算
db = DBSCAN(eps=0.3,min_samples=10).fit(X)
core_samples_mask = np.zeros_like(db.labels_,dtype=bool)
core_samples_mask[db.core_sample_indices_] = True
labels = db.labels_

n_clusters_ = len(set(labels))-(1 if -1 in labels else 0)

unique_labels = set(labels)
colors = plt.cm.Spectral(np.linspace(0,1,len(unique_labels)))
for k,col in zip(unique_labels,colors):
    if k == -1:
        col = 'k'
    class_member_mask = (labels == k)
    xy = X[class_member_mask & core_samples_mask]
    plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=col,
             markeredgecolor='k', markersize=14)

    xy = X[class_member_mask & ~core_samples_mask]
    plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=col,
             markeredgecolor='k', markersize=6)

plt.title('Estimated number of clusters: %d' % n_clusters_)
plt.show()

补充:用聚类进行图像分割


相关代码:
# -*- coding: utf-8 -*-
"""
Created on Sat Feb 11 11:37:03 2017

@author: ZQ
"""

import time
import scipy as sp
import numpy as np
import matplotlib.pyplot as plt

from sklearn.feature_extraction import image
from sklearn.cluster import spectral_clustering
from sklearn.utils.testing import SkipTest
from sklearn.utils.fixes import sp_version

if sp_version < (0,12):
    raise SkipTest("Skipping because SciPy version earlier than 0.12.0 and "
                   "thus does not include the scipy.misc.face() image.")
face = sp.misc.face(gray=True)

#减小集合
face = sp.misc.imresize(face,0.10)/255

graph = image.img_to_graph(face)

#参数beta越小,分割越独立
beta = 5
eps = 1e-6
graph.data = np.exp(-beta*graph.data/graph.data.std())+eps

N_REGIONS = 25
for assign_labels in ('kmeans','discretize'):
    t0 = time.time()
    labels = spectral_clustering(graph,n_clusters=N_REGIONS,
                                 assign_labels=assign_labels,random_state=1)
    t1 = time.time()
    labels = labels.reshape(face.shape)
    
    plt.figure(figsize=(5,5))
    plt.imshow(face,cmap=plt.cm.gray)
    for l in range(N_REGIONS):
        plt.contour(labels==l,contours=1,
                    colors = [plt.cm.spectral(l/float(N_REGIONS))])
    plt.xticks(())
    plt.yticks(())
    title = 'Spectral clustering: %s, %.2fs' % (assign_labels,(t1-t0))
    print(title)
    plt.title(title)
plt.show()


  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值