当前位置: 首页 > article >正文

指定聚类中心的聚类算法实现

在k-mean聚类算法中,聚类中心是根据数据样本分布自动计算得到的,如果想要自己指定聚类中心,就需要使用改进的kMediod算法。

from numpy import *
import time
import matplotlib.pyplot as plt
import numpy as np
from sklearn.metrics import silhouette_score
from sklearn.cluster import KMeans

"""
参考:https://www.cnblogs.com/yifanrensheng/p/12354910.html#_label2_3
"""
#euclDistance函数计算两个向量之间的欧氏距离
def euclDistance(vector1, vector2):
    return np.sqrt(sum(np.power(vector2 - vector1, 2)))

# initCentroids选取设定点为初始均值点
# dataSet: 数据集, k: 人为设定的聚类簇数目
def initCentroids(dataSet, k):
    numSamples, dim = dataSet.shape
    centroids = np.zeros((k, dim))  #k行dim的0矩阵
    centroids[0, :] = [0.5,0.5]
    centroids[1, :] = [0.5,2.5]
    centroids[2, :] = [2.5,0.5]
    centroids[3, :] = [2.5,2.5]          
   #         print(centroids)
    return centroids
   #定义每个点到其他点的距离和。步骤四的更新簇的均值点时会用到
def costsum( vector1,matrix1):
    sum = 0
    for i in range(matrix1.shape[0]):
        sum += euclDistance(matrix1[i,:], vector1)
    return sum
   # kmediod: k-mediod聚类功能主函数
   # 输入:dataSet-数据集,k-人为设定的聚类簇数目
   # 输出:centroids-k个聚类簇的均值点,clusterAssment-聚类簇中的数据点
def kMediod(dataSet, k):
    numSamples = dataSet.shape[0]
    clusterAssment = np.mat(np.zeros((numSamples, 2)))
    # clusterAssment第一列存储当前点所在的簇
    # clusterAssment第二列存储点与质心点的距离
    clusterChanged = True   #用于遍历的标记
    ## 步骤一: 初始化均值点
    centroids = initCentroids(dataSet, k)
    while clusterChanged:
        clusterChanged = False
        ## 遍历每一个样本点
        for i in range(numSamples):
            minDist  = 100000.0    # minDist:最近距离,初始定一个较大的值
            minIndex = 0       # minIndex:最近的均值点编号
            ## 步骤二: 寻找最近的均值点
            for j in range(k):
                distance = euclDistance(centroids[j, :], dataSet[i, :])  #每个点和中心点的距离,共有k个值
                if distance < minDist:
                    #循环去找最小的那个
                    minDist  = distance
                    minIndex = j
            ## 步骤三: 更新所属簇
            if clusterAssment[i, 0] != minIndex:
                clusterChanged = True
                clusterAssment[i, :] = minIndex, minDist**2  #记录序号和点与质心点的距离
        ## 步骤四: 更新簇核心点
        for j in range(k):
            pointsInCluster = dataSet[np.nonzero(clusterAssment[:, 0] == j)[0]]  #当前属于j类的序号
            mincostsum = costsum(centroids[j,:],pointsInCluster)
            for point in range(pointsInCluster.shape[0]):
                cost = costsum( pointsInCluster[point, :],pointsInCluster)
                if cost < mincostsum:
                    mincostsum = cost
                    centroids[j, :] = pointsInCluster[point, :]
    print ('Congratulations, cluster complete!')
    return centroids, clusterAssment

# showCluster利用pyplot绘图显示聚类结果(二维平面)
# 输入:dataSet-数据集,k-聚类簇数目,centroids-聚类簇的均值点,clusterAssment-聚类簇中数据点
def showCluster(dataSet, k, centroids, clusterAssment):
    numSamples, dim = dataSet.shape
    if dim != 2:
        print ("Sorry, the dimension of your data is not 2!")
        return 1
    mark = ['or', 'ob', 'og', 'ok', '^r', '+r', 'sr', 'dr', '<r', 'pr']
    if k > len(mark):
        return 1
    # 画出所有的样本点
    for i in range(numSamples):
        markIndex = int(clusterAssment[i, 0])
        plt.plot(dataSet[i, 0], dataSet[i, 1], mark[markIndex])
    mark = ['Dr', 'Db', 'Dg', 'Dk', '^b', '+b', 'sb', 'db', '<b', 'pb']
    # 标记簇的质心
    for i in range(k):
        plt.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize = 12)
    plt.show()

  
## step 1: 构造数据
matrix1=np.random.random((12,2))
matrix2=np.random.random((12,2))
matrix3=np.random.random((12,2))
matrix4=np.random.random((12,2))
for i in range(12):
    matrix2[i,0] = matrix2[i,0]+2
    matrix3[i,1] = matrix3[i,1]+2
    matrix4[i,:] = matrix4[i,:]+2
dataSet = np.vstack((matrix1,matrix2,matrix3,matrix4))
# print(dataSet)
## step 2: 开始聚类...
# dataSet = mat(dataSet)
k = 4
centroids, clusterAssment = kMediod(dataSet, k)
#step 3: 显示聚类结果
showCluster(dataSet, k, centroids, clusterAssment)
# 计算轮廓系数
lable = [np.array(row) for row in clusterAssment] 
lable = [row[0] for row in lable] 
lable = [row[0] for row in lable] 

silhouette_avg = silhouette_score(dataSet, lable )
print("轮廓系数:", silhouette_avg)


http://www.kler.cn/a/306676.html

相关文章:

  • JDBC-Dao层模式
  • OLED 显示画面的变换操作——上下、左右翻转
  • 【人工智能】Transformers之Pipeline(二十三):文档视觉问答(document-question-answering)
  • 将 Docker 镜像保存到本地文件系统中
  • 显示器接口种类 | 附图片
  • 图像融合self
  • [Golang] Channel
  • Sourcetree安装教程及使用
  • C8T6超绝模块--DMA
  • 【面向对象】
  • 玄机科技浪漫绘情缘:海神缘下,一吻定情
  • 门检测系统源码分享
  • Java笔记 【1】docker introduction
  • MySQl篇(SQL - 基本介绍)(持续更新迭代)
  • 嵌入式硬件基础知识
  • 微信小程序中巧妙使用 wx:if 和 catchtouchmove 实现弹窗禁止页面滑动功能
  • 安卓玩机工具-----无需root权限 卸载 禁用 删除当前机型app应用 ADB玩机工具
  • 用 defineAsyncComponent 实现高效异步组件加载
  • 使用 SSM 框架编写的解决方案
  • Python应用指南:获取行政区最小外接矩形
  • ubuntu 安装 chrome 及 版本匹配的 chromedriver
  • vue3+vite项目中使用阿里图标库(svg)图标
  • NX CAM二次开发-创建程序组
  • Linux套接字
  • Python Web 开发中的性能优化策略(一)
  • Java多线程面试精讲:源于技术书籍的深度解读