AIGC背后的技术分析 | K均值聚类算法Python实现

简介: 本篇介绍K均值聚类算法实现。

640.jpg

01、算法说明

K均值聚类算法是一种简单的迭代型聚类算法,采用距离作为相似性指标,从而发现给定数据集中的K个类,且每个类有一个聚类中心,即质心,每个类的质心是根据类中所有值的均值得到。对于给定的一个包含n个d维数据点的数据集X以及要分得的类别K,选取欧式距离作为相似度指标。聚类目标是使得各类的聚类平方和最小,即最小化:

640.jpg


K-means是一个反复迭代的过程,算法分为四个步骤:

(1)选取数据空间中的K个对象作为初始中心,每个对象代表一个聚类中心;

(2)对于样本中的数据对象,根据它们与这些聚类中心的欧氏距离,按距离最近的准则将它们分到距离它们最近的聚类中心(最相似)所对应的类;
(3)更新聚类中心:将每个类别中所有对象所对应的均值作为该类别新的聚类中心,计算目标函数的值;
(4)判断聚类中心和目标函数的值是否发生改变,若不变,则输出结果,若改变,则返回步骤(2)。

02、程序实现

以下是K均值法的python代码实现。程序使用的工具包括numpy和matplotlib,其中numpy是一个用于处理多维数组的库,而Matplotlib 则用于绘制二维图形。

# -*- coding: UTF-8-*-
import numpy   #用于处理多维数组的库import random  #用于生成初始质心
import codecs   #用于读取数据集文本并且解码import re      #利用正则表达式来整理输入数据的格式import matplotlib.pyplot as plt #绘制二维图形的库


# 计算向量vec1和向量vec2之间的欧氏距离def calcuDistance(vec1, vec2):
    return numpy.sqrt(numpy.sum(numpy.square(vec1- vec2)))

def loadDataSet(inFile):
    # 载入数据测试数据集
    # 数据由文本保存,为二维坐标
    inDate = codecs.open(inFile, 'r', 'utf-8').readlines()
    dataSet = list()
    for line in inDate:
        line = line.strip()    #  

        strList = re.split('[ ]+', line)  # 去除多余的空格
        # print strList[0], strList[1]
        numList = list()
        for item in strList:
            num = float(item)
            numList.append(num)
        # print numList
            dataSet.append(numList)

    return dataSet  #dataSet = [[], [], [], ...]

# 初始化k个质心,随机获取
def initCentroids(dataSet, k):
    return random.sample(dataSet,k)  # 从dataSet中随机获取k个数据项返回


def minDistance(dataSet, centroidList):
    # 对每个属于dataSet的item,计算item与centroidList中k个质心的欧式距离,找出距离最小的,
    # 并将item加入相应的簇类中
    clusterDict = dict() # 用dict来保存簇类结果
    for item in dataSet:
        vec1 = numpy.array(item)  #转换成array形式
        flag = 0  # 簇分类标记,记录与相应簇距离最近的那个簇
        minDis = float("inf")  # 初始化为最大值

        for i in range(len(centroidList)):
            vec2 =numpy.array(centroidList[i])
            distance =calcuDistance(vec1, vec2)  # 计算相应的欧式距离
            if distance < minDis:
                minDis = distance
                flag = i  #循环结束时,flag保存的是与当前item距离最近的那个簇标记
            if flag not in clusterDict.keys():  #簇标记不存在,进行初始化
               clusterDict[flag] = list()
        # print flag, item
             clusterDict[flag].append(item)  #加入相应的类别中
    return clusterDict  # 返回新的聚类结果


# 得到k个质心
def getCentroids(clusterDict):
    centroidList = list()
    for key in clusterDict.keys():
        centroid =numpy.mean(numpy.array(clusterDict[key]), axis=0)  #计算每列的均值,即找到质心
        # print key, centroid
        centroidList.append(centroid)

    return numpy.array(centroidList).tolist()

def getVar(clusterDict, centroidList):
    # 计算簇集合间的均方误差
    # 将簇类中各个向量与质心的距离进行累加求和
    sum = 0.0
    for key in clusterDict.keys():
        vec1 =numpy.array(centroidList[key])
        distance = 0.0
        for item in clusterDict[key]:
            vec2 = numpy.array(item)
            distance +=calcuDistance(vec1, vec2)
        sum += distance
    return sum

# 展示聚类结果def showCluster(centroidList, clusterDict):
    colorMark = ['or', 'ob', 'og', 'ok', 'oy', 'ow']  # 不同簇类的标记 'or' --> 'o'代表圆,'r'代表red,'b':blue
    centroidMark = ['dr', 'db', 'dg', 'dk', 'dy', 'dw']  # 质心标记 同上'd'代表棱形
    for key in clusterDict.keys():
        plt.plot(centroidList[key][0],centroidList[key][1], centroidMark[key], markersize=12)  # 画质心点
        for item in clusterDict[key]:
            plt.plot(item[0],item[1],colorMark[key])  # 画簇类下的点
    plt.show()

if __name__ == '__main__':

    inFile = "D:\Python\practice\kmean.txt"  # 数据集文件
    dataSet = loadDataSet(inFile)  #载入数据集
    centroidList = initCentroids(dataSet, 3)  #初始化质心,设置k=3
    clusterDict = minDistance(dataSet,centroidList)  # 第一次聚类迭代
    newVar = getVar(clusterDict, centroidList)  #获得均方误差值,通过新旧均方误差来获得迭代终止条件
    oldVar = -0.0001  #开始时均方误差值初始化为-0.0001
    print('***** 第1次迭代 *****')
    print()
    print('簇类')
    for key in clusterDict.keys():
        print(key, ' --> ', clusterDict[key])
    print('k个均值向量: ',centroidList)
    print('平均均方误差: ',newVar)
    print(showCluster(centroidList,clusterDict))  # 展示聚类结果

    j = 2  #
    while abs(newVar- oldVar) >= 0.0001:  # 当连续两次聚类结果小于0.0001时,迭代结束
        centroidList = getCentroids(clusterDict)  #获得新的质心
        clusterDict = minDistance(dataSet,centroidList)  # 新的聚类结果
        oldVar = newVar
        newVar = getVar(clusterDict,centroidList)

        print('***** 第%d次迭代 *****' % j)
        print()
        print('簇类')
        for key in clusterDict.keys():
            print(key, ' --> ', clusterDict[key])
        print('k个均值向量: ',centroidList)
        print('平均均方误差: ',newVar)

        print(showCluster(centroidList,clusterDict))         # 展示聚类结果

        j += 1

03、数据验证

现在假设有9个坐标点数据,它们分别是(3,2)、(3,9)(8,6)(9,5)(2,4)(3,10)(2,5)(9,6)(2,2)。利用上面的程序来计算它的簇,设定在计算开始时随机选择三个点作为初始质心,并且要求聚类结果必须小于0.0001。

程序运行的字符界面输出的结果如下图1和图2所示。

640.jpg


▍图1 程序运行的字符界面输出的结果


640.jpg


▍图2 程序运行的字符界面输出的结果(续)

程序调用python的绘图包输出图形界面的结果如下图3、图4和图5所示。从这几个图中可以看到簇类和簇心的变化。
图3展示的迭代开始时,随机选择的簇心。

640.jpg


▍图3 第一次迭代,随机选择的簇心

图4展示第二次迭代后,簇心发生变化,平均均方误差减小(从图2可以看出)。

640.jpg


▍图4 第二次迭代后,簇心发生的变化

图5展示第三次迭代后,簇心进一步发生变化,平均均方误差更小(从图2可以看出)。

640.jpg


▍图5 第三次迭代后,簇心进一步发生变化

从图2可以看出,第4次迭代与第三次迭代的结果是相同的,因此迭代4次后,程序终止执行。

04、程序说明

(1)在计算机安装了python之后,还需要安装numpy和matplotlib。这两个工具包分别是帮助进行科学运算并且根据计算结果绘制图的。
(2)安装完成后,可以根据实际情况改变数据集文件的地址,数据集是由loadDataSet这个函数进行数据的加载和整理的。本程序中main函数部分的语句:
dataset=loadDataSet(inFile)
就是完成这个功能。
(3)数据集加载完成后,由函数initCentroids来进行质心的初始化。在本程序中,使用了random函数来从数据集中随机抽取若干个质心,而质心的数量可以由第二个参数来设定。本程序设定的质心数量为3个。
(4)整理好的数据集和随机选取的质心会作为参数,交给函数minDistance进行聚类迭代计算。在这个计算里面,使用了定义的calcuDistance函数来计算点到点之间的欧式距离。
(5)最后利用上一步的结果,使用函数getVar来计算簇集合间的均方误差。
(6)控制迭代结束的条件是,在main函数中利用两次聚类的结果只差小于0.0001。

目录
相关文章
|
3天前
|
算法 数据安全/隐私保护 开发者
马特赛特旋转算法:Python的随机模块背后的力量
马特赛特旋转算法是Python `random`模块的核心,由松本真和西村拓士于1997年提出。它基于线性反馈移位寄存器,具有超长周期和高维均匀性,适用于模拟、密码学等领域。Python中通过设置种子值初始化状态数组,经状态更新和输出提取生成随机数,代码简单高效。
|
18天前
|
人工智能 自然语言处理 数据可视化
什么是AIGC?如何使用AIGC技术辅助办公?
2分钟了解AIGC技术及其如何提高日常办公效率!
58 4
什么是AIGC?如何使用AIGC技术辅助办公?
|
18天前
|
算法 数据挖掘 数据安全/隐私保护
基于FCM模糊聚类算法的图像分割matlab仿真
本项目展示了基于模糊C均值(FCM)算法的图像分割技术。算法运行效果良好,无水印。使用MATLAB 2022a开发,提供完整代码及中文注释,附带操作步骤视频。FCM算法通过隶属度矩阵和聚类中心矩阵实现图像分割,适用于灰度和彩色图像,广泛应用于医学影像、遥感图像等领域。
|
13天前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
垃圾识别分类系统。本系统采用Python作为主要编程语言,通过收集了5种常见的垃圾数据集('塑料', '玻璃', '纸张', '纸板', '金属'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对图像数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。然后使用Django搭建Web网页端可视化操作界面,实现用户在网页端上传一张垃圾图片识别其名称。
48 0
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
|
13天前
|
机器学习/深度学习 人工智能 算法
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
手写数字识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Flask框架,开发网页端操作平台,实现用户上传一张图片识别其名称。
49 0
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
|
13天前
|
机器学习/深度学习 人工智能 算法
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
蔬菜识别系统,本系统使用Python作为主要编程语言,通过收集了8种常见的蔬菜图像数据集('土豆', '大白菜', '大葱', '莲藕', '菠菜', '西红柿', '韭菜', '黄瓜'),然后基于TensorFlow搭建卷积神经网络算法模型,通过多轮迭代训练最后得到一个识别精度较高的模型文件。在使用Django开发web网页端操作界面,实现用户上传一张蔬菜图片识别其名称。
55 0
基于深度学习的【蔬菜识别】系统实现~Python+人工智能+TensorFlow+算法模型
|
18天前
|
算法 Python
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果;贪心算法在每一步选择局部最优解,追求全局最优;动态规划通过保存子问题的解,避免重复计算,确保全局最优。这三种算法各具特色,适用于不同类型的问题,合理选择能显著提升编程效率。
32 2
|
19天前
|
算法 Python
Python图论探索:从理论到实践,DFS与BFS遍历技巧让你秒变技术大牛
图论在数据结构与算法中占据重要地位,应用广泛。本文通过Python代码实现深度优先搜索(DFS)和广度优先搜索(BFS),帮助读者掌握图的遍历技巧。DFS沿路径深入搜索,BFS逐层向外扩展,两者各具优势。掌握这些技巧,为解决复杂问题打下坚实基础。
29 2
|
21天前
|
开发框架 开发者 Python
探索Python中的装饰器:技术感悟与实践
【10月更文挑战第31天】 在编程世界中,装饰器是Python中一种强大的工具,它允许我们在不修改函数代码的情况下增强函数的功能。本文将通过浅显易懂的方式,带你了解装饰器的概念、实现原理及其在实际开发中的应用。我们将一起探索如何利用装饰器简化代码、提高可读性和复用性,同时也会分享一些个人的技术感悟,帮助你更好地掌握这项技术。
32 2
|
25天前
|
数据采集 Web App开发 iOS开发
如何利用 Python 的爬虫技术获取淘宝天猫商品的价格信息?
本文介绍了使用 Python 爬虫技术获取淘宝天猫商品价格信息的两种方法。方法一使用 Selenium 模拟浏览器操作,通过定位页面元素获取价格;方法二使用 Requests 和正则表达式直接请求页面内容并提取价格。每种方法都有详细步骤和代码示例,但需注意反爬措施和法律法规。
下一篇
无影云桌面