机器学习kmeans算法的实现

数据文件:
链接:https://pan.baidu.com/s/1E0Hkj1ORxu-1zT6J2VAd0g
提取码:ckwr

机器学习kmeans算法用代码实现:

#!/user/bin/env python3
# -*- coding: utf-8 -*-
# @Author : Crystal
import numpy as np
import matplotlib.pyplot as plt
dataSet = np.genfromtxt('testSet1.txt')
x_data = dataSet[:,0]
y_data = dataSet[:,1]
plt.scatter(x_data,y_data)
print(dataSet.shape)

'''
上述过程的伪代码表示如下:
(1)创建k个点作为起始质心(初始化质心)
(2)当任意一个点的簇分配结果发生改变时
    对数据集中的每个数据点
        对每个质心
        计算质心与数据点之间的距离
    将数据点分配到距其最近的簇
  对每一个簇,计算簇中所有点的均值并将均值作为质心
'''
k = 4


def eduDistance(vector1, vector2):
    # print(sum(((vector1 - vector2) ** 2)))
    return np.sqrt(sum((vector1 - vector2) ** 2))


# (1)初始化质心
def initCentroids(data, k):
    #获取行数及列数
    numSamples, dim = data.shape
    # k个质心,因为是存放质心的数据,所有列数和样本点的列数一样
    #生成一个四行二列的数组
    centroids = np.zeros((k, dim))
    # print(centroids)
    # 随机生成k个质心
    for i in range(k):
        #随机生成一个存在的索引,通过随机的索引选取随机的值作为质心
        index = int(np.random.uniform(0, numSamples))
        centroids[i] = data[index]
    print('cen:',centroids)
    return centroids


# (2)计算每个样本点到簇中心的举例
def kmeans(data, k):
    # 计算样本点的个数
    #索引0,及数据的行数,即数据个数
    numSamples = data.shape[0]
    # 定于簇分配结果矩阵,第一列保存样本点属于那个簇,第二列保存样本点和当前所属簇的误差
    #生成临时矩阵,用于存放误差
    clusterData = np.array(np.zeros((numSamples, 2)))
    # print(clusterData)
    # 决定簇质心是否发生改变的量
    clusterChanged = True


    # 初始化质心
    #获取生成质心函数返回的对象
    centroids = initCentroids(data, k)
    l = 0
    while clusterChanged:  # 当=true才会执行
        clusterChanged = False
        for i in range(numSamples):  # 遍历所有的样本点;(选择先遍历所有的质心会比较麻烦)
            # 最小距离
            minDist = 100000
            # 定义样本所属的簇
            minIndex = 0
            # print('minDist',minDist)
            # 循环计算每一个质心与该样本点的距离
            for j in range(k):
                distance = eduDistance(data[i], centroids[j])
                # 如果计算的距离小于最小距离,则更换最小距离和所属的簇
                # 如果计算的距离小于最小距离,则证明该行数据距离第j个质心更近
                if distance < minDist:
                    minDist = distance
                    clusterData[i, 1] = minDist
                    # 更换样本所属的簇
                    minIndex = j
            #                     clusterData[i,0] = minIndex#这两行代码不能写在这里,写在这里的化会陷入死循环
            #                     clusterChanged = True
            # print(clusterData[i,0])
            # print(minIndex)
            #寻找了最小距离之后,需要更换样本点所属的质心
            if clusterData[i, 0] != minIndex:
                clusterChanged = True
                clusterData[i, 0] = minIndex
        # 更换质心
        for j in range(k):
            # 获取第j个簇所有样本所在的索引
            cluster_index = np.nonzero(clusterData[:, 0] == j)
            # print(cluster_index)
            # 第j个簇所有的样本点
            pointInCluster = data[cluster_index]
            # 计算质心
            # print('22:',centroids[j, :])
            #将质心更换为所属簇样本点的平均值
            centroids[j, :] = np.mean(pointInCluster, axis=0)
            # print('33:',centroids[j, :])
    print('cen2:',centroids)
    #不断更换质心,直至所有样本点的所属簇与最小距离对应的簇相同
    #后将这些簇样本点的平均值作为最后的质心
    return centroids, clusterData


def showCluster(data, k, centroids, clusterData):
    numSamples, dim = data.shape
    if dim != 2:
        print("dimension of your data is not 2!")
        return 1
    # 用不同类别展示各个颜色
    mark = ['or', 'ob', 'og', 'ok', '^r', '+r', 'sr', 'dr', ', 'pr']
    if k > len(mark):
        print("your k is too large!")
        return 1
    # 画样本点
    for i in range(numSamples):
        markIndex = int(clusterData[i, 0])
        plt.plot(data[i, 0], data[i, 1], mark[markIndex])
    # 用不同颜色形状来表示各个质心
    mark = ['+r', '+b', '+g', '+k', '^b', '+b', 'sb', 'db', ', 'pb']
    for i in range(k):
        plt.plot(centroids[i, 0], centroids[i, 1], mark[i], markersize=60)
    plt.show()


centroids, clusterData = kmeans(dataSet, k)
#判断是否正常执行
if np.isnan(centroids).any():
    print('Error')
else:
    print('cluster complete')

showCluster(dataSet, k, centroids, clusterData)



最后实现的结果:
机器学习kmeans算法的实现_第1张图片

你可能感兴趣的:(python,算法,机器学习,深度学习)