什么是聚类

聚类可以将相似的样本归到同一簇中,是无监督学习中最常见的问题。聚类的结果是,簇内的对象越相似,聚类的效果就越好。一个簇的意思就是一个类别。

以人学习习题为例,仔细观察习题,就会发现高频出现运算符号的题目是数学题,高频出现英文字母的题目是英语题。如下图,这种将相似样本归到同一簇中的过程,并不依赖标准答案,这就是聚类。

聚类算法中,最经典的就是Kmeans 聚类了,也叫作 K 均值聚类,是最常用的聚类算法。

Kmeans 算法中的 K 表示的是,将样本聚为 K 个簇;Means 代表取每一个聚类中数据值的均值作为该簇的中心,或者称为质心。Kmeans 聚类算法,可以将输入数据聚合成 K 个簇并输出。

Kmeans 聚类算法

Kmeans聚类算法输入的内容包括,聚类目标 K 值和样本的集合。

执行算法的第一步是初始化。通常采用的策略是,在特征空间中,随机选 K 个点作为初始的质心。

第二步是归类和更新。具体来说,归类是对数据集中每个点而言,计算其与每个质点之间的距离,并将数据点分配到距离最近的质点所在的簇。更新是对每一个簇而言,计算簇中所有点的均值,并将均值作为新的质心替换掉原来的质心。

之后呢,就需要重复执行归类和更新的操作,直到某些停止条件满足。

Kmeans 算法的停止条件通常有以下 4 个,一般任意满足一点即可停止算法的主流程:

1)预先设置好迭代的轮数,一旦超过了迭代的最大轮数则停止迭代;

2)在某次循环中,没有数据点被重新分配到其他的簇,也就是算法已经收敛,则算法结束迭代;

3)某次循环,质心的位置没有发生改变,也是算法发生了收敛,则算法结束迭代;

4)某次循环,均方误差 SSE 递减的增量,小于预先设置的某个阈值,也就是这一次的迭代对聚类结果影响非常小,算法已经趋近于收敛,则算法结束迭代。SSE 的计算公式如下:

其中,K 表示 K 个簇,Cj 为簇 j 内数据样本的集合,mj 表示 Cj 簇的质心。这个公式的意思是,对每个簇计算每个数据点与其所归属的质心的距离平方和,再将所有簇的结果求和。随着 Kmeans 不断迭代,SSE 的值在不断的缩小,直到某次迭代,这个减小的幅度可被忽略。

接下来我们看一个例题,来实际用一下 Kmeans 聚类算法。

假设样本集合为 (0.1, 0.9)、(0.2, 0.8)、(0.1, 0.8)、(0.9, 0.3)、(0.9, 0.2)、(0.8, 0.1),设置 K 为 2,采用 Kmeans 聚类算法对样本集合进行聚类。根据算法流程,首先随机初始化两个质心,假设为 (0.5, 0.5) 和 (0.4, 0.3),此时样本集合(图中蓝色圆点)以及质心(图中红色、绿色方块)如下图:

对每个样本点,计算其与每个质点的距离,并归至距离近的簇中。在这里,我们选取欧式距离作为距离函数。也就是:

结果,(0.8, 0.1) 被归至绿色的簇,其余点被归至红色的簇。利用每个簇数据点的均值,替换上一轮的质心,则有下图:

重复上面的过程,发现红色簇有两个数据点发生了簇跳变,被重新归位绿色簇中,此时两个质心再次发生改变。见下图:

再次重复上面的过程,发现没有数据点的簇标签发生变化,则算法结束计算。最终结果如下图,其中数据点被聚为两个簇中,分别用红色和绿色标记,每个簇的质心用对应颜色的方块表示:

Kmeans聚类算法的优缺点

Kmeans 算法的优势在于简单易懂、便于实现。Kmeans 算法非常简单,上面的内容已经将它的核心流程和示例描述得清楚明了。在运用过程中,即使不使用公开的工具包,自行编码开发,也只不过是体力劳动而已。

既然这个算法简单容易,其实也就决定了它的缺陷和不足。根据经验,Kmeans 算法至少存在 4 个明显的缺陷。

首先,K 是输入参数,没有一套自适应的计算方法,需要依赖人工经验。如果 K 给的不好,则结果质量很难保证。

其次,Kmeans 聚类算法对离群点很敏感。质心的更新,依靠的是全部簇内数据点的平均值。如果样本集合中存在某个离群点,可能会导致质心平均值计算偏差很大,而影响结果。

第三,Kmeans 聚类算法对初始质心很敏感。如果初始质心给的不好,很有可能出现意想不到的结果。

最后,如果样本点的分布不是凸的,Kmeans 聚类算法有可能出现错误的结果。这种情况一旦发生,是很难被发现的,如下图:

聚类问题是无监督学习的代表性问题之一,Kmeans 算法是最常见的聚类算法。Kmeans 算法简单易懂、便于实现,在项目初期的数据分析中,能帮助发现数据背后的规律,发挥了巨大作用。但由于其存在至少 4 个明显的缺陷,造成了其结果的不可控,因此通常在实际工程中不会高频使用。

最优k值的选取:(手肘法)

手肘法的核心指标是SSE(sum of the squared errors,误差平方和)

其中,Ci是第i个簇,p是Ci中的样本点,mi是Ci的质心(Ci中所有样本的均值),SSE是所有样本的聚类误差,代表了聚类效果的好坏。

手肘法的核心思想是:随着聚类数k的增大,样本划分会更加精细,每个簇的聚合程度会逐渐提高,那么误差平方和SSE自然会逐渐变小。并且,当k小于真实聚类数时,由于k的增大会大幅增加每个簇的聚合程度,故SSE的下降幅度会很大,而当k到达真实聚类数时,再增加k所得到的聚合程度回报会迅速变小,所以SSE的下降幅度会骤减,然后随着k值的继续增大而趋于平缓,也就是说SSE和k的关系图是一个手肘的形状,而这个肘部对应的k值就是数据的真实聚类数。当然,这也是该方法被称为手肘法的原因。

代码示例:

import jieba
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
from sklearn.decomposition import PCAclass KmeansClustering():def __init__(self, stopwords_path=None):self.stopwords = self.load_stopwords(stopwords_path)self.vectorizer = CountVectorizer()self.transformer = TfidfTransformer()def load_stopwords(self, stopwords=None):"""加载停用词:param stopwords::return:"""if stopwords:with open(stopwords, 'r', encoding='utf-8') as f:return [line.strip() for line in f]else:return []def preprocess_data(self, corpus_path):"""文本预处理,每行一个文本:param corpus_path::return:"""corpus = []with open(corpus_path, 'r', encoding='utf-8') as f:for line in f:corpus.append(' '.join([word for word in jieba.lcut(line.strip()) if word not in self.stopwords]))return corpusdef get_text_tfidf_matrix(self, corpus):"""获取tfidf矩阵:param corpus::return:"""tfidf = self.transformer.fit_transform(self.vectorizer.fit_transform(corpus))# 获取词袋中所有词语# words = self.vectorizer.get_feature_names()# 获取tfidf矩阵中权重weights = tfidf.toarray()return weightsdef pca(self, weights, n_components=2):"""PCA对数据进行降维:param weights::param n_components::return:"""pca = PCA(n_components=n_components)return pca.fit_transform(weights)def kmeans(self, corpus_path, n_clusters=5, fig=True):"""KMeans文本聚类:param corpus_path: 语料路径(每行一篇),文章id从0开始:param n_clusters: :聚类类别数目:return: {cluster_id1:[text_id1, text_id2]}"""corpus = self.preprocess_data(corpus_path)weights = self.get_text_tfidf_matrix(corpus)pca_weights = self.pca(weights)clf = KMeans(n_clusters=n_clusters)# clf.fit(weights)y = clf.fit_predict(weights)if fig:plt.scatter(pca_weights[:, 0], pca_weights[:, 1], c=y)plt.show()# 中心点centers = clf.cluster_centers_print('中心点', centers)# 用来评估簇的个数是否合适,距离约小说明簇分得越好,选取临界点的簇的个数score = clf.inertia_print("评估簇的个数是否合适", score)# 每个样本所属的簇result = {}for text_idx, label_idx in enumerate(y):if label_idx not in result:result[label_idx] = [text_idx]else:result[label_idx].append(text_idx)return resultdef elbow_algorithm(self, corpus_path, n_clusters_iterations=12):"""肘部算法  确定最优聚类类别数目:param n_clusters_iterations: 聚类类别数目:param corpus_path: 语料路径(每行一篇),文章id从0开始:return:"""corpus = self.preprocess_data(corpus_path)weights = self.get_text_tfidf_matrix(corpus)SSE = []  # 存放每次结果的误差平方和for k in range(1, n_clusters_iterations):clf = KMeans(n_clusters=k)  # 构造聚类器clf.fit(weights)SSE.append(clf.inertia_)  # clf.inertia_获取聚类准则的总和(用来评估簇的个数是否合适,距离约小说明簇分得越好,选取临界点的簇的个数)X = range(1, n_clusters_iterations)plt.xlabel('k')plt.ylabel('SSE')plt.plot(X, SSE, 'o-')plt.show()

if __name__ == '__main__':Kmeans = KmeansClustering(stopwords_path='./data/stop_words.txt')# 肘部算法  确定 簇的最优Kmeans.elbow_algorithm('./data/test_data.txt',24)result = Kmeans.kmeans('./data/test_data.txt', n_clusters=18)

kmeans设置中心_Kmeans 聚类算法相关推荐

  1. kmeans设置中心_kmeans聚类与支持向量机(1)

    本篇文章主要讲一下k-means聚类和支持向量机(SVM),这两种方法都是机器学习中基本的分类方法(分类一词可能不准确),作用都是把一堆数据按照一定的规则分成两类或几类. 该篇文章还是注重于通过pyt ...

  2. K-means与DBSCAN聚类算法

    K-means与DBSCAN聚类算法 前言:目前数据聚类方法大体上可以分为划分式聚类方法(Partition-based Methods).基于密度的聚类方法(Density-based method ...

  3. kmeans算法_KMeans聚类算法详解

    1. 写在前面 如果想从事数据挖掘或者机器学习的工作,掌握常用的机器学习算法是非常有必要的,常见的机器学习算法: 监督学习算法:逻辑回归,线性回归,决策树,朴素贝叶斯,K近邻,支持向量机,集成算法Ad ...

  4. k means聚类算法_K-Means 聚类算法 20210108

    说到聚类,应先理解聚类和分类的区别 聚类和分类最大的不同在于:分类的目标是事先已知的,而聚类则不一样,聚类事先不知道目标变量是什么,类别没有像分类那样被预先定义出来. K-Means 聚类算法有很多种 ...

  5. k-means(k均值聚类)算法介绍及实现(c++)

    基本介绍: k-means 算法接受输入量 k :然后将n个数据对象划分为 k个聚类以便使得所获得的聚类满足:同一聚类中的对象相似度较高:而不同聚类中的对象相似度较小.聚类相似度是利用各聚类中对象的均 ...

  6. 浅尝辄止_数学建模(笔记_K-means聚类算法)

    文章目录 一.聚类模型 二.K-means聚类算法 1.算法的流程步骤 2.优点 3.缺点 三.K-means++算法 1. 算法的流程步骤 四.SPSS软件求解K-means++算法 五.K-mea ...

  7. K-means和PAM聚类算法Python实现及对比

    K-means(K均值划分)聚类:简单的说,一般流程如下:先随机选取k个点,将每个点分配给它们,得到最初的k个分类:在每个分类中计算均值,将点重新分配,划归到最近的中心点:重复上述步骤直到点的划归不再 ...

  8. python聚类分析鸢尾花_K-Means 聚类算法实现鸢尾花数据的聚类

    #!/usr/bin/env Python3 # -*- coding: utf-8 -*- # @Software: PyCharm # @virtualenv:workon # @contact: ...

  9. 【数据挖掘】十大算法之K-Means K均值聚类算法

    目录 1 Kmeans步骤 2 kmeans损失函数 3 优缺点 4 如何调优和改进 5 改进的算法 1 Kmeans步骤 (1)数据预处理,如归一化.离群点处理等 (2)随机选取K个簇中心,记为u1 ...

最新文章

  1. 当用户控件有异动时,网页某部位作出相应变化
  2. 24点——判断4个数能否经过运算使得结果为24
  3. Windows端口占用情况?
  4. BlackBerry App之Hello World
  5. [网络流24题] 最长k可重线段集问题 (费用流)
  6. 笔记之_Java整理IO流
  7. .NET framework 4.0 安装失败的解决方案
  8. 创业商业计划PPT模板
  9. 【蓝桥杯试题】盾神与困难数独
  10. ylbtech-dbs:ylbtech-4,PurpleHouse(房地产楼盘销售系统)
  11. SQL:with ties
  12. IP技术 -- 6 Telemetry
  13. 关于word文档误点不保存后文档的恢复
  14. 大华视频实时调用视频
  15. Netlogon 特权提升漏洞(CVE-2020-1472)原理分析与验证
  16. MOV AX,DATA MOV DS,AX
  17. 流利阅读 2019.1.5 Gatekeeper at Japan’s ‘Suicide Forest’ hopes music can save lives
  18. 安卓电子书格式_[技巧] 无敌的boss级电子书阅读app,全能高手就要一个打十个。...
  19. DGA - 研究内容整理
  20. 移民加拿大,你们后悔了么?

热门文章

  1. mount 命令中文man
  2. O‘REILLY: Lightbulb Start Watching —— 从指定时间开始计算多组时间差之和(秒数)
  3. 华为HarmonyOS App开发工具DevEco Studio下载安装及第一个HarmonyOS App实战教程
  4. 以假乱真的日用品,大家小心了。
  5. 无CUDA支持的dlib库的安装与使用
  6. IE11浏览器设置为兼容不同IE版本
  7. nodeJS exports
  8. 大数据 杨栋_大数据应用案例
  9. java中random方法取值范围_java的Random类详解
  10. 伯凡时间-160218 十个能让你的无形资产增值的好习惯(转)