K-MEANS聚类算法,K值最优取值

分类: 机器学习 |
缺点:
2、在 K-means 算法中,首先需要根据初始聚类中心来确定一个初始划分,然后对初始划分进行优化。这个初始聚类中心的选择对聚类结果有较大的影响,一旦初始值选择的不好,可能无法得到有效的聚类结果;
3、该算法需要不断地进行样本分类调整,不断地计算调整后的新的聚类中心,因此当数据量非常大时,算法的时间开销是非常大的;
4、若簇中含有异常点,将导致均值偏离严重(即:对噪声和孤立点数据敏感);
其中,Ci是第i个簇,p是Ci中的样本点,mi是Ci的质心(Ci中所有样本的均值),SSE是所有样本的聚类误差,代表了聚类效果的好坏。
手肘法的核心思想是:随着聚类数k的增大,样本划分会更加精细,每个簇的聚合程度会逐渐提高,那么误差平方和SSE自然会逐渐变小。并且,当k小于真实聚类数时,由于k的增大会大幅增加每个簇的聚合程度,故SSE的下降幅度会很大,而当k到达真实聚类数时,再增加k所得到的聚合程度回报会迅速变小,所以SSE的下降幅度会骤减,然后随着k值的继续增大而趋于平缓,也就是说SSE和k的关系图是一个手肘的形状,而这个肘部对应的k值就是数据的真实聚类数。当然,这也是该方法被称为手肘法的原因。
1.2 实现代码
我们对数据.csv中的数据利用手肘法选取最佳聚类数k。具体做法是让k从1开始取值直到取到你认为合适的上限(一般来说这个上限不会太大,这里我们选取上限为10),对每一个k值进行聚类并且记下对于的SSE,然后画出k和SSE的关系图(毫无疑问是手肘形),最后选取肘部对应的k作为我们的最佳聚类数。python实现如下:-
import
pandas as pd -
from
sklearn.cluster importKMeans -
import
matplotlib.pyplot as plt -
-
df_features
= pd.read_csv(r'D:\数据.csv',encoding='gbk') # 读入数据 -
'利用SSE选择k'
-
SSE
= [] # 存放每次结果的误差平方和 -
for
k inrange( 1,11): -
estimator = KMeans(n_clusters=k) # 构造聚类器 -
estimator.fit(df_features[['R','F','M']]) -
SSE.append(estimator.inertia_) -
X
= range(1,11) -
plt.xlabel('k')
-
plt.ylabel('SSE')
-
plt.plot(X,SSE,'o-')
- plt.show()
2、轮廓系数
2.1 基本原理
方法的核心指标是轮廓系数(Silhouette Coefficient),某个样本点Xi的轮廓系数定义如下:
其中,a是Xi与同簇的其他样本的平均距离,称为凝聚度,b是Xi与最近簇中所有样本的平均距离,称为分离度。而最近簇的定义是
其中p是某个簇Ck中的样本。事实上,简单点讲,就是用Xi到某个簇所有样本平均距离作为衡量该点到该簇的距离后,选择离Xi最近的一个簇作为最近簇。
2.2 代码实现
我们同样使用2.1中的数据集,同样考虑k等于1到8的情况,对于每个k值进行聚类并且求出相应的轮廓系数,然后做出k和轮廓系数的关系图,选取轮廓系数取值最大的k作为我们最佳聚类系数,python实现如下:
- import
pandas as pd - from
sklearn.cluster importKMeans - from
sklearn.metrics importsilhouette_score - import
matplotlib.pyplot as plt -
-
df_features
= pd.read_csv(r'C:\Users\61087\Desktop\项目\爬虫数据\预处理后数据.csv',encoding='gbk') -
Scores
= [] # 存放轮廓系数 - for
k inrange( 2,11): -
estimator = KMeans(n_clusters=k) # 构造聚类器 -
estimator.fit(df_features[['R','F','M']]) -
Scores.append(silhouette_score(df_features[['R','F','M']],estimator.labels_,metric='euclidean')) -
X
= range(2,11) - plt.xlabel('k')
- plt.ylabel('轮廓系数')
- plt.plot(X,Scores,'o-')
- plt.show()
上图可以看到,轮廓系数最大的k值是2,这表示我们的最佳聚类数为2。但是从k和SSE的手肘图可以看出,当k取2时,SSE非常大,所以这是一个不太合理的聚类数,我们退而求其次,考虑轮廓系数第二大的k值4,这时候SSE已经处于一个较低的水平,因此最佳聚类系数应该取4而不是2。