赞
踩
有很多聚类方法,我们这里是最基本的Kmeans聚类
什么是Kmeans聚类,俗话讲‘物以类聚,人以群分’。数据也是如此
与分类不同的是:聚类是无监督算法,而分类是有监督算法是带标签的。
聚类可以简单的理解为根据数据的各个特征把一堆数据聚集为多个群体。然后针对不同群体的数据进行不同的操作。
例如:
老王想要在村子里开几个个超市,那么开超市的可不单单是随便挑选位置的;
他应该考虑到每家每户到超市的距离都尽可能的小,保证村民和自己的利益最大化。
假设这个村子一个有20个房屋,他们在平面上的坐标为
[2, 5], [4, 6], [3, 1], [6, 4], [7, 2], [8, 4], [2, 3], [3, 1], [5, 7], [6, 9], [12, 16], [10, 11], [15, 19],[16, 12], [11, 15], [10, 14], [19, 11], [17, 14], [16, 11], [13, 19]
数据分布为:
在Kmeans的思想中,需要首先给他K个聚类中心,这个是随机的。
老王由于资金短缺,所以预计只开两个超市,K就是2
然后聚类中心也就是超市的位置,就应该计算每户到超市的距离
然后将村民聚成两类
每一个村民到超市的距离就有了。我们要的就是通过反复的计算距离(我们一般用欧几里得来计算距离)
最终将村民到超市的距离计算出来,第二次循环,再次计算村民到到超市的距离,再次将村民聚为两类,通过反复循环来调优,直到聚类中心不再变换。
结果图为:
那么我们该如何确定最优的聚类中心个数呢:
在这里讲解一下肘部法则:
为什么叫它肘部法则呢,因为它是根据聚类中心个数和距离平方和所画出来的图。针对每一个聚类中心都有所对应的距离平方和,(这里的距离平方和可以理解为损失)
如图:
在不同问题中考虑因素不同,在老王开超市这个问题中,我们可以看到在聚类中心越多,损失越少。在聚类中心个数为5-20个的时候,它的损失下降的很少。所以我们可以根据肘部法则来确定最优的聚类中心个数。
from sklearn.cluster import KMeans import matplotlib.pyplot as plt import numpy as np from pylab import * mpl.rcParams['font.sans-serif'] = ['SimHei'] # 画图是争取显示中文 # 20个数据 data = np.array( [[2, 5], [4, 6], [3, 1], [6, 4], [7, 2], [8, 4], [2, 3], [3, 1], [5, 7], [6, 9], [12, 16], [10, 11], [15, 19], [16, 12], [11, 15], [10, 14], [19, 11], [17, 14], [16, 11], [13, 19]]) est = KMeans(n_clusters=2) # 创建一个kmean对象 est.fit(data) # 训练模型 # plt.figure() # plt.scatter(data[:, 0], data[:, 1]) # plt.show() print('聚类中心的位置: \n', est.cluster_centers_) print('聚类中心所属聚类中心的索引: ', est.labels_) print('代价', est.inertia_) # 依据距离来计算的 print(data) # 画样本数据 plt.figure('K-mean算法', figsize=(10, 6)) plt.scatter(data[est.labels_ == 0, 0], data[est.labels_ == 0, 1]) plt.scatter(data[est.labels_ == 1, 0], data[est.labels_ == 1, 1]) # plt.plot(est.inertia_) # plt.scatter(data[:, 0], data[:, 1]) for i in range(2): plt.scatter(est.cluster_centers_[i, 0], est.cluster_centers_[i, 1], marker='x') for i in range(2): plt.annotate('超市'+str(i+1), xy=(est.cluster_centers_[i, 0], est.cluster_centers_[i, 1]), xytext=(4, 4), textcoords='offset points', fontsize=10) plt.show() m = 20 k = [] # K是聚类中心个数 inertia = [] # 用来存储聚类中心个数所对应的代价 for i in range(m): est = KMeans(n_clusters=i+1) est.fit(data) k.append(i+1) inertia.append(est.inertia_) plt.figure('肘部法则图', figsize=(10, 6)) plt.title('代价函数图') plt.xlabel('k值') plt.ylabel('代价') plt.plot(k, inertia) plt.show()
如果有些地方写错的话,欢迎指出。谢谢。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。