聚类

类别

  • 划分(分裂)算法
    • K-Means算法(K-平均)
    • K-MFDOIDS算法(K-中心)
    • CLARANS算法
  • 层次分析方法
    • BIRCH算法(平衡迭代规约和聚类)
    • CURE算法(点聚类)
  • 基于密度的方法
    • DBSCAN算法(基于高密度连接区域)
    • DENCLUE算法(密度分布函数)

K—Means

简介

  • K-means算法是集简单和经典于一身的基于距离的聚类算法

  • 采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。

  • 该算法认为类簇是由距离靠近的对象组成的,因此把得到紧凑且独立的簇作为最终目标。

核心思想

  • 通过迭代寻找k个类簇的一种划分方案,使得用这k个类簇的均值来代表相应各类样本时所得的总体误差最小。

  • k个聚类具有以下特点:

    • 各聚类本身尽可能的紧凑
    • 各聚类之间尽可能的分开
    • 优点:容易实现
    • 缺点:可能收敛到局部最小值,在大规模数据集上收敛较慢
    • 使用数据类型:数值型数据
  • 算法步骤:

    • 首先我们选择c个类/组,并随机初始化它们各自的中心点。中心点是与每个数据点向量长度相同的位置。这需要我们提前预知类的数量(即中心点的数量)。
    • 计算每个数据点到中心点的距离,数据点距离哪个中心点最近就划分到哪一类中。
    • 计算每一类中中心点作为新的中心点。
    • 重复以上步骤,直到每一类中心在每次迭代后变化不大为止。也可以多次随机初始化中心点,然后选择运行结果最好的一个。

聚类笔记一.(K-means)

代码段

  • 使用sklearn模块
    聚类笔记一.(K-means)
import matplotlib.pyplot as plt  
import numpy as np  
from sklearn.cluster import KMeans
from sklearn import datasets  


iris = datasets.load_iris() 
X = iris.data[:, :2]  # #表示我们取特征空间中的4个维度
print(X.shape)
 
# 绘制数据分布图
plt.scatter(X[:, 0], X[:, 1], c="red", marker='o', label='see')  
plt.xlabel('petal length')  
plt.ylabel('petal width')  
plt.legend(loc=2)  
plt.show()  
 
estimator = KMeans(n_clusters=3)  # 构造聚类器
estimator.fit(X)  # 聚类
label_pred = estimator.labels_  # 获取聚类标签
# 绘制k-means结果
x0 = X[label_pred == 0]
print(x0)
x1 = X[label_pred == 1]
x2 = X[label_pred == 2]
plt.scatter(x0[:, 0], x0[:, 1], c="red", marker='o', label='label0')  
plt.scatter(x1[:, 0], x1[:, 1], c="green", marker='*', label='label1')  
plt.scatter(x2[:, 0], x2[:, 1], c="blue", marker='+', label='label2')  
plt.xlabel('petal length')  
plt.ylabel('petal width')  
plt.legend(loc=2)  
plt.show()

  • 手动计算并显示
    聚类笔记一.(K-means)
import numpy as np
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt 
iris = load_iris()

def dist(x,y):
    # dist: 求样本间的余弦相似度
    return sum(x*y)/(sum(x**2)*sum(y**2))**0.5

def K_means(data=iris.data[:,:2],k=3,ping=0,maxiter=100):
    # k: 类别数
    # maxiter: 最大迭代次数
    n, m = data.shape    # n:样本个数,m:属性个数
    print(n,m)
    centers = data[:k,:] #初始类中心
    while ping < maxiter: #迭代步数
        dis = np.zeros([n,k+1])  #距离矩阵
        for i in range(n):       #求各样本至各类中心的距离
            for j in range(k):
                dis[i,j] = dist(data[i,:],centers[j,:])
            dis[i,k] = dis[i,:k].argmax()
        
        centers_new = np.zeros([k,m])
        for i in range(k):
            # 求新类中心:各类样本均值作为新类中心
            index = dis[:,k]==i
            centers_new[i,:] = np.mean(data[index,:],axis=0)
        
        if np.all(centers==centers_new):
            # 判定类中心是否发生变化
            break
        centers = centers_new #更新类中心
        ping += 1
    print(centers)
    print(ping)
    x0 = []
    x1 = []
    x2 = []
    index0 = dis[:,k]==0
    x0 = data[index0,:]
    index1 = dis[:,k]==1
    x1 = data[index1,:]
    index2 = dis[:,k]==2
    x2 = data[index2,:]

    plt.scatter(x0[:, 0], x0[:, 1], c="red", marker='o', label='label0')  
    plt.scatter(x1[:, 0], x1[:, 1], c="green", marker='*', label='label1')  
    plt.scatter(x2[:, 0], x2[:, 1], c="blue", marker='+', label='label2')  
    plt.xlabel('petal length')  
    plt.ylabel('petal width')  
    plt.legend(loc=2)  
    plt.show()
    return dis
if __name__ == '__main__':
    res = K_means()

相关文章: