K-均值聚类算法

from numpy import *

#创建元组
dataSet = []
#与我们所熟悉的矩阵类似,最终我们将获得N*2的矩阵,
fileIn = open("/home/zengxl/PycharmProjects/test3/机器学习实战代码/Ch10/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()

dataSet = mat(dataSet)  #mat()函数是Numpy中的库函数,将数组转化为矩阵

#函数euclDistance()计算两个向量的欧式距离
def euclDistance(vector1, vector2):
    return sqrt(sum(power(vector2 - vector1, 2))) #使用了sqrt。

#在样本集中随机选取k个样本点作为初始质心
def initCentroids(dataSet, k):
    numSamples, dim = dataSet.shape   #矩阵的行数、列数
    centroids = mat(zeros((k, dim)))  #mat函数创建k行n列的矩阵,centroids存放簇中心
    for i in range(k):
        index = int(random.uniform(0, numSamples))  #uniform()随机生成一个[x, y)范围内实数,然后将其转化为int型
        centroids[i, :] = dataSet[index, :]
    return centroids

#k为将dataSet矩阵中的样本分成k个类,数据集及簇的数目是必选参数。
def kmeans(dataSet, k):
    numSamples = dataSet.shape[0]  #读取矩阵dataSet的第一维度的长度,即获得有多少个样本数据
    # clusterAssment创建一个m行2列的矩阵,第一列存放索引值,第二列存放误差,误差用来评价聚类效果
    clusterAssment = mat(zeros((numSamples, 2)))  #得到一个N*2的零矩阵

    #标志变量clusterChanged,如果该值为True,则继续迭代。
    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#或者inf为正无穷大
            minIndex = 0 #创建索引
            #计算每个样本点与质点之间的距离,将其归内到距离最小的那一簇
            for j in range(k):
                # 寻找最近的质心
                distance = euclDistance(centroids[j, :], dataSet[i, :])#计算每个点到质心的欧氏距离
                if distance < minDist:
                    minDist  = distance
                    minIndex = j

            #如果任一点的簇分配结果发生改变,则更新clusterChanged标志。
            if clusterAssment[i, 0] != minIndex:
                clusterChanged = True
                clusterAssment[i, :] = minIndex, minDist**2  #两个**表示的是minDist的平方

        ## 更新质心的位置
        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

myCentroids, clustAssing = kmeans(dataSet, 4)
print("myCentroids:", myCentroids)

print("clustAssing", clustAssing)

    原文作者:聚类算法
    原文地址: https://blog.csdn.net/zxllll8898/article/details/78343162
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞