机器学习之聚类算法
一、聚类算法简介
1、概念
聚类算法:根据样本之间的相似性,将样本划分到不同的类别中;不同的相似度计算方法,会得到不
同的聚类结果,常用的相似度计算方法有欧式距离法。
聚类算法的目的是在没有先验知识的情况下,自动发现数据集中的内在结构和模式。
无监督学习算法。
使用不同的聚类准则,产生的聚类结果不同。
比如书店里的书,可以按照国家来划分,也可以按照专业来划分,也可以按照漫画书或者文学书去划分,不同的规则划分出去的书也不同。
2、应用场景
(1)用户画像,广告推荐,Data Segmentation,搜索引擎的流量推荐,恶意流量识别
(2)基于位置信息的商业推送 新闻聚类,筛选排序
(3)图像分割,降维,识别;离群点检测,信用卡异常消费;发掘相同功能的基因片段
3、分类
(1)根据聚类颗粒度分类:细聚类和粗聚类

(2)根据实现方法分类
a、K-means:按照质心分类,主要介绍K-means,通用、普遍
b、层次聚类:对数据进行逐层划分,直到达到聚类的类别个数
c、DBSCAN聚类是一种基于密度的聚类算法
d、谱聚类是一种基于图论的聚类算法
二、聚类算法API
1、聚类算法API
sklearn.cluster.KMeans(n_clusters=k)
参数:n_clusters: 开始的聚类中心数量
整形,k:生成的聚类数,即产生的质心(centroids)数。
方法:estimator . fit(x)
estimator . predict(x)
estimator . fit_predict(x):计算聚类中心并预测每个样本属于哪个类别,相当于先
调用fit(x),然后再调用predict(x)。
2、代码案例
随机创建不同二维数据集作为训练集,并结合k-means算法将其聚类,尝试分别聚类不同数量的簇,并观察聚类效果
1. 导包 sklearn.cluster.KMeans sklearn.datasets.make_blobs
2. 创建数据集
3. 实例化Kmeans模型并预测
4. 展示聚类效果
5. 评估聚类效果好坏
# 必须放在第一个位置上
import os
os.environ['OMP_NUM_THREADS']='4'
#导包
from sklearn.cluster import KMeans #聚类API 采用指定 质心 分簇
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
# 默认会按照高斯分布(正态分布)生成数据集 ,只需要 指定 均值 ,标准差
from sklearn.metrics import calinski_harabasz_score
# 评估指标 值越大 , 聚类效果越好
# 1、准备数据
x, y = make_blobs(n_samples = 1000, n_features = 2,\
centers = [[-1,1],[0,0],[1,1],[2,2]],\
cluster_std = [0.4,0.2,0.2,0.2],random_state = 666)
# 2、绘制上述的图形
# 参1: 横坐标 参2: 纵坐标
plt.scatter(x[:,0],x[:,1])
plt.show()
# 3、创建KMeans
# 参1: 聚类数量 参2: 随机种子
es = KMeans(n_clusters = 4, random_state=666)
# 4、模型训练和预测
y_pre = es.fit_predict(x) # 把样本分簇
print(f"预测值:\n{y_pre}")
# 5、绘制预测结果
plt.scatter(x[:,0],x[:,1],c = y_pre)
plt.show()
#6、评估指标
print(f"评估指标:{calinski_harabasz_score(x,y_pre)}") # 数值越大越好
三、KMeans实现流程
1 、事先确定常数K ,常数K意味着最终的聚类类别数
2、随机选择 K 个样本点作为初始聚类中心
3、计算每个样本到 K 个中心的距离,选择最近的聚类中心点作为标记类别
4、根据每个类别中的样本点,重新计算出新的聚类中心点(平均值),如果计算得出的新中心点与原中心点一样则停止聚类,否则重新进行第 3 步过程,直到聚类中心不再变化
四、模型评估方法
1、SSE聚类评估指标
误差平方和SSE (The sum of squares due to error)
Ci 表示簇,k 表示聚类中心的个数,p 表示某个簇内的样本,m 表示质心点
SSE 越小,表示数据点越接近它们的中心,聚类效果越好
"肘" 方法通过 SSE 确定 n_clusters 的值
1. 对于n个点的数据集,迭代计算 k from 1 to n,每次聚类完成后计算 SSE
2. SSE 是会逐渐变小的,因为每个点都是它所在的簇中心本身。
3. SSE 变化过程中会出现一个拐点,下降率突然变缓时即认为是最佳 n_clusters 值。
4.在决定什么时候停止训练时,肘形判据同样有效,数据通常有更多的噪音,在增加分类无法带来更多回报时,我们停止增加类别。
下降率突然变缓时即认为是最佳的k值
代码实现
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '4'
# 导包
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.metrics import silhouette_score, calinski_harabasz_score
# 1、定义函数 演示:SSE + 肘部法
def dm01_see():
# 0、定义SSE列表,目的:记录每个K值的SSE值
sse_list = []
# 1、获取数据
# 参1: 样本数量 参2: 特征数量 参3: 4个簇的质点 参4: std标准差 参5: 随机种子
x,y = make_blobs(
n_samples=1000,
n_features=2,
centers=[[-1, 1], [0, 0], [1, 1], [2, 2]],
cluster_std=[0.4, 0.2, 0.2, 0.2],
random_state=22
)
# 2、for循环 训练 获取每个K值,对应的SSE值
for k in range(1, 100):
# 2.1 创建模型
# 参1: 簇的数量 参2: 最大迭代次数 参3: 固定随机种子
es = KMeans(n_clusters=k,max_iter = 100, random_state= 22)
# 2.2 训练模型
es.fit(x)
# 2.3 获取每个簇的SSE值
sse_value = es.inertia_
# 2.4 将每个K值对应的SSE值,添加到sse_list
sse_list.append(sse_value)
# 3、绘制SSE曲线 -> 数据可视化
# print(sse_list)
# 3.1 创建画布
plt.figure(figsize=(20,10))
# 3.2 设置标题
plt.title("sse value")
# 3.3 设置x轴
plt.xticks(range(0,100,3))
# 参1: K值 参2: 该K值对应的SSE值
# o 代表 圆点样式 r 代表 红色 - 代表 连接数据点的样式(实线)
plt.plot(range(1,100),sse_list,'or-')
plt.xlabel("K")
plt.ylabel("sse")
plt.grid()
plt.show()

2、SC聚类评估指标
轮廓系数法考虑簇内的内聚程度(Cohesion),簇外的分离程度(Separation)。其计算过程如下
1、对计算每一个样本 i 到同簇内其他样本的平均距离 ai,该值越小,说明簇内的相似程度越大
2、计算每一个样本i到最近簇 j 内的所有样本的平均距离 bij,该值越大,说明该样本越不属于其他簇 j
3、根据下面公式计算该样本的轮廓系数:
4、计算所有样本的平均轮廓系数
5、轮廓系数的范围为:[-1, 1],SC值越大聚类效果越好
主要考量:簇内聚程度、簇间分离程度

代码实现
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '4'
# 导包
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.metrics import silhouette_score, calinski_harabasz_score
def dm02_sc轮廓系数法():
# 0、定义sc列表,目的:记录每个K值的SSE值
sc_list = []
# 1、获取数据
# 参1: 样本数量 参2: 特征数量 参3: 4个簇的质点 参4: std标准差 参5: 随机种子
x, y = make_blobs(
n_samples=1000,
n_features=2,
centers=[[-1, 1], [0, 0], [1, 1], [2, 2]],
cluster_std=[0.4, 0.2, 0.2, 0.2],
random_state=22
)
# 3、遍历for循环,获取每个K值,计算对应SC值,并添加到sc_list列表汇总
for k in range(2,100): # 考虑簇外,至少2簇
es = KMeans(n_clusters=k, max_iter=100, random_state=23)
es.fit(x)
y_pre = es.predict(x)
sc_value = silhouette_score(x, y_pre)
sc_list.append(sc_value)
# 绘制sc曲线 -> 数据可视化
plt.figure(figsize=(20,10))
plt.title("sc value")
plt.xticks(range(0,100,3))
plt.xlabel("K")
plt.ylabel("sc")
plt.grid()
plt.plot(range(2,100),sc_list)
plt.show()

3、CH聚类评估指标
CH 系数考虑簇内的内聚程度、簇外的离散程度、质心的个数
分数s高则聚类效果越好
CH达到的目的:用尽量少的类别聚类尽量多的样本,同时获得较好的聚类效果
主要考量:簇内聚程度、簇间分离程度、质心个数
类别内部数据的距离平方和越小越好,类别之间的距离平方和越大越好。聚类的种类数越少越好
m 表示样本数量 k 表示质心个数
SSW 的含义:相当于SSE,簇内距离
表示质心 ,
表示某个样本 ,SSW 值是计算每个样本点到质心的距离,并累加起来 ,SSW 表示表示簇内的内聚程度,越小越好。
SSB 的含义:簇间距离
表示质心,
表示质心的均值,
表示样本的个数 SSB 表示簇与簇之间的分离程度,SSB 越大越好.
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '4'
# 导包
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from sklearn.metrics import silhouette_score, calinski_harabasz_score
def dm03_ch_簇内_簇外_质心点个数():
# 0、定义ch列表,目的:记录每个K值的SSE值
ch_list = []
# 1、获取数据
# 参1: 样本数量 参2: 特征数量 参3: 4个簇的质点 参4: std标准差 参5: 随机种子
x, y = make_blobs(
n_samples=1000,
n_features=2,
centers=[[-1, 1], [0, 0], [1, 1], [2, 2]],
cluster_std=[0.4, 0.2, 0.2, 0.2],
random_state=22
)
# 3、 for循环 k
for k in range(2,100):
es = KMeans(n_clusters=k,max_iter=100,random_state=23)
es.fit(x)
y_pre = es.predict(x)
# 获取每一个簇的ch值
ch_value = calinski_harabasz_score(x,y_pre)
ch_list.append(ch_value)
# 4、绘图 ch 曲线 -> 数据可视化
plt.figure(figsize=(20,10))
plt.title("ch value")
plt.xticks(range(0,100,3))
plt.xlabel("K")
plt.ylabel("ch")
plt.grid()
plt.plot(range(2,100),ch_list,'or-')
plt.show()

五、代码习题
案例:顾客数据聚类分析('customers.csv')
已知:客户性别、年龄、年收入、消费指数
需求:对客户进行分析,找到业务突破口,寻找黄金客户
步骤解析:1、寻找最优K,确定进行评估需要分几类(肘方法、sh系数)
2、按照第1步得到的K进行聚类算法划分数据源,绘图
更多推荐



所有评论(0)