机器学习实战笔记:K-均值聚类

    K-均值算法:首先,随机确定k个初始点作为质心。根据样本与类中心的距离将数据集中的每个点分配到相应的簇中,接着重新计算类中心,迭代直至收敛。

    伪代码如下:

创建k个点作为起始质心(随机选择)
当任意一个点的簇分配结果发生改变时:
    对数据集中的每个数据点:
        对每个质心:
            计算质心与数据点之间的距离
        将数据点分配到距其最近的簇
    对每一个簇,计算簇中所有点的均值并将均值作为质心

    一般流程:

  1. 收集数据;
  2. 准备数据:需要数值型数据来计算距离,也可以将标记型数据映射为二值型数据再用于距离计算
  3. 分析数据;
  4. 训练算法:无监督学习没有训练过程
  5. 测试算法;
  6. 使用算法;

    K-均值聚类支持函数:

def loadDataSet(filename):
    dataMat=[]
    fr=open(filename)
    for line in fr.readlines():
        curLine=line.strip().split('\t')
        fltLine=list(map(float,curLine))   #会根据提供的函数(类型)对指定序列做映射,python3中map返回的是迭代器,所以要改成list
        dataMat.append(fltLine)
    return dataMat


"""计算两个样本之间的距离"""
def distEclud(vecA,vecB):
    return sqrt(sum(power(vecA-vecB,2)))

"""为给定的数据集构建一个包含k个随机簇质心的集合"""
"""随机质心必须在整个数据集的边界之内,通过找到数据集每一维的最小和最大值来完成"""
def randCent(dataSet,k):
    n=shape(dataSet)[1]             #特征数
    centroids=mat(zeros((k,n)))     #构建k个质心的矩阵,初始化为全0
    for j in range(n):
        minJ=min(dataSet[:,j])      #找出所有样本中每一个特征的最小特征的样本
        rangeJ=float(max(dataSet[:,j])-minJ)    #质心的特征可以设置的范围
        centroids[:,j]=minJ+rangeJ*random.rand(k,1)    #随机k个质心
    return centroids

K-均值算法实现:

"""K-Means聚类"""
def kMeans(dataSet,k,distMeas=distEclud,createCent=randCent):
    m=shape(dataSet)[0]         #样本总数
    clusterAssment=mat(zeros((m,2)))    #创建一个矩阵,用于存储每个点的簇分配结果,包含两列:记录簇索引值;存储误差(当前点到簇质心的距离)
    centroids=createCent(dataSet,k)     #初始化簇质心
    clusterChanged=True                 #簇分配发生改变(因为簇质心发生了改变)
    while clusterChanged:               #迭代
        clusterChanged=False            
        for i in range(m):              #遍历每一个样本
            minDist=inf                 
            minIndex=-1
            for j in range(k):           #用该样本和每一个当前质心比较   
                distJI=distMeas(centroids[j,:],dataSet[i,:])    #找到距离最近的质心
                if distJI<minDist:
                    minDist=distJI        #记录最短距离
                    minIndex=j            #记录簇序号(索引)
            if clusterAssment[i,0]!=minIndex:     #查看当前样本的簇是否和现在分配的簇序号一致
                clusterChanged=True
            clusterAssment[i,:]=minIndex,minDist**2    #记录误差
        print(centroids)
        for cent in range(k):    #更新质心
            ptsInClust=dataSet[nonzero(clusterAssment[:,0].A==cent)[0]]
            centroids[cent,:]=mean(ptsInClust,axis=0)      #更新方式是计算簇中所有点的均值作为新的质心
    return centroids,clusterAssment

   

猜你喜欢

转载自blog.csdn.net/qq_29599907/article/details/80605924