(转)Python -- 实现kmeans算法

代码理解参考:https://blog.csdn.net/hanxia159357/article/details/81530361

K-means 算法基本流程:
(1) 随机选取k个聚类中心
(2) 计算每个样本到聚类中心的距离
(3) 更新样本聚类中心
(4) 重复1-3,直到样本聚类中心不发生变化。

关键注意点
随机选取聚类中心
采用欧氏距离计算
记录、更新样本的分类状况和距中心距离
更新聚类中心的方法
需要一个变量记录是否发生改变,改变就一直循环,不改变即停止。

数据:

1.65	4.28
-3.45	3.42
4.84	-1.15
-5.37	-3.36
0.97	2.92
-3.57	1.53
0.45	-3.30
-3.49	-1.72
2.67	1.59
-3.16	3.19

代码实现:

import numpy as np

# 加载数据
def loadDataSet(fileName):
    data = np.loadtxt(fileName, delimiter='\t')
    return data

# 欧氏距离计算
def distEclud(x, y):
    return np.sqrt(np.sum((x - y) ** 2))  # 计算欧氏距离

# 为给定数据集构建一个包含K个随机聚类中心的集合
def randCent(dataSet, k):
    m, n = dataSet.shape
    # print(m,n)
    centroids = np.zeros((k, n))
    for i in range(k):
        index = int(np.random.uniform(0, m))
        # print(index)
        centroids[i, :] = dataSet[index, :]
    # print(centroids)
    # print(centroids[1,:])
    return centroids

# k均值聚类
def KMeans(dataSet, k):
    m = np.shape(dataSet)[0]  # 行的数目
    # 第一列存样本属于哪一簇
    # 第二列存样本的到簇的中心点的误差
    clusterAssment = np.mat(np.zeros((m, 2)))
    # print(clusterAssment)
    # print(clusterAssment[1,0])
    clusterChange = True

    # 第1步 初始化centroids
    centroids = randCent(dataSet, k)
    while clusterChange:
        clusterChange = False

        # 遍历所有的样本(行数)
        for i in range(m):
            minDist = 100000.0
            minIndex = -1

            # 遍历所有的质心
            # 第2步 找出最近的质心
            for j in range(k):
                # 计算该样本到质心的欧式距离
                distance = distEclud(centroids[j, :], dataSet[i, :])
                if distance < minDist:
                    minDist = distance
                    minIndex = j
            # 第 3 步:更新每一行样本所属的簇
            if clusterAssment[i, 0] != minIndex:
                clusterChange = True
                clusterAssment[i, :] = minIndex, minDist ** 2

        # 第 4 步:更新质心
        for j in range(k):
            pointsInCluster = dataSet[np.nonzero(clusterAssment[:, 0].A == j)[0]]  # 获取簇类所有的点
            centroids[j, :] = np.mean(pointsInCluster, axis=0)  # 对矩阵的行求均值
            # print(np.nonzero(clusterAssment[:, 0].A == j)[0])
    # print("Congratulations,cluster complete!")
    return centroids, clusterAssment

if __name__ == "__main__":
    dataset = loadDataSet('test.txt')
    # # 测试1
    # print(dataset.shape)
    # # 测试2
    # randCent(dataset,3)
    print(KMeans(dataset,3))

你可能感兴趣的:(算法,Python,Kmeans)