机器学习 | 聚类算法(K-means)
学习前,大家可以先了解一下这些概念
概念参考此链接整理:8-9-机器学习-聚类算法-Kmeans
聚类:
把没有类别的一组数据(原始数据没有分类),根据样本与样本之间的相关性,分到已有的类别中(无监督学习)。
-
簇:KMeans算法将一组N个样本的特征矩阵X划分为K个无交集的簇(相当于是一个组)(簇的个数与质心相同
-
质心:簇中所有数据的均值u通常被称为这个簇的“质心”(x求均值,y求均值,得到的这个点)
-
KMeans算法:随机抽k个样本作为质心,将原始样本分到离它最近的质心,得到k个簇,计算每个簇均值得到新的质心,再次将样本重新划分到新的质心形成新的簇,以此循环,直到质心不发生变化。这个时候聚类就完成,将每个簇作为一个类别。
-
聚类算法追求“簇内差异小,簇外差异大” (而这个“差异“,由样本点到其所在簇的质心的距离来衡量)
-
簇内平方和:一个簇中所有样本点到质心的距离的平方和为簇内平方和。使用簇内平方和就可以表示簇内差异的大小**(越大差异越大)**
-
整体平方和:将每个簇的簇内平方和相加就得到了整体平方和
-
KMeans算法有损失函数吗?
- 有:可以求解最小整体平方和所对应的最优质心的位置,整体平方和就可以作为损失函数(质心越优,整体平方和就越小)
- 没有:损失需要通过*拟合效果来恒定,拟合的越好损失就越小,拟合不好损失就越大,但****KMeans模型没有标签所以无法计算拟合程度*****
-
API:
from sklearn.cluster import KMeans
- 重要参数
- n_clusters(簇的个数)
- random_state(初始化质心)
- 重要参数
-
聚类predict:数据量大的时候使用少量数据求得质心,再用模型通过predict求得分类 (这样聚类效果会差一些,但会减少我们的计算成本)
接下来我们正式开始学习啦!!!
无监督学习与聚类算法
-
聚类算法又叫做“无监督分类”,其目的是将数据划分成有意义或有用的组(或簇)。
-
无监督的算法在训练的时候只需要特征矩阵X,不需要标签。
-
聚类算法就是无监督学习的代表算法。
聚类和分类
聚类 | 分类 | |
---|---|---|
核心 | 将数据分成多个组、探索每个组的数据是否有联系 | 从已经分组的数据中去学习、把新数据放到已经分好的组中去 |
学习类型 | 无监督,无需标签进行训练 | 有监督,需要标签进行训练 |
典型算法 | K-Means,DBSCAN,层次聚类,光谱聚类 | 决策树,贝叶斯,逻辑回归 |
算法输出 | 聚类结果是不确定的、不一定总是能够反映数据的真实分类、同样的聚类,根据不同的业务需求、可能是一个好结果,也可能是一个坏结果 | 分类结果是确定的、分类的优劣是客观的、不是根据业务或算法需求决定 |
聚类的概念:
- 聚类分析,将数据对象分组成为多个簇(组)
- 同一簇中的对象彼此相似
- 不同簇中的对象彼此相异
- 聚类分析追求的目标是:簇内间距小,簇外间距大
聚类算法的功能:
- 作为一个独立的工具来获得数据分布的情况
- 作为其他算法(如:特征和分类)的预处理步骤
聚类算法的应用场景:
- 市场营销:帮市场分析人员从客户基本库中发现不同的客户群,从而可以对不同的客户群采用不同的营销策略。
- 保险业:发现汽车保险中索赔率较高的客户群
- 城市规划:根据房子的类型、价值和地理位置对其进行分组
- 地震研究:将观测到的震中点沿板块断裂带进行聚类,得出地震高危区
聚类算法的评判标准:
- 可扩展性:大多数来自于机器学习和统计学领域的聚类算法在处理数百万条数据时能表现出高效率。
- 处理不同数据类型的能力:数字型、二元类型、图像型等等
- 发现任意形状的能力:基于距离的聚类算法往往发现的是球形的聚类【因为基本都是以欧式计算公式进行计算,由数据中心向外扩展】,其实现实的聚类是任意形状的
- 处理噪声数据的能力:对空缺值、离群点、数据噪声不敏感
- 对于输入数据的顺序不敏感:同一个数据集合,以不同的次序提交给同一个算法,应该产生相似的结果
聚类中的数据结构
聚类算法采用以下两种数据结构:
数据矩阵:行代表不同的数据,列为数据的属性。
相似度矩阵:存储n个对象两两之间的相似度。
聚类算法的距离计算
- 对象间的相似度:是基于两个对象间的1/距离来计算的
- 欧氏距离
- Manhattan距离
数据需要注意的问题
数据标准化避免度量单位的影响
from sklearn import preprocessing
import numpy as np
X_train = np.array([[ 1., -1., 2.],[ 2., 0., 0.],[ 0., 1., -1.]])
X_scaled = preprocessing.scale(X_train) #scale 数组标准化。
X_scaled
划分聚类
主要聚类方式:
- 基于划分的方法
- 基于层次的方法
- 基于密度的方法
基于划分的方法:
- 划分方法(Partitioning method): 将数据集中的数据对象分配到n个簇中,并且通过设定目标函数来驱使算法趋向于目标
- 每个组至少包含一个对象
- 每个对象必须属于且只属于一个组
K-means聚类方式
K-Means(K均值)算法是划分聚类算法中的一种,其中K表示簇的数量,means表示均值。算法通过预先设定的 K值及每个簇的初始质心对相似的数据点进行划分。并通过划分后的均值迭代优化获得最优的聚类结果
K-means聚类方式
K-Means算法的伪代码如下:
-
1.从D中任意选择k个对象作为初始簇的质心
-
2.根据簇质心的值,将每个数据分配到最相似的簇
-
3.计算簇均值,更新簇质心值
-
4.Repeat:2~3
-
5.until簇中心不在发生变化为止。
关键词:K表示簇的数量,means表示均值,初始质心,划分,迭代
质点是质量分布的平均位置,是最能代表一个簇的点
算法的目标是什么?
- 聚类的目的是为了获取子集中的数据对象尽可能的相似,且与其他不同子集或簇内的数据尽可能的相异。
质心为什么需要改变?
- 质心不停的改变,才能尽可能的符合聚类的目标
质心对样本的代表函数
一个衡量质心对簇样本紧凑程度的代表指标是 RSS (Residual Sum of Squares, 残差平方和) ,即所有数据到其簇质心距离的平方和,公式为:
K-means聚类执行过程
K-means的结束条件
- 当迭代一个固定次数后停止
- 当RSS低于某个阈值时停止
- 当质心不再改变后停止
划分聚类sklearn调用学习
from sklearn.cluster import KMeans
import numpy as np
# 模拟数据
X = np.array([[1, 2], [1, 4], [1, 0], [4, 2], [4, 4], [4, 0]])
# 创建 KMeans 模型,并将数据聚类为两组
kmeans = KMeans(n_clusters=2, random_state=0).fit(X)
# 获取聚类结果
labels = kmeans.labels_
# 获取聚类中心
cluster_centers = kmeans.cluster_centers_
print("聚类结果:", labels)
print("聚类中心:", cluster_centers)
!!!使用时重点是理解X应该是什么
:是训练的特征矩阵X
层次聚类
引入:基于划分聚类具有概念简单、速度快的优点,但是同时也有很多缺点:它们需要预先定义簇的数目。
层次聚类(hierarchical clustering)是指对与给定的数据集对象,我们通过层次聚类算法获得一个具有层次结构的数据集合子集结合的过程。
层次聚类分为两种:
- 自底向上的凝聚法;
- 自顶向下的分裂法
凝聚层次聚类
凝聚法指的是初始时将每个样本点当做一个簇,所以原始簇的数量等于样本点的个数,然后依据某种准则合并这些初始的簇,直到达到某种条件或者达到设定的簇的数目。
某种准则可以是相似度
基本算法流程:
-
计算各数据间的相似度矩阵
-
每个数据就是一个簇
-
Repeat:第4~5步
-
合并两个最相似的簇形成新簇
-
更新相似度矩阵
-
Until 只剩一个类簇
层次聚类运行过程
层次聚类不需要事先指定簇的数目,设定层次树高度就可以达到任意选
择簇数量的目的。
层次聚类问题
簇间相似度
◼ MIN(单连接):单链接的计算方法是将两个簇的数据点中距离最近的两
个数据点间的距离作为这两个簇的距离
这种方法容易受到极端值的影响。两个并非很相似的簇可能由于其中的
某个极端的数据点距离较近而组合在一起
单连接产生非常分散的簇,擅长处理非球形簇
对离群点和噪声敏感
◼ MAX(全连接):全链接(Complete Linkage)的计算方法与单链接相反,将两个簇的数据点中距离最远的两个数据点间的距离作为这两个簇的距离。
对那些与总体结构不太一致的离群点给予了过多的关注。也就是说,全连接聚类并不能找出最直观的簇结构,容易打破大团。
对离群点和噪声敏感
◼ Group Average(组平均):组平均(Average Linkage)的计算方法是计算两个簇的数据点中的每个数据点与其他所有数据点的距离:
对单链接和全链接的权衡,组平均链接方法计算量比较大,但结果比前两种方法合理。
对噪声和离群点没那么敏感。
◼ Distance Between Centroids(质心距离):质心距离(Distance Between Centroids)的计算方法是将两个簇的质心距离作为这两个簇的距离。
质心距离聚类优势:
- 减少组平均方法计算量比较大问题
- 对噪声和离群点没那么敏感
- 偏向于球型簇
层次聚类特点
- 不需要输入聚类数目k
- 一旦一个合并被执行,就不能修正
- 没有一个全局最优化的目标函数
- 计算量较大
使用方法:
AgglomerativeClustering(n_clusters=2, *, affinity='euclidean', memory=None, connectivity=None, compute_full_tree='auto',linkage='ward', distance_threshold=None, compute_distances=False,)
代码实现层次聚类
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import AgglomerativeClustering
from scipy.cluster.hierarchy import dendrogram, linkage
# 生成一些示例数据
np.random.seed(0)
X = np.random.rand(10, 2) # 10个样本,每个样本有2个特征
# 执行层次聚类
clustering = AgglomerativeClustering(n_clusters=3).fit(X)
#查看聚类之后样本所属类别
print(clustering.labels_)
# 可视化聚类结果的树状图
linkage_matrix = linkage(X, "ward")
dendrogram(linkage_matrix)
plt.show()
思考:
尝试用层次聚类对abalone.txt进行聚类,当K=3,4,5时,依次给出聚类的轮廓系数及效果图展示图,并说明应该聚类多少类是最优的?
尝试用层次聚类对abalone.txt进行聚类,当K=3,4,5时,依次给出聚类的轮廓系数及效果图展示图,并说明应该聚类多少类是最优的?
聚类模型评估指标
- 聚类质量的评测是主观且困难的,通常有两种方法对模型进行评估:
- 外部方法:有监督的类标进行对比或者专家构建基准
- 内部方法:轮廓系数、组内平方和、整体平方和等等
轮廓系数
-
测聚类结果好坏的一个方式是观察集群分离的离散程度,集群分离的离散程度的计算方式我们称为轮廓系数
-
==轮廓系数的值是介于 [-1,1] ,越趋近于1代表内聚度和分离度都相对较优。==将所有点的轮廓系数求平均,就是该聚类结果总的轮廓系数
-
聚类算法所追求的是:组内差异小(越紧凑),组间差异大(间隔远)
使用:
sklearn.metrics.silhouette_score(X,labels,metric='euclidean')
import numpy as np
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
# 生成一些示例数据
np.random.seed(0)
X = np.array([[1, 2], [1, 4], [1, 0],
[4, 2], [4, 4], [4, 0]])
# 使用K-means算法进行聚类
kmeans = KMeans(n_clusters=2, random_state=0)
kmeans.fit(X)
labels = kmeans.labels_
# 计算轮廓系数
silhouette_avg = silhouette_score(X, labels)
print("轮廓系数:", silhouette_avg)
# 获取簇内平方和
inertia = kmeans.inertia_
print("簇内平方和:", inertia)
# 获取整体平方和
total_inertia = np.sum((X - np.mean(X, axis=0))**2)
print("整体平方和:", total_inertia)
其他知识点
当数据很大,使用层次聚类的效果图过于复杂时,可以选取部分数据展示
#随机选取数据
import pandas
#随机从数据集中抽取10行数据,并且保证下次抽取时与此次抽取结果一样
X1=X.sample(n=10,axis=0)
X2=X1.sample(n=2, axis=1)#随机取两列
X=np.array(X2)#格式转换
X
选择最优的聚类数k的原则是:
k应该使聚类结果的轮廓系数最大。当k增大时,轮廓系数通常会先增加后减小,因为当k增大时,簇内的点会更加密集,而簇与簇之间的距离会变大,同时聚类的质量也会下降。因此,我们可以通过绘制轮廓系数随k变化的曲线来确定最优的聚类数k,即轮廓系数最大的k值。
利用图形选择合适的聚类簇数
#选择合适的聚类簇数 遍历2到10的簇数,给出最优拐点为4的结果
# 通过使用Yellowbrick的KElbowVisualizer来选择合适的聚类簇数
# KElbowVisualizer通过评估不同簇数下的平均畸变程度(SSE)来确定最佳簇数,
# 同时绘制了不同簇数下的SSE与簇数的曲线图。用户可以通过观察曲线图来选择最佳簇数
from yellowbrick.cluster import KElbowVisualizer
from sklearn.cluster import KMeans
n_min = 2
n_max = 10
model = KMeans(init = 'k-means++', random_state = 40) #采用K-means算法
visualizer = KElbowVisualizer(model, k=(n_min,n_max), timings=False)
# 可视化
visualizer.fit(X)
visualizer.show()
声明:
文章个人学习笔记,资料来源于老师课上内容
如有不当,欢迎大家指正!
木木ᶻ: 谢谢你的支持!
近听水无声477: 写得很好呢,加油!!!
CSDN-Ada助手: “恭喜作者发布了新的博客,内容涉及机器学习中的多项式回归,看来作者对于这一领域的知识已经有了深入的理解。希望作者在未来的创作中能够继续分享更多实践经验和案例分析,或许可以考虑加入一些实际项目的应用实例,让读者更好地理解和应用所学知识。期待作者未来更多精彩的创作!”
CSDN-Ada助手: 恭喜你写了这篇关于K-means聚类算法的博客,内容非常有深度和价值。我希望你能继续保持创作的热情,分享更多关于机器学习和聚类算法的知识。或许下一步可以写一些实际案例分析,让读者更好地理解算法在实际应用中的价值。谢谢你的分享,期待你更多的精彩内容!
CSDN-Ada助手: 恭喜你写了这么精彩的博客!对于机器学习和线性回归的介绍非常清晰和详细。希望你能继续分享更多关于机器学习领域的知识。或许下一篇博客可以深入讨论一些实际案例或者应用场景,这样读者能更好地理解线性回归在实际中的应用。期待你的下一篇作品!