《机器学习实战》之K-均值聚类算法的python实现

《机器学习实战》之K-均值聚类算法的python实现

最近的项目是关于“基于数据挖掘的电路故障分析”,项目基本上都是师兄们在做,我只是在研究关于项目中用到的如下几种算法:二分均值聚类、最近邻分类、基于规则的分类器以及支持向量机。基于项目的保密性(其实也没有什么保密的,但是怕以后老板看到我写的这篇博文,所以,你懂的),这里就不介绍“基于数据挖掘的电路故障分析”的思路了。

废话不多说了,开始正题哈。

基本K-均值聚类算法

基本K均值算法的基本思路为:首先选择K个初始质心(集合中所有点度量值的均值), K值为期望得到簇的个数,大小由用户指定;将每个点指派到最近的质心,点与点之间的距离通过两点对应的度量值差的绝对值进行度量,然后根据指派到簇的点,更新每个簇的质心,重复指派和更新,直到簇不再发生变化,或者满足终止条件。

其伪代码如下:

创建k个点作为初始的质心点(随机选择)

当任意一个点的簇分配结果发生改变时

对数据集中的每一个数据点

对每一个质心

计算质心与数据点的距离

将数据点分配到距离最近的簇

对每一个簇,计算簇中所有点的均值,并将均值作为质心

python实现代码如下:注释基本上写的相当相当详细,由于自己还是python的初学者,觉得注释过多不方便看,还请大家谅解,有错误希望大家指正。

用到的库有numpymatplotlib,直接通过如下命令安装即可。

pip install numpy

pip install matplotlib

KMeans.py文件

from numpy import *
import time
import matplotlib.pyplot as plt  

# calculate Euclidean distance
def euclDistance(vector1, vector2):
    return sqrt(sum(power(vector2 - vector1, 2)))  #求这两个矩阵的距离,vector1、2均为矩阵

# init centroids with random samples
#在样本集中随机选取k个样本点作为初始质心
def initCentroids(dataSet, k):
    numSamples, dim = dataSet.shape   #矩阵的行数、列数
    centroids = zeros((k, dim))         #感觉要不要你都可以
    for i in range(k):
        index = int(random.uniform(0, numSamples))  #随机产生一个浮点数,然后将其转化为int型
        centroids[i, :] = dataSet[index, :]
    return centroids  

# k-means cluster
#dataSet为一个矩阵
#k为将dataSet矩阵中的样本分成k个类
def kmeans(dataSet, k):
    numSamples = dataSet.shape[0]  #读取矩阵dataSet的第一维度的长度,即获得有多少个样本数据
    # first column stores which cluster this sample belongs to,
    # second column stores the error between this sample and its centroid
    clusterAssment = mat(zeros((numSamples, 2)))  #得到一个N*2的零矩阵
    clusterChanged = True  

    ## step 1: init centroids
    centroids = initCentroids(dataSet, k)  #在样本集中随机选取k个样本点作为初始质心

    while clusterChanged:
        clusterChanged = False
        ## for each sample
        for i in range(numSamples):  #range
            minDist  = 100000.0
            minIndex = 0
            ## for each centroid
            ## step 2: find the centroid who is closest
            #计算每个样本点与质点之间的距离,将其归内到距离最小的那一簇
            for j in range(k):
                distance = euclDistance(centroids[j, :], dataSet[i, :])
                if distance < minDist:
                    minDist  = distance
                    minIndex = j  

            ## step 3: update its cluster
            #k个簇里面与第i个样本距离最小的的标号和距离保存在clusterAssment中
            #若所有的样本不在变化,则退出while循环
            if clusterAssment[i, 0] != minIndex:
                clusterChanged = True
                clusterAssment[i, :] = minIndex, minDist**2  #两个**表示的是minDist的平方

        ## step 4: update centroids
        for j in range(k):
            #clusterAssment[:,0].A==j是找出矩阵clusterAssment中第一列元素中等于j的行的下标,返回的是一个以array的列表,第一个array为等于j的下标
            pointsInCluster = dataSet[nonzero(clusterAssment[:, 0].A == j)[0]] #将dataSet矩阵中相对应的样本提取出来
            centroids[j, :] = mean(pointsInCluster, axis = 0)  #计算标注为j的所有样本的平均值

    print (‘Congratulations, cluster complete!‘)
    return centroids, clusterAssment  

# show your cluster only available with 2-D data
#centroids为k个类别,其中保存着每个类别的质心
#clusterAssment为样本的标记,第一列为此样本的类别号,第二列为到此类别质心的距离
def showCluster(dataSet, k, centroids, clusterAssment):
    numSamples, dim = dataSet.shape
    if dim != 2:
        print ("Sorry! I can not draw because 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):
        print ("Sorry! Your k is too large! ")
        return 1 

    # draw all samples
    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‘]
    # draw the centroids
    for i in range(k):
        plt.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize = 12)  

    plt.show() 

测试文件test.py

from numpy import *
import time
import matplotlib.pyplot as plt
import KMeans

## step 1: load data
print ("step 1: load data..." )
dataSet = []   #列表,用来表示,列表中的每个元素也是一个二维的列表;这个二维列表就是一个样本,样本中包含有我们的属性值和类别号。
#与我们所熟悉的矩阵类似,最终我们将获得N*2的矩阵,
fileIn = open("D:/xuepython/testSet.txt")  #是正斜杠
for line in fileIn.readlines():
    temp=[]
    lineArr = line.strip().split(‘\t‘)  #line.strip()把末尾的‘\n‘去掉
    temp.append(float(lineArr[0]))
    temp.append(float(lineArr[1]))
    dataSet.append(temp)
    #dataSet.append([float(lineArr[0]), float(lineArr[1])])#上面的三条语句可以有这条语句代替
fileIn.close()
## step 2: clustering...
print ("step 2: clustering..."  )
dataSet = mat(dataSet)  #mat()函数是Numpy中的库函数,将数组转化为矩阵
k = 4
centroids, clusterAssment = KMeans.kmeans(dataSet, k)  #调用KMeans文件中定义的kmeans方法。

## step 3: show the result
print ("step 3: show the result..."  )
KMeans.showCluster(dataSet, k, centroids, clusterAssment)

运行结果图如下:

上面是出现的两种聚类的结果。由于基本K均值聚类算法质心选择的随机性,其聚类的结果一般比较随机,一般不会很理想,最终结果往往出现自然簇无法区分的情况,为避免此问题,本文采用二分K均值聚类算法

二分K-均值聚类的python的实现将在下篇博文给出。

完整代码和测试所用的数据可以在这里获取,还是希望大家从连接获取源码,因为从网页上copy的代码会出现没有缩进的情况,需要大家添加缩进,比较麻烦,当你遇到IndentationError:unindent does not match any outer indentation level这样的错误的时候,就是缩进引起的错误,可以看这篇博文,这篇博文给予了解决方法。

除了参考了《机器学习实战》这本书之外,还参考了如下博客,这篇博客基本上也是参考了《机器学习实战》这本书,在此,感谢作者。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-22 18:22:09

《机器学习实战》之K-均值聚类算法的python实现的相关文章

k-均值聚类算法;二分k均值聚类算法

根据<机器学习实战>一书第十章学习k均值聚类算法和二分k均值聚类算法,自己把代码边敲边理解了一下,修正了一些原书中代码的细微差错.目前代码有时会出现如下4种报错信息,这有待继续探究和完善. 报错信息: Warning (from warnings module): File "F:\Python2.7.6\lib\site-packages\numpy\core\_methods.py", line 55 warnings.warn("Mean of empty

机器学习实战笔记-利用K均值聚类算法对未标注数据分组

聚类是一种无监督的学习,它将相似的对象归到同一个簇中.它有点像全自动分类.聚类方法几乎可以应用于所有对象,簇内的对象越相似,聚类的效果越好 簇识别给出聚类结果的含义.假定有一些数据,现在将相似数据归到一起,簇识别会告诉我们这些簇到底都是些什么.聚类与分类的最大不同在于,分类的目标事先巳知,而聚类则不一样.因为其产生的结果与分类相同,而只是类别没有预先定义,聚类有时也被称为无监督分类(unsupervised classification ). 聚类分析试图将相似对象归人同一簇,将不相似对象归到不

K均值聚类算法

k均值聚类算法(k-means clustering algorithm)是一种迭代求解的聚类分析算法,其步骤是随机选取K个对象作为初始的聚类中心,然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心.聚类中心以及分配给它们的对象就代表一个聚类.每分配一个样本,聚类的聚类中心会根据聚类中现有的对象被重新计算.这个过程将不断重复直到满足某个终止条件.终止条件可以是没有(或最小数目)对象被重新分配给不同的聚类,没有(或最小数目)聚类中心再发生变化,误差平方和局部最小.

基于改进人工蜂群算法的K均值聚类算法(附MATLAB版源代码)

其实一直以来也没有准备在园子里发这样的文章,相对来说,算法改进放在园子里还是会稍稍显得格格不入.但是最近邮箱收到的几封邮件让我觉得有必要通过我的博客把过去做过的东西分享出去更给更多需要的人.从论文刊登后,陆陆续续收到本科生.研究生还有博士生的来信和短信微信等,表示了对论文的兴趣以及寻求算法的效果和实现细节,所以,我也就通过邮件或者短信微信来回信,但是有时候也会忘记回复. 另外一个原因也是时间久了,我对于论文以及改进的算法的记忆也越来越模糊,或者那天无意间把代码遗失在哪个角落,真的很难想象我还会全

机器学习实战精读--------K-均值聚类算法

 一个聚类算法只需要知道如何计算相似度就可以了 K-均值(k-means)聚类算法:该算法可以发现K个不同的簇,每个簇的中心采用簇中所安置的均值计算而成. 分层聚类算法 ① BIRCH算法:结合了层次聚类算法和迭代的重定位方法,首先用自底向上的层次算法,然后用迭代的重定位来改进效果. ② DBSCAN算法:具有噪声的基于密度的聚类方法 ③ CURE算法:选择基于质心和基于代表对象方法之间的中间策略.它不用单个质心或对象来代表一个簇,而是选择数据空间中固定数目的具有代表性的点.每一个簇有多于一个的

K均值聚类算法的MATLAB实现

1.K-均值聚类法的概述 之前在参加数学建模的过程中用到过这种聚类方法,但是当时只是简单知道了在matlab中如何调用工具箱进行聚类,并不是特别清楚它的原理.最近因为在学模式识别,又重新接触了这种聚类算法,所以便仔细地研究了一下它的原理.弄懂了之后就自己手工用matlab编程实现了,最后的结果还不错,嘿嘿~~~ 简单来说,K-均值聚类就是在给定了一组样本(x1, x2, ...xn) (xi, i = 1, 2, ... n均是向量) 之后,假设要将其聚为 m(<n) 类,可以按照如下的步骤实现

机器学习实战5:k-means聚类:二分k均值聚类+地理位置聚簇实例

k-均值聚类是非监督学习的一种,输入必须指定聚簇中心个数k.k均值是基于相似度的聚类,为没有标签的一簇实例分为一类. 一 经典的k-均值聚类 思路: 1 随机创建k个质心(k必须指定,二维的很容易确定,可视化数据分布,直观确定即可): 2 遍历数据集的每个实例,计算其到每个质心的相似度,这里也就是欧氏距离:把每个实例都分配到距离最近的质心的那一类,用一个二维数组数据结构保存,第一列是最近质心序号,第二列是距离: 3 根据二维数组保存的数据,重新计算每个聚簇新的质心: 4 迭代2 和 3,直到收敛

聚类之K均值聚类和EM算法

这篇博客整理K均值聚类的内容,包括: 1.K均值聚类的原理: 2.初始类中心的选择和类别数K的确定: 3.K均值聚类和EM算法.高斯混合模型的关系. 一.K均值聚类的原理 K均值聚类(K-means)是一种基于中心的聚类算法,通过迭代,将样本分到K个类中,使得每个样本与其所属类的中心或均值的距离之和最小. 1.定义损失函数 假设我们有一个数据集{x1, x2,..., xN},每个样本的特征维度是m维,我们的目标是将数据集划分为K个类别.假定K的值已经给定,那么第k个类别的中心定义为μk,k=1

k均值聚类

目录 一.k均值简介 二.应用简介 三.算法 四.选择合适的K 五.具体实例 一.k均值简介 K均值聚类是一种无监督学习,对未标记的数据(即没有定义类别或组的数据)进行分类. 该算法的目标是在数据中找到由变量K标记的组.该算法迭代地工作基于所提供的特征,将每个数据点分配给K个组中的一个. 基于特征相似性对数据点进行聚类. K均值聚类算法的结果是: 1.K簇的质心,可用于标记新数据 2.训练数据的标签(每个数据点分配给一个集群) 二.应用简介 K均值聚类算法用于查找未在数据中明确标记的组.这可用于