K均值算法【K-means】

K均值算法是学习无监督学习的第一个算法,这个算法理解和实现都比较简单,算法的目的是将数据分成K组。

为了达到这个目的,算法首先随机初始化k个数据点(聚类中心),然后遍历所有数据,计算出每一个数据到k个点的距离,找到最小的距离,则该点属于这个类。之后计算每一组中的平均值,然后更新聚类中心,直到中心点不再发生变化。

下面是算法的流程图:

下面是python的代码实现:

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import scipy.io as sio
import numpy as np

#读入数据,将数据转化为DataFrame
mat = sio.loadmat('ex7data2.mat')
data = pd.DataFrame(mat.get('X'),columns=['X1','X2'])

# 将数据可视化
sns.set(context='notebook',style='white')
sns.lmplot('X1','X2',data=data,fit_reg=False)

数据如下图所示:

K均值算法【K-means】_第1张图片

#计算两个向量之间的距离
def distEclud(vecA,vecB):
    return np.sqrt(np.sum(np.power(vecA-vecB,2)))

#随机选择K个聚类中心,进行初始化化
def randCent(dataSet,k):
    # n是数据的维数
    n = np.shape(dataSet)[1]
    centroids = np.mat(np.zeros((k,n)))
    for j in range(n):
        minJ = min(dataSet[:,j])
        rangeJ = float(max(dataSet[:,j])-minJ)
        centroids[:,j] = minJ + rangeJ*np.random.rand(k,1)
    return centroids

def KMeans(dataSet,k,distMeans=distEclud,createCent=randCent):
    m = np.shape(dataSet)[0]
    clusterAssment = np.zeros((m,2))
    centroids = createCent(dataSet,k)
    clusterChanged = True
    while clusterChanged:
        clusterChanged = False
        # 遍历所有样本
        for i in range(m):
            minDist = np.inf
            minIndex = -1
            # 对于一个样本,计算他和每一个聚类中心的距离,找到最小的距离
            for j in range(k):
                distJI = distMeans(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[np.nonzero(clusterAssment[:,0]==cent)[0]]
            centroids[cent,:] = np.mean(ptsInClust,axis=0)
    return centroids,clusterAssment
#调用函数,进行聚类
myCentroids,clustAssing =KMeans(data.values,3)

#将类别添加到数据中
data['C'] = clustAssing[:,0]

#绘制分类后的数据
sns.lmplot('X1','X2',hue='C',data=data,fit_reg=False)

最后的聚类结果:

K均值算法【K-means】_第2张图片

可以看到,算法几乎将数据准确的分成了三类,但是这是在我们知道算法的类别是3的情况下,如果我们初始化的类别不是3,算法就不会有这么好的效果。特别是对于高维数据,我们无法将数据可视化的情况下,需要多次运行算法,查看分类效果。将聚类中心初始化为6,效果就没有那么好了,如下图所示:

K均值算法【K-means】_第3张图片

参考资料:1>吴恩达机器学习K-means作业

        2>机器学习实战

你可能感兴趣的:(机器学习)