机器学习——聚类算法一

news2024/12/24 2:24:36

机器学习——聚类算法一

文章目录

  • 前言
  • 一、基于numpy实现聚类
  • 二、K-Means聚类
    • 2.1. 原理
    • 2.2. 代码实现
    • 2.3. 局限性
  • 三、层次聚类
    • 3.1. 原理
    • 3.2. 代码实现
  • 四、DBSCAN算法
    • 4.1. 原理
    • 4.2. 代码实现
  • 五、区别与相同点
    • 1. 区别:
    • 2. 相同点:
  • 总结


前言

在机器学习中,有多种聚类算法可以用于将数据集中的样本按照相似性进行分组。本文将介绍一些常见的聚类算法:

  1. K-Means聚类
  2. 层次聚类
  3. DBSCAN算法

在这里插入图片描述

一、基于numpy实现聚类

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from numpy.linalg import norm
import random
np.random.seed(42)
data = np.random.randn(100,2)  #生成一个包含100个样本点的随机数据集,每个样本有2个特征
df = pd.DataFrame(data= data,columns=["x1","x2"])

x1_min, x1_max, x2_min, x2_max = df.x1.min(), df.x1.max() ,df.x2.min(), df.x2.max()

# 初始化两个质心
centroid_1 = np.array([random.uniform(x1_min, x1_max), random.uniform(x2_min, x2_max)])
centroid_2 = np.array([random.uniform(x1_min, x1_max), random.uniform(x2_min, x2_max)])

data = df.values
#设置迭代次数为10
for i in range(10):
    clusters = []
    for point in data:
        centroid_1_dist = norm(centroid_1- point) #计算两点之间的距离
        centroid_2_dist = norm(centroid_2- point)
        cluster = 1
        if centroid_1_dist > centroid_2_dist:
            cluster = 2
        clusters.append(cluster)
    df["cluster"] = clusters

#更换质心(即迭代聚类点)
centroid_1 = [round(df[df.cluster == 1].x1.mean(),3), round(df[df.cluster == 1].x2.mean(),3)]
centroid_2 = [round(df[df.cluster == 2].x1.mean(),3), round(df[df.cluster == 2].x2.mean(),3)]

plt.scatter(x1, x2, c=df["cluster"])
plt.scatter(centroid_1,centroid_2, marker='x', color='red')
plt.show()


在这里插入图片描述

二、K-Means聚类

2.1. 原理

K-means 是一种迭代算法,它将数据集按照距离划分为 K 个簇(其中K是用户预先指定的簇的数量),每个簇代表一个聚类(聚类后同一类数据尽可能聚集到一起,不同类数据分离)。实现步骤如下:

  1. 随机初始化K个质心,每个质心代表一个簇
  2. 将每个样本点分配到距离其最近的质心所代表的簇。(如此就形成了K个簇)
  3. 更新每个簇的质心,(即计算每个簇中样本点的平均值)
  4. 重复步骤2和步骤3,直到质心的位置不再改变或达到预定的迭代次数。

2.2. 代码实现

  1. 导入数据集,以鸢尾花(iris)数据集为例:
from sklearn.datasets import load_iris
import pandas as pd

# 加载数据集
iris = load_iris()

#查看数据集信息
print(iris.keys())
dict_keys(['data', 'target', 'frame', 'target_names', 'DESCR', 'feature_names', 'filename', 'data_module'])

#获取特征数据
data = iris["data"]

# 获取标签数据
target = iris["target"]
print(pd.Series(target).unique())
[0 1 2]


#查看分类名
print(iris["target_names"])
['setosa' 'versicolor' 'virginica']


#整合到数据框
import pandas as pd
df = pd.DataFrame(data= iris["data"],columns= iris["feature_names"])
print(df.head())
   sepal length (cm)  sepal width (cm)  petal length (cm)  petal width (cm)
0                5.1               3.5                1.4               0.2
1                4.9               3.0                1.4               0.2
2                4.7               3.2                1.3               0.2
3                4.6               3.1                1.5               0.2
4                5.0               3.6                1.4               0.2
  1. 确定初始化质点K的取值

肘部法则选择聚类数目:
该方法适用于K值相对较小的情况,随着聚类数目的增加,聚类误差(也称为SSE,Sum of Squared Errors)会逐渐减小。然而,当聚类数目达到一定阈值后,聚类误差的减小速度会变缓,形成一个类似手肘的曲线。这个手肘点对应的聚类数目就是肘部法则选择的合适聚类数目

from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
sse = []
# 设置聚类数目的范围
k_range = range(1, 10)
# 计算每个聚类数目对应的 SSE
for k in k_range:
    kmeans = KMeans(n_clusters=k,random_state = 42)
    kmeans.fit(df)
    sse.append(kmeans.inertia_)

# 绘制聚类数目与 SSE 之间的曲线图
plt.style.use("ggplot")
plt.plot(k_range, sse,"r-o")
plt.xlabel('Number of K')
plt.ylabel('SSE')
plt.title('Elbow Method')
plt.show()

在这里插入图片描述

从图中可看出,当K=3时,该曲线变得比较平缓,则该点为肘部点。即最佳的聚类数目为K=3

  1. 从sklean中调用k-Means算法模型
from sklearn.cluster import KMeans
kmeans = KMeans(n_clusters=3,max_iter= 400,random_state=42)
kmeans.fit(df)
print(kmeans.cluster_centers_)
y_kmeans = kmeans.labels_
df["y_kmeans"] = y_kmeans
  1. 可视化聚类结果

绘制平面图:

plt.scatter(df["sepal length (cm)"], df["sepal width (cm)"], c=df["y_kmeans"], cmap='viridis')
# 绘制聚类中心
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], c='red', marker='x', s=100)
plt.xlabel('Sepal Length')
plt.ylabel('Sepal Width')
plt.title('K-Means Clustering')
handles, labels = sc.legend_elements()
plt.legend(handles, labels)
plt.show()

在这里插入图片描述

绘制三维图:

# 创建3D图形对象
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')
# 绘制散点图
sc = ax.scatter(df["sepal length (cm)"], df["sepal width (cm)"], df["petal length (cm)"], c=df["y_kmeans"], cmap='viridis')

# 绘制聚类中心
ax.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], kmeans.cluster_centers_[:, 2], c='red', marker='x', s=100)

ax.set_xlabel('Sepal Length')
ax.set_ylabel('Sepal Width')
ax.set_zlabel('Petal Length')
ax.set_title('K-Means Clustering')

# 添加图例
handles, labels = sc.legend_elements()
ax.legend(handles, labels)

plt.show()

在这里插入图片描述

2.3. 局限性

k-Means算法通过距离来度量样本之间的相似性,因此对于非凸形状的聚类,算法可能无法正确地将样本划分到正确的聚类中。

k-Means算法对噪声和离群点敏感。这些异常值可能会影响到聚类结果,使得聚类变得不准确

需要事先指定聚类的数量k,而且对结果敏感。如果选择的聚类数量不合适,会导致聚类结果不准确或不理想。

比如这种情况:
在这里插入图片描述

三、层次聚类

3.1. 原理

层次聚类(Agglomerative clustering)算法是一种基于树状结构的聚类方法,分为凝聚型和分裂型层次聚类。

分裂型层次聚类从整个数据集作为一个簇开始,然后逐步将簇分裂为更小的簇,直到达到预定的簇的数量或达到某个停止准则。

凝聚型层次聚类将数据集中的样本逐步合并为越来越大的簇。
即从N个簇开始(每个样本为一个簇),在每个步骤中合并两个最相似的簇,直到达到某个停止准则。

如图所示,从上(下)往下(上):
在这里插入图片描述

优点是可以直观地展示数据点之间的相似性关系,并且不一定要预先指定聚类簇的数量。
层次聚类的缺点是计算复杂度较高,且对数据的噪声和异常值比较敏感。

3.2. 代码实现

参数 linkage: 用于指定链接算法。
“ward” : 单链接,即两个簇的样本对之间距离的min
“complete”: 全链接,即两个簇的样本对之间距离的max
“average”: 均链接,即两个簇的样本对之间距离的mean

参数 affinity : 用于计算距离。
“euclidean”:使用欧几里德距离来计算数据点之间的距离(这是默认的距离度量方法)。
“manhattan”:使用曼哈顿距离来计算数据点之间的距离,它是两个点在所有维度上绝对值之和的总和。
“cosine”:使用余弦相似度来计算数据点之间的距离。

from sklearn.cluster import AgglomerativeClustering
cluster = AgglomerativeClustering()
print(cluster.fit_predict(df))

cluster = AgglomerativeClustering(n_clusters= 3 ,linkage= "complete",affinity="manhattan")
cluster.fit(df)
df["cluster"] = cluster.labels_
print(cluster.labels_)


# 创建3D图形对象
fig = plt.figure(figsize=(8, 6))
ax = fig.add_subplot(111, projection='3d')
plt.style.use("ggplot")

for i in range(len(df["cluster"])):
    if df["cluster"][i] == 0:
        ax.scatter(df["sepal length (cm)"][i], df["sepal width (cm)"][i], df["petal length (cm)"][i],c = "red")
    elif df["cluster"][i] ==1:
        ax.scatter(df["sepal length (cm)"][i], df["sepal width (cm)"][i], df["petal length (cm)"][i],c = "blue")
    else:
        ax.scatter(df["sepal length (cm)"][i], df["sepal width (cm)"][i], df["petal length (cm)"][i],c = "yellow")

ax.set_xlabel('Sepal Length')
ax.set_ylabel('Sepal Width')
ax.set_zlabel('Petal Length')
ax.set_title('Clustering')
plt.show()

在这里插入图片描述

四、DBSCAN算法

4.1. 原理

DBSCAN是一种基于密度的聚类算法,它能够发现任意形状的聚类簇,并且能够识别出噪声点,它将样本划分为核心点、边界点和噪声点。算法的步骤如下:

  1. 随机选择一个未访问的样本点。根据设置的距离半径(eps),称在这一范围的区域为该样本实例的邻域

  2. 如果该样本点的邻域内样本数大于设定的阈值(min_samples),则将其标记为核心点,并将其邻域内的样本点加入到同一个簇中。

  3. 如果该样本点的邻域内样本数小于设定的阈值,则将其标记为边界点。

  4. 重复以上步骤,直到所有样本点都被访问。

  5. 最后,任何不是核心点,且邻域中没有实例样本的样本点都将被标记为噪声点

4.2. 代码实现

from sklearn.cluster import DBSCAN
cluster = DBSCAN(eps= 0.6 , min_samples= 10)
cluster.fit(df)
df["cluster"] = cluster.labels_
print(df)

#-1代表噪声点
print(df["cluster"].value_counts())
 1    88
 0    49
-1    13
Name: cluster, dtype: int64


sc = plt.scatter(df["sepal length (cm)"],df["sepal width (cm)"],c = df["cluster"])
plt.title('DBSCAN Clustering')
handles, labels = sc.legend_elements()
plt.legend(handles, labels)
plt.show()

在这里插入图片描述

from sklearn.cluster import DBSCAN
from sklearn.datasets import make_moons

# 生成随机数据
X, y = make_moons(n_samples=200, noise=0.05) 
print(X)

dbscan = DBSCAN(eps=0.3, min_samples=5)
dbscan.fit(X)

# 获取聚类标签
labels = dbscan.labels_

#因为设置的noise很小,故没有噪声点
print(pd.Series(labels).value_counts())
0    100
1    100
dtype: int64


# 绘制聚类结果
plt.scatter(X[:, 0], X[:, 1], c=labels)
plt.title('DBSCAN Clustering')
handles, labels = sc.legend_elements()
plt.legend(handles, labels)
plt.show()

在这里插入图片描述

五、区别与相同点

1. 区别:

  1. K-means是一种划分聚类算法,它将数据集划分为固定数量的簇(一定要预先指定簇的数量),而层次聚类(不一定要指定簇的数量)和DBSCAN算法(需要指定邻域半径和最小样本数),它们可以自动确定簇的数量。

  2. K-means和层次聚类算法都假设簇具有相同的形状和大小,而DBSCAN算法可以发现任意形状和大小的簇。

  3. K-means和层次聚类算法都对异常值敏感,而DBSCAN算法对异常值不敏感。(可去掉噪声点)

2. 相同点:

K-means、层次聚类和DBSCAN算法都是无监督学习算法中的聚类算法,它们不依赖于标签信息。

这些算法都使用距离或相似性度量来度量样本之间的相似性或距离。


总结

本文从最开始的自己实现聚类到后面的三个机器学习中聚类算法:( K-Means 、层次聚类、DBSCAN聚类)的学习,再到后面对这三个算法的比较与总结。加深了对聚类原理的了解。

我住长江头,君住长江尾;日日思君不见君

–2023-8-31 筑基篇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/957725.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springboot+activiti5.0整合(工作流引擎)

概述 springboot整合activiti使用modeler进行流程创建&#xff0c;编辑、部署以及删除实例&#xff08;可运行&#xff09; 详细 1、现在来说一下流程&#xff0c;先建立spring boot项目&#xff0c;导入对应的jar包。 <dependencies><dependency><groupId&…

Java 循环语句解析:从小白到循环达人

如果你正在学习编程&#xff0c;那么循环语句是一个绕不开的重要话题。循环语句让我们能够重复执行一段代码&#xff0c;从而实现各种各样的功能。在本篇博客中&#xff0c;我们将围绕 Java 编程语言中的循环语句展开&#xff0c;从最基础的概念出发&#xff0c;一步步引领你从…

Qt日历控件示例-QCalendarWidget

基本说明 QCalendarWidget介绍&#xff1a; QCalendarWidget 是 Qt 框架中提供的一个日期选择控件,用户可以通过该控件快速选择需要的日期,并且支持显示当前月份的日历。 这里&#xff0c;我们继承了QCalendarWidget&#xff0c;做了一些简单封装和样式调整 1.使用的IDE&…

java_error_in_idea.hprof 文件

在用户目录下的java_error_in_idea.hprof文件(/Users/用户) 大约1.5个G,IDEA的错误日志,可以删除

shiny根据数据的长度设置多个色板

shiny根据数据的长度设置多个色板 library(shiny) library(colourpicker) ui <- fluidPage(# 添加一个选择颜色的下拉菜单uiOutput("color_dropdown") )server <- function(input, output) {# 数据长度data_length <- reactive({length(c("数据1"…

Linux(centos) 下 Mysql 环境安装

linux 下进行环境安装相对比较简单&#xff0c;可还是会遇到各种奇奇怪怪的问题&#xff0c;我们来梳理一波 安装 mysql 我们会用到下地址&#xff1a; Mysql 官方文档的地址&#xff0c;可以参考&#xff0c;不要全部使用 https://dev.mysql.com/doc/refman/8.0/en/linux-i…

文献阅读:Deep Learning based Semantic Communications: An Initial Investigation

目录 论文简介动机&#xff1a;为什么作者想要解决这个问题&#xff1f;贡献&#xff1a;作者在这篇论文中完成了什么工作(创新点)&#xff1f;规划&#xff1a;他们如何完成工作&#xff1f;理由&#xff1a;通过什么实验验证它们的工作结果自己的看法 论文简介 作者 Huiqiang…

day-06 多进程服务器端 -- 进程间通信

一.多进程服务器端 &#xff08;一&#xff09;进程概念及应用 利用之前学习到的内容&#xff0c;我们的服务器可以按照顺序处理多个客户端的服务请求。在客户端和服务时间增长的情况下&#xff0c;服务器就不足以满足需求了。 1.两种类型的服务器端 &#xff08;1&#xff…

安全基础 --- https详解(02)、cookie和session、同源和跨域

https详解&#xff08;02&#xff09;--- 数据包扩展 Request --- 请求数据包Response --- 返回数据包 若出现代理则如下图&#xff1a; Proxy --- 代理服务器 &#xff08;1&#xff09;http和https的区别 http明文传输&#xff0c;数据未加密&#xff1b;http页面响应速度…

【Java 动态数据统计图】动态X轴二级数据统计图思路Demo(动态,排序,动态数组(重点推荐:难)九(131)

需求&#xff1a; 1.有一组数据集合&#xff0c;数据集合中的数据为动态&#xff1b; 举例如下&#xff1a; [{province陕西省, city西安市}, {province陕西省, city咸阳市}, {province陕西省, city宝鸡市}, {province陕西省, city延安市}, {province陕西省, city汉中市}, {pr…

用了这么久SpringBoot却还不知道的一个小技巧

前言 你可能调第三方接口喜欢启动application&#xff0c;修改&#xff0c;再启动&#xff0c;再修改&#xff0c;顺便还有个不喜欢写JUnitTest的习惯。 你可能有一天想要在SpringBoot启动后&#xff0c;立马想要干一些事情&#xff0c;现在没有可能是你还没遇到。 那么SpringB…

windows10默认浏览器总是自动更改为Edge浏览器

在设置的默认应用设置中把默认浏览器改为chrome或其他之后他自动又会改回Edge。不得不说*软真的狗。 解决办法&#xff1a; 后来发现在Edge浏览器的设置中有这么一个选项&#xff0c;会很无耻的默认是Edge。把它关掉后重新设置就行了。

02. 计算机的组成

1. 从手机和电脑开始 要是20年前&#xff0c;大家对于计算机还很陌生&#xff0c;但是现在手机和电脑已经非常普及了&#xff0c;即使对于偏远地区可能有人没有接触过电脑&#xff0c;但是手机肯定都用过。其实手机和电脑都是计算机&#xff01; 1.1 手机的8G256G是什么意思?…

2D-2D对极几何中的基本矩阵、本质矩阵和单应矩阵

本文主要参考高翔博士的视觉SLAM十四讲第二版中的7.3章节内容。文章目录 1 对极约束2 本质矩阵E3 单应矩阵 1 对极约束 现在&#xff0c;假设我们从两张图像中得到了一对配对好的特征点&#xff0c;如图7.9所示&#xff08;假如后面我们有若干对这样的匹配点&#xff0c;根据这…

IDEA打开一个项目时,idea左侧project模式下,不显示项目工程目录的解决方法

在IDEA打开一个一个已有的项目chapter3时&#xff0c;idea左侧project模式下&#xff0c;左侧也没有project按钮&#xff0c;如下问题截图&#xff1a;&#xff08;ps:项目结构可以显示&#xff0c;但是src等目录不见&#xff09; 在网上查了一些方法&#xff1a; 1、解决办法…

移动端的概念

【移动端】 1. 什么是移动端 大前端时代&#xff1a; ​ 前端开发涉及的领域越来越多&#xff0c;如&#xff1a;PC端&#xff0c;移动端&#xff0c;小程序&#xff0c;App&#xff0c;甚至是物联网​ 大前端’的大字体现在地位重要&#xff0c;涉及领域众多​ 前后端完全分…

从零开始的Hadoop学习(五)| HDFS概述、shell操作、API操作

1. HDFS 概述 1.1 HDFS 产出背景及定义 1&#xff09;HDFS 产生背景 随着数据量越来越大&#xff0c;在一个操作系统存不下所有的数据&#xff0c;那么就分配到更多的操作系统管理的磁盘中&#xff0c;但是不方便管理和维护&#xff0c;迫切 需要一种系统来管理多台机器上的…

OpenCV(八):图像二值化

目录 1.固定值二值化 2.自适应阈值二值化 3.Android JNI完整代码 1.固定值二值化 固定阈值二值化是OpenCV中一种简单而常用的图像处理技术&#xff0c;用于将图像转换为二值图像。在固定阈值二值化中&#xff0c;像素值根据一个预定义的阈值进行分类&#xff0c;大于阈值的…

OFDM 系统在 AWGN 信道下对不同载波频率偏移 (CFO) 的 BER 灵敏度研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

软件测评国家标准概要总结

软件测试 软件测评是指针对软件功能、性能、用途使用价值等进行的评价和测试&#xff1b; 软件测评主要依靠标准是GB/T 25000.51-2016 系统与软件工程 系统与软件质量要求和评价&#xff08;SQuaRE&#xff09; 第51部分&#xff1a;就绪可用软件产品&#xff08;RUSP&#x…