《机器学习公式推导与代码实现》chapter17-kmeans

news2024/11/16 18:00:41

《机器学习公式推导与代码实现》学习笔记,记录一下自己的学习过程,详细的内容请大家购买作者的书籍查阅。

聚类分析和k均值聚类算法

聚类分析(cluster analysis)是一类经典的无监督学习算法,在给定样本的情况下,聚类分析通过度量特征相似度或者距离,将样本自动划分为若干类别。

1 距离度量和相似度度量方式

距离度量和相似度度量是聚类分析的核心概念,大多数聚类算法建立在距离度量之上。常用的距离度量方式包括闵氏距离马氏距离,常用的相似度度量方式包括相关系数夹角余弦等。

(1) 闵氏距离闵可夫斯基距离(Minkowski distance),该距离定义如下,给定m维向量样本集合X,对于xixjXxi=(x1i,x2i,...xmi)T,那么样本xi与样本xj的闵氏距离可定义为:
d i j = ( ∑ k = 1 m ∣ x k i − x k j ∣ p ) 1 p , p ≥ 1 d_{ij}=\left ( \sum_{k=1}^{m}\left | x_{ki}-x_{kj} \right | ^{p} \right )^{\frac{1}{p} }, p\ge 1 dij=(k=1mxkixkjp)p1,p1
可以简单看出,当p=1时,闵氏距离就变成了曼哈顿距离(Manhatan distance):
d i j = ∑ k = 1 m ∣ x k i − x k j ∣ d_{ij}=\sum_{k=1}^{m}\left | x_{ki}-x_{kj} \right | dij=k=1mxkixkj
p=2时,闵氏距离就变成了欧氏距离(Euclidean distance):
d i j = ( ∑ k = 1 m ∣ x k i − x k j ∣ 2 ) 1 2 d_{ij}=\left ( \sum_{k=1}^{m}\left | x_{ki}-x_{kj} \right | ^{2} \right )^{\frac{1}{2} } dij=(k=1mxkixkj2)21
p=∞时,闵氏距离也称切比雪夫距离(Chebyshev distance):
d i j = m a x ∣ x k i − x k j ∣ d_{ij}=max\left | x_{ki}-x_{kj} \right | dij=maxxkixkj
(2) 马氏距离全称马哈拉诺比斯距离(Mahalanobis distance),是一种衡量各个特征之间相关性的聚类度量方式。给定一个样本集合X=(xij)mxn,假设样本的协方差矩阵为S,那么样本xi与样本xj之间的马氏距离可以定义为:
d i j = [ ( x i − x j ) T S − 1 ( x i − x j ) ] 1 2 d_{ij}=\left [\left(x_{i}-x_{j}\right)^{T} S^{-1}\left(x_{i}-x_{j}\right)\right] ^{\frac{1}{2}} dij=[(xixj)TS1(xixj)]21
S为单位矩阵,即样本的各特征之间相互独立且方差为1时,马氏距离就是欧氏距离。

(3) 相关系数(correlation coefficent)是度量样本相似度最常用的方式。相关系数有多种定义方式,较为常用的是皮尔逊相关系。相关系数越接近1,两个样本越相似;样本xi与样本xj之间的相关系数可定义为:
r i j = ∑ k = 1 m ( x k i − x ˉ i ) ( x k j − x ˉ j ) [ ∑ k = 1 m ( x k i − x ˉ i ) 2 ∑ k = 1 m ( x k j − x ˉ j ) 2 ] 1 2 r_{ij}=\frac{\sum_{k=1}^{m}\left ( x_{ki}-\bar{x}_{i}\right )\left ( x_{kj}-\bar{x}_{j}\right )}{\left [ \sum_{k=1}^{m} \left ( x_{ki}-\bar{x}_{i}\right )^{2} \sum_{k=1}^{m} \left ( x_{kj}-\bar{x}_{j}\right )^{2} \right ] ^{\frac{1}{2} } } rij=[k=1m(xkixˉi)2k=1m(xkjxˉj)2]21k=1m(xkixˉi)(xkjxˉj)
上边这个式子看起来有点复杂,其实就是:
r ( X , Y ) = C o v ( X , Y ) V a r [ X ] V a r [ Y ] r\left ( X,Y \right ) =\frac{Cov\left ( X,Y \right ) }{\sqrt{Var\left [ X \right ] Var\left [ Y \right ] } } r(X,Y)=Var[X]Var[Y] Cov(X,Y)
(4) 余弦夹角(angle cosine)也是度量两个样本相似度的方式。夹角余弦越接近1,表示两个样本越相似:
s i m i l a r i t y = c o s ( θ ) = A ⋅ B ∥ A ∥ ∥ B ∥ similarity=cos\left ( \theta \right ) =\frac{A\cdot B}{\left\|A\right\|\left\|B\right\|} similarity=cos(θ)=ABAB
样本xi与样本xj之间的夹角余弦可定义为:
A C i j = ∑ k = 1 m x k i x k j [ ∑ k = 1 m x k i 2 ∑ k = 1 m x k j 2 ] 1 2 AC_{ij}=\frac{\sum_{k=1}^{m}x_{ki}x_{kj}}{\left [ \sum_{k=1}^{m}x_{ki}^{2} \sum_{k=1}^{m}x_{kj}^{2}\right ] ^{\frac{1}{2}}} ACij=[k=1mxki2k=1mxkj2]21k=1mxkixkj

2 聚类算法一览

聚类算法将相似的样本归入同一个簇(cluster)中,这使得同一个簇中的样本对象的相似度尽可能大,同时不同簇中的样本对象的差异性也尽可能大。常用的聚类算法有如下几种:

  • 基于距离的聚类:该类算法的目标是使簇内距离小、簇间距离大,最典型的就是k均值聚类算法。
  • 基于密度的聚类:该类算法是根据样本邻近区域的密度来进行划分的,最常见的密度聚类算法当属DBSCAN算法
  • 层次聚类算法:包括合并层次聚类和分裂层次聚类等。
  • 基于图论的谱聚类

在这里插入图片描述
sklearn在不同数据集上的10类聚类算法效果对比。

3 K-means算法原理

在这里插入图片描述

4 K-means算法numpy实现

import numpy as np

# 定义欧氏距离
def euclidean_distance(x, y):
    
    distance = 0
    for i in range(len(x)):
        distance += np.power((x[i] - y[i]), 2)
    return np.sqrt(distance)
# 质心初始化
def centroids_init(X, k): # 训练样本,质心个数(聚类簇数)

    m, n = X.shape # 样本数和特征数
    centroids = np.zeros((k, n)) # 初始化质心矩阵,大小为质心个数*特征数
    for i in range(k):
        centroid = X[np.random.choice(range(m))]
        centroids[i] = centroid
    return centroids # centroids:质心矩阵,k个长度为n的从m个样本中选取的样本
# 求单个样本所属最近质心的索引
def closest_centroid(x, centroids): # 单个样本实例,质心矩阵

    closest_i, closest_dist = 0, float('inf')
    for i, centroid in enumerate(centroids):
        distance = euclidean_distance(x, centroid)
        if distance < closest_dist:
            closest_i = i
            closest_dist = distance
    return closest_i # closest_i:最近质心
# 构建簇与分配样本
def build_clusters(centroids, k, X): # 质心矩阵,质心个数, 训练样本

    clusters = [[] for _ in range(k)] # 初始化簇列表
    for x_i, x in enumerate(X):
        centroid_i = closest_centroid(x, centroids) # 样本最近质心的下标
        clusters[centroid_i].append(x_i) # 样本下标加入簇矩阵中
    return clusters # 聚类簇
# 计算新的质心
def calculate_centroids(clusters, k, X):

    n = X.shape[1] # 特征数
    centroids = np.zeros((k, n)) # 初始化质心矩阵
    for i, cluster in enumerate(clusters):
        centroid = np.mean(X[cluster], axis=0) # 计算每个簇的均值作为新的质心
        centroids[i] = centroid # 更新质心矩阵
    return centroids # 返回新的质心矩阵
# 获取每个样本所属聚类类别
def get_cluster_labels(clusters, X):

    y_pred = np.zeros(X.shape[0]) # 样本数
    for cluster_i, cluster in enumerate(clusters):
        for sample_i in cluster:
            y_pred[sample_i] = cluster_i
    return y_pred # 预测结果
# 封装k-means算法
def kmeans(X, k, max_iterations):

    centroids = centroids_init(X, k) # 训练样本,质心个数(聚类簇数)

    # 迭代至收敛
    for _ in range(max_iterations):
        clusters = build_clusters(centroids, k, X) # 分配样本与构建簇
        new_centroids = calculate_centroids(clusters, k, X) # 计算新的质心
        print(f'迭代进行到第{_}轮')
        diff = centroids - new_centroids
        centroids = new_centroids
        if not diff.any():
            break
    return get_cluster_labels(clusters, X) # 获取每个样本所属聚类类别
from sklearn import datasets

# 测试算法
data = datasets.load_iris()
iris, y = data.data, data.target
label_pred = kmeans(iris, 3, 100)

# 取2个或者3个维度来看一下聚类的效果
X = iris[:,2:]
x0 = X[label_pred == 0]
x1 = X[label_pred == 1]
plt.scatter(x0[:, 0], x0[:, 1], c = "red", marker='o', label='label0')
plt.scatter(x1[:, 0], x1[:, 1], c = "green", marker='*', label='label1')
plt.xlabel('petal length')
plt.ylabel('petal width')
plt.legend(loc=2)
plt.show()

在这里插入图片描述

5 基于sklearn的K-means算法

from sklearn.cluster import KMeans

kmeans_sk = KMeans(n_clusters=3, random_state=2023).fit(iris)
label_pred = kmeans_sk.labels_ # 打印拟合标签

X = iris[:,2:]
x0 = X[label_pred == 0]
x1 = X[label_pred == 1]
plt.scatter(x0[:, 0], x0[:, 1], c = "red", marker='o', label='label0')
plt.scatter(x1[:, 0], x1[:, 1], c = "green", marker='*', label='label1')
plt.xlabel('petal length')
plt.ylabel('petal width')
plt.legend(loc=2)
plt.show()

在这里插入图片描述
笔记本_Github地址

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

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

相关文章

【半监督:交叉分辨率:解纠缠】

Cross-Resolution Semi-Supervised Adversarial Learning for Pansharpening &#xff08;用于泛锐化的交叉分辨率半监督对抗学习&#xff09; 现有的基于深度神经网络&#xff08;DNN&#xff09;的方法已经产生了良好的泛锐化图像。然而&#xff0c;监督DNN为基础的泛锐化方…

卷积是什么

参考&#xff1a; 【官方双语】那么……什么是卷积&#xff1f;https://www.bilibili.com/video/BV1Vd4y1e7pj/ [建议看完] x.1 一维卷积 一维卷积&#xff0c;即对于两个向量的卷积&#xff0c;就是将向量翻转后&#xff0c;从前向后滑动&#xff0c;相乘再相加。 x.2 二维卷…

Spring Boot启动原理

Spring Boot的自动配置为我们提供了快捷方便的方式来运行Spring应用&#xff0c;但很多开发者对其内部启动原理还不是很明白。这篇博客旨在解开Spring Boot的神秘面纱&#xff0c;帮助大家理解它的启动原理。 入口类和注解 我们的Spring Boot应用通常从一个主类开始&#xff…

感知机(Perceptron)底层原理

1.感知机&#xff08;Perceptron&#xff09;底层原理 声明&#xff1a;笔记来源于《白话机器学习的数学》 感知机是接受多个输入后将每个值与各自权重相乘&#xff0c;最后输出总和的模型。 单层感知机因过于简单&#xff0c;无法应用于实际问题&#xff0c;但它是神经网络和深…

8个很少用,但却很好用的 Python 库!

本文介绍一些我们可能很少听过&#xff0c;但是对于特定问题或者特定任务来说&#xff0c;可能会非常有帮助的 Python 库 技术交流 技术要学会分享、交流&#xff0c;不建议闭门造车。一个人可以走的很快、一堆人可以走的更远。 好的文章离不开粉丝的分享、推荐&#xff0c;文…

黑马程序员前端 Vue3 小兔鲜电商项目——(六)二级分类页

文章目录 二级路由配置模版代码配置路由关系跳转配置 面包屑导航实现封装接口渲染数据 分类基础列表实现准备接口渲染数据 列表筛选实现无限加载实现定制路由 scrollBehavior 二级路由配置 模版代码 创建 src\views\SubCategory\index.vue 文件&#xff0c;添加以下代码&…

云服务器部署企业版openGauss,本地Data Studio远程连接

1.下载安装包 在华为云上租一台服务器&#xff0c;操作系统选&#xff1a;openEuler 20.03 64bit (64-bit) 获取openGauss Server安装包&#xff0c;企业版&#xff1a;软件包链接 使用xshell连接服务器&#xff0c;准备软硬件安装环境。准备软硬件安装环境 教程 下载Data …

javaee 过滤器加cookie实现自动登录

思路 如上图&#xff0c;如果勾选了自动登录&#xff0c;在登录时&#xff0c;就将用户名和密码存储到cookie中&#xff0c;当下次访问首页时&#xff0c;过滤器先拦截请求&#xff0c;获取下cookie中的账号密码&#xff0c;然后如果cookie中的账号密码有效就将登录信息存储到…

Paddle FastDeploy 执行Cmake 时错误处理方法

1.Paddle FastDeploy 在cmake 时的命令执行报错处理 命令是参考官网的&#xff0c;如下: git clone https://github.com/PaddlePaddle/FastDeploy.git cd FastDeploy mkdir build && cd build cmake .. -G "Visual Studio 16 2019" -A x64 \-DENABLE_ORT_BA…

【MyBatis-Plus】入门案例与简介

1&#xff0c;MyBatisPlus入门案例与简介 1. 入门案例 MybatisPlus(简称MP)是基于MyBatis框架基础上开发的增强型工具&#xff0c;旨在简化开发、提供效率。 开发方式 基于MyBatis使用MyBatisPlus基于Spring使用MyBatisPlus基于SpringBoot使用MyBatisPlus SpringBoot刚刚我…

工资管理系统(学校期末作业)

一、 题目要求 1、需求分析 工资信息存放在文件中&#xff0c;提供文件的输入、输出等操作&#xff1b;要浏览&#xff0c;提供显示、排序操作&#xff1b;查询功能要求实现查找操作&#xff1b;提供键盘式选择菜单以实现功能选择。 2、总体设计 系统可分为信息输入、信息添…

洛谷 P2782 友好城市 排序 动态规划

题目描述 有一条横贯东西的大河&#xff0c;河有笔直的南北两岸&#xff0c;岸上各有位置各不相同的N个城市。北岸的每个城市有且仅有一个友好城市在南岸&#xff0c;而且不同城市的友好城市不相同。每对友好城市都向政府申请在河上开辟一条直线航道连接两个城市&#xff0c;但…

servlet 技能总结

Servlet介绍 Servlet是Server Applet的简称&#xff0c;称为服务端小程序&#xff0c;是JavaEE平台下的技术标准&#xff0c;基于Java语言编写的服务端程序。Web容器或应用服务器实现了Servlet标准所以Servlet需运行在Web容器或应用服务器中。Servlet主要功能在于能在服务器中执…

【前端技术】uni-app 01:快速开始

开个新坑&#xff0c;学习一下 uni-app&#xff0c;之后也想 uni-app 来做些事&#xff0c;虽然我主业是后端&#xff0c;但 uni-app 其作为一个高效生产力工具&#xff0c;个人认为非常有必要学习一下~ 目录 1 uni-app 介绍 1.1 uni-app 由来 1.2 为什么选择 uni-app 1.3 …

Win7 64位 VS2015及MinGW环境编译矢量库agg-2.5和cairo-1.14.6

书接上文&#xff0c;昨天装了MinGW&#xff0c;主要原因之一是要用到MSYS&#xff0c;所以顺手把FFMPEG又编译了一遍。 回到主题&#xff0c;其实我是想编译矢量库&#xff0c;因为最近要学习一些计算几何算法&#xff0c;所以找个方便的2D画图库就很重要。 说白了其实是懒得…

我把GPT 的学习轨迹可视化了竟和人类十分类似 |ACL2023

回想一下我们小时候是如何习得一门语言的&#xff1f;一般而言&#xff0c;在人类婴儿出生第一年内&#xff0c;最开始婴儿只能模仿式的说出一些“音素”&#xff0c;说出一些最简单与基本的单词或句子&#xff0c;而伴随着成长&#xff0c;在大约一岁到三岁的阶段&#xff0c;…

windows进程结构体

了解进程线程的概念后&#xff0c;我们就来看看windows里面的进程长什么样子的。进程本质上就是一个结构体。在Linux里面也称之为进程描述符。当操作系统创建一个进程的时候&#xff0c;它会填充一个结构体&#xff0c;往这个结构体里写入数据&#xff0c;这个结构体就用于管理…

Queue,List,Deque联系

如图所示&#xff0c;可以得出LinkedList既可以是双向链表也可以是双端队列&#xff0c;Deque接口继承了Queue接口 Queue add(E):boolean 在队尾添加元素&#xff0c;添加成功返回true&#xff0c;如果队列已满无法添加则抛出异常。offer(E):boolean 在队尾添加元素&#xff0…

linux mail -s发送邮件异常解决

异常&#xff1a; Error initializing NSS: Unknown error -8015. "/root/dead.letter" 11/301 . . . message not sent. 出现此问题&#xff0c;大概率是和证书相关。如果没有安装证书&#xff0c;请先安装&#xff1a; 1&#xff0c;下载 yum -y install mailx …

Python采集某xsp内容, m3u8视频内容下载

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 环境使用: Python 3.8 Pycharm 专业版 模块使用: import requests >>> pip install requests import re 正则表达式 解析数据 import json 基本步骤去实现 一. 数据来源分析 通过开发者工具进行抓包分析, 分…