机器学习之十大经典算法(二)K-Means算法

  1K-means简介

k-meansalgorithm算法是一个聚类算法,把n的对象根据他们的属性分为k个分割,k < n。假设对象属性来自于空间向量,并且目标是使各个群组内部的均方误差总和最小。

      假设有k个群组Si, i=1,2,...,k。μi是群组Si内所有元素xj的质心,或叫中心点。

k平均聚类发明于1956年, 该算法最常见的形式是采用被称为劳埃德算法(Lloydalgorithm)的迭代式改进探索法。劳埃德算法首先把输入点分成k个初始化分组,可以是随机的或者使用一些启发式数据。然后计算每组的中心点,根据中心点的位置把对象分到离它最近的中心,重新确定分组。继续重复不断地计算中心并重新分组,直到收敛,即对象不再改变分组(中心点位置不再改变)。

劳埃德算法和k平均通常是紧密联系的,但是在实际应用中,劳埃德算法是解决k平均问题的启发式法则,对于某些起始点和重心的组合,劳埃德算法可能实际上收敛于错误的结果。虽然存在变异,但是劳埃德算法仍旧保持流行,因为它在实际中收敛非常快。实际上,观察发现迭代次数远远少于点的数量。然而最近,David ArthurSergei Vassilvitskii提出存在特定的点集使得k平均算法花费超多项式时间达到收敛。近似的k平均算法已经被设计用于原始数据子集的计算。

从算法的表现上来说,它并不保证一定得到全局最优解,最终解的质量很大程度上取决于初始化的分组。由于该算法的速度很快,因此常用的一种方法是多次运行k平均算法,选择最优解。

k平均算法的一个缺点是,分组的数目k是一个输入参数,不合适的k可能返回较差的结果。另外,算法还假设均方误差是计算群组分散度的最佳参数。

  2)基本方法:

一、从数据中随机抽取k个点作为初始聚类的中心,由这个中心代表各个聚类。

二、计算数据中所有的样本点到这k个点的距离,将每个样本点都归到最近的聚类里。

三、重新计算聚类中心点,方法就是将第二步中的中心移动到聚类的几何中心(即平均值)处。

四、重复第2步直到聚类的中心不再移动,此时算法收敛。

3sklearn中基本步骤。

读入数据、可以绘制出数据的样子、训练模型、绘制边界(观察效果)、中心点绘制。

代码参考如下:

from numpy import *

import numpy as np

from math import *

import matplotlib.pyplot as plt

import matplotlib   

#--------------------------------------输入信息

#输入:文件名;

#输出:listdataMat,数据集为所有特征(无监督学习)

def loadDataSet(fileName):

   numFeat=len(open(fileName).readline().split('\t'))

    dataMat=[];labelArr=[]

    fr=open(fileName)

    for line infr.readlines():

        lineArr=[]

       curLine=line.strip().split('\t')

        for i inrange(numFeat): 

           lineArr.append(float(curLine[i]))

       dataMat.append(lineArr)

    return dataMat  #返回的是array类型。

#-------------------------------------------------------------————————

def plotxy(x,y):#x,y具有相同数组序列;只要长度一致即可。

    #x=[[2,3,4,5,6,7,8]]

   #y=[[1],[2],[3],[4],[5],[6],[7]]

    fig=plt.figure()

    ax1=fig.add_subplot(221)

   ax1.set_title('clustering:')   

    ax1.scatter(x,y,s=20,c='r',marker='o')#s代表大小,可以是数组,和前面对应。

    x_min, x_max = min(x) - 1,max(x) + 1

y_min, y_max = min(y) - 1, max(y) + 1

plt.xlim(x_min, x_max)

plt.ylim(y_min, y_max)

plt.xticks(())

plt.yticks(())

plt.show()

# Train the model

kmeans = KMeans(init='k-means++',n_clusters=num_clusters, n_init=10)

kmeans.fit(data)

# Step size of the mesh

step = 0.05

# Plot the boundaries

x_min, x_max = min(data[:, 0]) - 1,max(data[:, 0]) + 1

y_min, y_max = min(data[:, 1]) - 1,max(data[:, 1]) + 1

x_values, y_values =np.meshgrid(np.arange(x_min, x_max, step_size), np.arange(y_min, y_max, step))

predicted_labels =predicted_labels.reshape(x_values.shape)

plt.figure()

plt.clf()

plt.imshow(predicted_labels,interpolation='nearest',

          extent=(x_values.min(), x_values.max(), y_values.min(), y_values.max()),

          cmap=plt.cm.Paired,aspect='auto', origin='lower')

plt.scatter(data[:,0], data[:,1],marker='o', facecolors='none', edgecolors='k', s=30)

centroids = kmeans.cluster_centers_

plt.scatter(centroids[:,0], centroids[:,1],marker='o', s=200, linewidths=3,color='k', zorder=10, facecolors='black')

x_min, x_max = min(data[:, 0]) - 1,max(data[:, 0]) + 1

y_min, y_max = min(data[:, 1]) - 1,max(data[:, 1]) + 1

plt.title('Centoids and boundaries obtainedusing KMeans')

plt.xlim(x_min, x_max)

plt.ylim(y_min, y_max)

plt.xticks(())

plt.yticks(())

plt.show()

猜你喜欢

转载自blog.csdn.net/weixin_42039090/article/details/80547686
今日推荐