k-means聚类:擒贼先擒王,找到中心点,它附近的都是一类


属于无监督学习,聚类算法事先并不需要知道数据的类别标签,只是根据数据特征去学习,找到相似数据的特征,然后把已知的数据集划分成几个不同的类别

算法原理:

假设数据总共有m条,计划分成3个类别

先随机在这个空间中选取三个点,称之为中心点;计算所有的点到这三个点的距离,这里的距离计算使用的是欧氏距离;使用每个组的数据计算出这些数据的一个均值,使用这个均值作为下一轮迭代的中心点

如何确定k值

手肘法(适用于k值不那么大)

循环尝试k值,计算在不同的k值情况下,所有数据的损失即用每一个数据点到中心点的距离之和计算平均距离

 k=4时左侧数值变化大,右侧较为平缓

算法优点

简洁明了,计算复杂度低

收敛速度较快

算法缺点

结果不稳定

无法解决样本不均衡的问题

容易收敛到局部最优解

受噪声影响较大

from sklearn import datasets

import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans

"""
画出聚类后的图像
labels:聚类后的label,从0开始的数字
cents:质心坐标
n_cluster:聚类后簇的数量
"""
def draw_result(train_x,labels,cents,title):
   n_clusters = np.unique(labels).shape[0]
   color = ["red","orange","yellow"]
   plt.figure()
   plt.title(title)
   for i in range(n_clusters):
      current_data = train_x[labels ==i]
      plt.scatter(current_data[:,0],current_data[:,1],c=color[i])
#使用蓝色的星形表示中心点位置
      plt.scatter(cents[i,0],cents[i,1],c="blue",marker="*",s=100)
   return plt

if _name_ == '__main__':
   iris = datasets.load_iris()
   iris_x - iris.data
#设定聚类数目为3
    clf = KMeans(n_clusters=3,max_iter=10,n_init=10,init="k-means++",algorithm="full",tol=1e-4,n_jobs=-1,random_state=1)
    clf.fit(iris_x)
    print("SSE={0}".format(clf.inertia_))
    draw_result(iris_x,clf.labels_,clf.cluster_centers_,"kmeans").show()

#SEE是误差平方和,越接近0说明效果越好