三、(4)评价Kmeans算法聚类结果。利用 手肘法SSE 和 轮廓系数 检验。
本文运用SSE(簇内误方差)和轮廓系数两种检验方法,对三、(2)python实现完整的K-means算法进行K值检验。
完整代码如下:
(1) SSE。
SSE利用计算误方差和,来实现对不同K值的选取后,每个K值对应簇内的点到中心点的距离误差平方和,理论上SSE的值越小,代表聚类效果越好,通过数据测试,SSE的值会逐渐趋向一个最小值。
代码如下:
# -*- coding: utf-8 -*-
from sklearn.cluster import KMeans
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
from matplotlib import font_manager
my_font = font_manager.FontProperties(fname="/Windows/Fonts/simhei.ttf",size=20)
import matplotlib.pyplot as plt
'''
1、加载语料
'''
#文档预料 空格连接
text = open('聚类4类.txt',"r", encoding='UTF-8').read() #打开本体TXT文件
list1=text.split("\n")
mytext_list=list1
'''
2、把每篇文篇关键词出现10次以上,转化成向量(tf),-idf设为权重
#把关键词转化成词篇矩阵
'''
#提取关键词出现#min_df=10次以上的关键词
count_vec=CountVectorizer(min_df=10)
#把关键词转化成词篇矩阵
xx1 = count_vec.fit_transform(list1).toarray()
#读取出现3次以上的具体关键词
word=count_vec.get_feature_names()
#该类会统计每个词语的tf-idf权值
transformer = TfidfTransformer()
#计算tf-idf
tfidf = transformer.fit_transform(xx1)
#将tf-idf矩阵抽取出来,元素w[i][j]表示j词在i类文本中的tf-idf权重
weight = tfidf.toarray()
#肘方法看k值
SSE = []
for i in range(1,11):
km = KMeans(n_clusters=i,random_state=100)
km.fit(weight)
#获取K-means算法的SSE
SSE.append(km.inertia_)
#绘制曲线
plt.plot(range(1,11),SSE,marker="o")
plt.xlabel("K值——簇数量",fontproperties=my_font,size=20)
plt.ylabel("簇内误方差SSE",fontproperties=my_font,size=20)
plt.show()
代码中的文本数据为科技、医学、汽车和国家四个类别。
输出结果如下图所示,当K = 4 时首次出现曲率最大的转折点。
(2) 轮廓系数。
使用K-means ,将待分类数据分为了 k 个簇 。对于簇中的每个向量。分别计算它们的轮廓系数。
对于其中的一个点 i 来说:
计算 a(i) = average(i向量到所有它属于的簇中其它点的距离)
计算 b(i) = min (i向量到各个非本身所在簇的所有点的平均距离)
那么 i 向量轮廓系数就为:
代码如下:
# -*- coding: utf-8 -*-
from sklearn.cluster import KMeans
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
from sklearn.metrics import silhouette_score
from matplotlib import font_manager
my_font = font_manager.FontProperties(fname="/Windows/Fonts/simhei.ttf",size=20)
import matplotlib.pyplot as plt
'''
1、加载语料
'''
#文档预料 空格连接
text = open('聚类4类.txt',"r", encoding='UTF-8').read() #打开本体TXT文件
list1=text.split("\n")
'''
2、把每篇文篇关键词出现10次以上,转化成向量(tf),-idf设为权重
#把关键词转化成词篇矩阵
'''
#提取关键词出现#min_df=10次以上的关键词
count_vec=CountVectorizer(min_df=10)
#把关键词转化成词篇矩阵
xx1 = count_vec.fit_transform(list1).toarray()
#读取出现3次以上的具体关键词
word=count_vec.get_feature_names()
#该类会统计每个词语的tf-idf权值
transformer = TfidfTransformer()
#计算tf-idf
tfidf = transformer.fit_transform(xx1)
#将tf-idf矩阵抽取出来,元素w[i][j]表示j词在i类文本中的tf-idf权重
weight = tfidf.toarray()
Scores = [] # 存放轮廓系数
for k in range(2,10):
kmeans = KMeans(n_clusters=k) # 构造聚类器
kmeans.fit(weight)
Scores.append(silhouette_score(weight,kmeans.labels_,metric='euclidean'))
X = range(2,10)
plt.xlabel('k值——簇数量',fontproperties=my_font,size=20)
plt.ylabel('轮廓系数',fontproperties=my_font,size=20)
plt.plot(X,Scores,'o-')
plt.show()
输出结果如下图所示,当K = 4 时 S(i) 局部最大。
搞定收工。
“☺☺☺ 若本篇文章对你有一丝丝帮助,请帮顶、评论点赞,谢谢。☺☺☺”
↓↓↓↓