当前位置: 首页 > article >正文

机器学习篇-day08-聚类Kmeans算法

一. 聚类算法简介

概念

无监督学习算法

根据样本之间的相似性,将样本划分到不同的类别中;不同的相似度计算方法,会得到不同的聚类结果,常用的相似度计算方法有欧式距离法。

聚类算法的目的是在没有先验知识的情况下,自动发现数据集中的内在结构和模式。

使用不同的聚类准则, 产生的聚类结果不同

应用场景

聚类算法分类

根据聚类颗粒度分类

根据实现方法分类

  1. K-means:按照质心分类,主要介绍K-means,通用、普遍

  2. 层次聚类:对数据进行逐层划分,直到达到聚类的类别个数

  3. DBSCAN聚类是一种基于密度的聚类算法

  4. 谱聚类是一种基于图论的聚类算法

总结

聚类概念

无监督学习算法,主要用于将相似的样本自动归到一个类别中;计算样本和样本之间的相似性,一般使用欧式距离

聚类分类

颗粒度:粗聚类、细聚类。

实现方法: K-means聚类、层次聚类、 DBSCAN聚类、谱聚类

二. API

Kmeans算法的API

Kmeans-API实践

聚类算法API

构造数据API

数据-结果

流程

代码

import os
​
os.environ["OMP_NUM_THREADS"] = '4'     # 解决内存泄露警告
​
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
from sklearn.metrics import calinski_harabasz_score
import matplotlib.pyplot as plt
​
​
# 1. 构建数据集
# x是样本(点的横纵坐标), y是标签
x, y = make_blobs(
    n_samples=1000,  # 样本数
    n_features=2,  # 特征数: x, y
    centers=[[-1, -1], [0, 0], [1, 1], [2, 2]],  # 聚类中心, 也可以写数字表示中心点的数量
    cluster_std=[0.4, 0.2, 0.2, 0.2],  # 聚类标准差, 默认为1, 也可以写数字表示所有点的标准差
    random_state=21
)
# print(x)
# print(y)
# 绘图显示数据集
plt.figure()
plt.scatter(x[:, 0], x[:, 1], marker='o')
plt.show()
​
​
# 2. 模型训练预测
model = KMeans(
    n_clusters=4,   # 蕨类中心的数量 
    random_state=21
)
y_pred = model.fit_predict(x)
​
​
# 3. 显示聚类效果
plt.scatter(x[:, 0], x[:, 1], c=y_pred)
plt.show()
​
​
# 4. 模型评估
print(calinski_harabasz_score(x, y_pred))

结果

三. ★Kmeans实现流程

★实现流程原理

  1. 事先确定常数K ,常数K意味着最终的聚类类别数

  2. 随机选择K 个样本点作为初始聚类中心

  3. 计算每个样本到 K 个中心的距离,选择最近的聚类中心点作为标记类别

  4. 根据每个类别中的样本点,重新计算出新的聚类中心点(各聚类类别内点的平均值),如果计算得出的新中心点与原中心点一样则停止聚类,否则重新进行第 2 步过程直到聚类中心不再变化

举例说明

原始数据

流程

  1. 随机设置K个特征空间内的点作为初始的聚类中心(本案例中设置p1和p2)

  2. 对于其他每个点计算到K个中心的距离,选择最近的一个聚类中心点作为标记类别

  3. 接着对标记的聚类中心,重新计算每个聚类的新中心点(平均值)

  4. 如果计算得出的新中心点与原中心点一样(质心不再移动),那么结束,否则重新进行第二步过程【经过判断,需要重复上述步骤,开始新一轮迭代】

总结

四. ★★模型评估方法

SSE聚类评估指标👇

原理

误差平方和SSE (The sum of squares due to error)

SSE 越小,表示数据点越接近它们的中心,聚类效果越好

代码演示-肘方法-SSE

肘方法确定K值(n_clusters=聚类中心点个数(肘点))

import os
​
os.environ["OMP_NUM_THREADS"] = '4'  # 解决内存泄露警告
​
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
from sklearn.metrics import calinski_harabasz_score
import matplotlib.pyplot as plt
​
plt.rcParams['font.sans-serif'] = ['SimHei']  # 正常显示汉字
plt.rcParams['axes.unicode_minus'] = False  # 正常显示负号
​
# 1. 构建数据集
# data是样本(点的横纵坐标), label是标签
data, label = make_blobs(
    n_samples=1000,  # 样本数
    n_features=2,  # 特征数: x, y坐标, 特征的两列
    centers=[[-1, -1], [0, 0], [1, 1], [2, 2]],  # 聚类中心, 也可以写数字表示中心点的数量
    cluster_std=[0.4, 0.2, 0.2, 0.2],  # 聚类标准差, 默认为1, 也可以写数字表示所有点的标准差
    random_state=21
)
​
sse_list = []
# 2. 遍历不同聚类中心数量, 计算sse
for clu_num in range(1, 100):
    kmeans = KMeans(n_clusters=clu_num, max_iter=100, random_state=21, n_init='auto')
    kmeans.fit(data)
    sse_list.append(kmeans.inertia_)    # 误差平方和(sse)
    # print(kmeans.inertia_)
​
# 根据中心点个数作为横坐标, 误差平方和(sse)作为纵坐标, 画出sse曲线
plt.figure(figsize=(20, 10), dpi=100)
plt.xticks(range(1, 100, 3), label=range(1, 100, 3))
plt.xlabel('n_clusters')
plt.ylabel('sse')
plt.title('SSE肘方法')
plt.grid()
plt.plot(range(1, 100), sse_list, 'or-')
plt.show()

结果图

肘方法的原理-K值

“肘”方法 (Elbow method) - K值确定(聚类中心的个数)

"肘"方法通过SSE确定n_clusters(聚类中心的个数)的

  1. 对于n个点的数据集,迭代计算 k from1 to n,每次聚类完成后计算 SSE

  2. SSE 是会逐渐变小的,因为每个点都是它所在的簇中心本身。

  3. ★SSE 变化过程中会出现一个拐点,下降率突然变缓时即认为是最佳 n_clusters 值。

  4. 在决定什么时候停止训练时,肘形判据同样有效,数据通常有更多的噪音,在增加分类无法带来更多回报时,我们停止增加类别。

SC聚类评估指标👆

原理

SC轮廓系数法(Silhouette Coefficient)

轮廓系数法考虑簇内的内聚程度(Cohesion)簇外的分离程度(Separation). 其计算过程如下

  1. 对计算每一个样本i 到同簇内其他样本的平均距离 ai,该值越小,说明簇内的相似程度越大

  2. 计算每一个样本 i 到最近簇 j 内的所有样本的平均距离 bij,该值越大,说明该样本越不属于其他簇j

  3. 根据下面公式计算该样本的轮廓系数:S = (b -a)/(max⁡(a, b))

  4. 计算所有样本的平均轮廓系数

  5. 轮廓系数的范围为:[-1, 1],SC值越大聚类效果越好

代码演示

sc_list = []
    for clu_num in range(2, 100):
        kmeans = KMeans(n_clusters=clu_num, max_iter=100, random_state=21, n_init='auto')
        kmeans.fit(data)
        y_pred = kmeans.predict(data)
        sc_list.append(silhouette_score(data, y_pred))
    plt.figure(figsize=(20, 10), dpi=100)
    plt.xticks(range(1, 100, 3), label=range(1, 100, 3))
    plt.xlabel('n_clusters')
    plt.ylabel('sc')
    plt.title('SC轮廓系数法')
    plt.grid()
    plt.plot(range(2, 100), sc_list, 'or-')
    plt.show()

结果图

CH聚类评估指标👆

原理

聚类效果评估 – CH轮廓系数法(Calinski-Harabasz Index)

CH 系数考虑簇内的内聚程度、簇外的离散程度质心的个数

CH越大越好

代码演示

ch_list = []
    for clu_num in range(2, 100):
        kmeans = KMeans(n_clusters=clu_num, max_iter=100, random_state=21, n_init='auto')
        kmeans.fit(data)
        y_pred = kmeans.predict(data)
        ch_list.append(calinski_harabasz_score(data, y_pred))
    plt.figure(figsize=(20, 10), dpi=100)
    plt.xticks(range(1, 100, 3), label=range(1, 100, 3))
    plt.xlabel('n_clusters')
    plt.ylabel('CH')
    plt.title('CH轮廓系数法')
    plt.grid()
    plt.plot(range(2, 100), ch_list, 'ob-')
    plt.show()

结果图

总结

五. 案例-顾客数据聚类分析

需求

代码

# -*- coding: utf-8 -*-
# @FileName : 03-顾客数据分析.py
# @Author   : YuanLitao
# @Time     : 2024/10/15 16:06
import os
​
os.environ["OMP_NUM_THREADS"] = '1'  # 解决内存泄露警告
​
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
​
plt.rcParams['font.sans-serif'] = ['SimHei']  # 正常显示汉字
plt.rcParams['axes.unicode_minus'] = False  # 正常显示负号
​
​
def demo01_find_best_k():
    # 数据获取
    data = pd.read_csv('data/customers.csv')
    # 获取特征
    # 根据顾客的收入和消费水平对客户进行分类
    x = data.iloc[:, [3, 4]]
    # 循环创建多个分类中心点, 找到最优的分类中心点
    sse_list = []
    sc_list = []
    for i in range(2, 21):
        kmeans = KMeans(n_clusters=i)
        kmeans.fit(x)
        y_pred = kmeans.predict(x)
        sse_list.append(kmeans.inertia_)
        sc_list.append(silhouette_score(x, y_pred))
​
    # 3. 数据可视化
    plt.figure(figsize=(20, 10), dpi=100)
    plt.title("sse")
    plt.xticks(range(2, 21))
    plt.plot(range(2, 21), sse_list, 'or-')
    plt.show()
​
    plt.figure(figsize=(20, 10), dpi=100)
    plt.title("sc轮廓系数")
    plt.xticks(range(2, 21))
    plt.plot(range(2, 21), sc_list, 'or-')
    plt.show()
​
​
def demo02_kmeans():
    # 数据获取
    data = pd.read_csv('data/customers.csv')
    # 获取特征
    x = data.iloc[:, [3, 4]]
    # 模型训练
    kmeans = KMeans(n_clusters=5, random_state=21)
    kmeans.fit(x)
    # 模型预测
    y_pred = kmeans.predict(x)
    print(y_pred)
    print(kmeans.cluster_centers_)
​
    # 可视化
    plt.figure(figsize=(20, 10), dpi=100)
    plt.scatter(x.values[y_pred == 0, 0], x.values[y_pred == 0, 1], s=100, c='red', label='学生用户')
    # 把类别是1的, 第0类数据,第1列数据, 作为x/y, 传给plt.scatter函数
    plt.scatter(x.values[y_pred == 1, 0], x.values[y_pred == 1, 1], s=100, c='blue', label='正常用户')
    # 把类别是2的, 第0类数据,第1列数据, 作为x/y, 传给plt.scatter函数
    plt.scatter(x.values[y_pred == 2, 0], x.values[y_pred == 2, 1], s=100, c='green', label='低消费用户')
    plt.scatter(x.values[y_pred == 3, 0], x.values[y_pred == 3, 1], s=100, c='cyan', label='普通用户')
    plt.scatter(x.values[y_pred == 4, 0], x.values[y_pred == 4, 1], s=100, c='magenta', label='黄金用户')
    plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s=300, c='black', label='质心')
​
    plt.title('Clusters of customers')
    plt.xlabel('Annual Income (k$)')
    plt.ylabel('Spending Score (1-100)')
    plt.legend()
    plt.show()
​
​
if __name__ == '__main__':
    # demo01_find_best_k()    # 看图得k=5时是最优的聚类中心点数量
    demo02_kmeans()

结果图


http://www.kler.cn/news/355685.html

相关文章:

  • Java项目-基于Springboot的在线外卖系统项目(源码+说明).zip
  • 腾讯PAG 动画库Android版本的一个问题与排查记录
  • CVE-2022-26965靶机渗透
  • LLM - 配置 ModelScope SWIFT 测试 Qwen2-VL 图像微调(LoRA) 教程(2)
  • react里实现左右拉伸实战
  • YOLO11改进 | 注意力机制 | 添加双重注意力机制 DoubleAttention【附代码+小白必备】
  • 86.#include预处理命令(1)
  • 【最新华为OD机试E卷-支持在线评测】VLAN资源池(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)
  • C# 实操高并发分布式缓存解决方案
  • Git中Update和Pull的区别
  • H.264 编码参数优化策略
  • 时序数据库 TDengine 支持集成开源的物联网平台 ThingsBoard
  • 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-17
  • 【计算机网络 - 基础问题】每日 3 题(四十八)
  • 简单说说 spring是如何实现AOP的(源码分析)
  • try increasing the minimum deployment target IOS
  • Trimble三维激光扫描开启工业元宇宙的安全“智造”之路-沪敖3D
  • 【PyTorch][chapter30][transformer-3]
  • Apache SeaTunnel 介绍
  • 用 Git Stash 临时保存修改,轻松切换任务!