03、K-means聚类实现步骤与基于K-means聚类的图像压缩

news2024/11/27 12:34:53

03、K-means聚类实现步骤与基于K-means聚类的图像压缩(1)

K-means聚类实现步骤

开始学习机器学习啦,已经把吴恩达的课全部刷完了,现在开始熟悉一下复现代码。对这个手写数字实部比较感兴趣,作为入门的素材非常合适。

1、K-means基础

K-means算法是一种常用的聚类算法,它的实现步骤如下:

STEP1:从数据集中随机选择k个样本作为初始聚类中心。
STEP2:计算每个样本到各聚类中心的距离,并将样本归入最近的聚类中心。
STEP3:重新计算每个聚类的中心,该中心为该类所有样本的平均值。
STEP4:重复步骤2和3,直到满足以下条件之一:

聚类中心不再变化。
达到预设的最大迭代次数。
最小平方误差SSE(误差的平方和)达到预设的阈值。

2、K-means的底层代码实现

STEP0:调用numpy和绘图库:

import numpy as np
from matplotlib import pyplot as plt

STEP1:从数据集中随机选择k个样本作为初始聚类中心:

# 随机初始化聚类初始优化点
def kMeans_init_centroids(X, K):
    # 随机重新排序样本的索引
    randidx = np.random.permutation(X.shape[0])
    # 取前K个样本作为聚类中心
    centroids = X[randidx[:K]]
    return centroids

STEP2:计算每个样本到各聚类中心的距离,并将样本归入最近的聚类中心:

def find_closest_centroids(X, centroids):
    # 获取聚类中心的数量,也即K值
    K = centroids.shape[0]
    # 初始化一个数组用于存储每个样本所属的聚类中心的索引  
    idx = np.zeros(X.shape[0], dtype=int)
    # 遍历数据集中的每个样本
    for i in range(X.shape[0]):
        # 初始化一个列表用于存储当前样本到每个聚类中心的距离
        distance = []
        # 计算当前样本到每个聚类中心的距离
        for j in range(centroids.shape[0]):
            # 使用欧几里得距离公式计算样本i与聚类中心j之间的距离
            norm_ij = np.linalg.norm(X[i] - centroids[j])
            distance.append(norm_ij)
            # 找出距离列表中的最小值,该最小值对应的索引就是当前样本所属的聚类中心
        idx[i] = np.argmin(distance)
        # 返回每个样本所属的聚类中心的索引数组
    return idx

STEP3:重新计算每个聚类的中心,该中心为该类所有样本的平均值:

def compute_centroids(X, idx, K):
    # 获取数据集X的行数m和列数n  
    # m表示样本数量,n表示每个样本的特征数量  
    m, n = X.shape
    # 初始化一个K x n的零矩阵,用于存储K个聚类中心  
    # K表示聚类数量,n表示特征数量  
    centroids = np.zeros((K, n))
    # 遍历每个聚类中心  
    for k in range(K):
        # 从数据集X中选择属于当前聚类k的所有样本  
        # idx是一个长度为m的数组,存储了每个样本所属的聚类中心的索引  
        points = X[idx == k]
        # 计算属于当前聚类k的所有样本的平均值,得到聚类中心  
        # axis=0表示按列计算平均值  
        centroids[k] = np.mean(points, axis=0)
        # 返回计算得到的K个聚类中心  
    return centroids

STEP4:重复步骤2和3,直到满足以下条件之一:
聚类中心不再变化。
达到预设的最大迭代次数。
最小平方误差SSE(误差的平方和)达到预设的阈值。

此处直接以达到预设的最大迭代次数作为停止条件

def run_kMeans(X, initial_centroids, max_iters=10):
    # 获取数据集X的行数m和列数n
    # m表示样本数量,n表示每个样本的特征数量
    m, n = X.shape
    # 获取初始聚类中心的数量K
    K = initial_centroids.shape[0]
    # 将初始聚类中心赋值给centroids变量
    centroids = initial_centroids
    # 将初始聚类中心复制给previous_centroids变量,用于后续比较聚类中心是否发生变化
    previous_centroids = centroids
    # 初始化一个长度为m的零数组,用于存储每个样本所属的聚类中心的索引
    idx = np.zeros(m)
    # 开始运行K-means算法,最多迭代max_iters次
    for i in range(max_iters):
        # 输出当前迭代进度
        print("K-Means iteration %d/%d" % (i, max_iters - 1))
        # 调用find_closest_centroids函数,为数据集X中的每个样本找到最近的聚类中心,并返回索引数组
        idx = find_closest_centroids(X, centroids)
        # 调用compute_centroids函数,根据每个样本所属的聚类中心和索引数组,计算新的聚类中心
        centroids = compute_centroids(X, idx, K)
        # 返回最终的聚类中心和每个样本所属的聚类中心的索引
    return centroids, idx

3、K-means的底层代码案例

此处直接使用吴恩达的案例,非常简洁直观嘞:

import numpy as np
import matplotlib.pyplot as plt


def load_data():
    X = np.load("K_means_data/ex7_X.npy")
    return X


def draw_line(p1, p2, style="-k", linewidth=1):
    plt.plot([p1[0], p2[0]], [p1[1], p2[1]], style, linewidth=linewidth)


def plot_data_points(X, idx):
    # plots data points in X, coloring them so that those with the same
    # index assignments in idx have the same color
    plt.scatter(X[:, 0], X[:, 1], c=idx)


def plot_progress_kMeans(X, centroids, previous_centroids, idx, K, i):
    # Plot the examples
    plot_data_points(X, idx)

    # Plot the centroids as black 'x's
    plt.scatter(centroids[:, 0], centroids[:, 1], marker='x', c='k', linewidths=3)

    # Plot history of the centroids with lines
    for j in range(centroids.shape[0]):
        draw_line(centroids[j, :], previous_centroids[j, :])

    plt.title("Iteration number %d" % i)

def find_closest_centroids(X, centroids):
    """
    Computes the centroid memberships for every example
    Args:
        X (ndarray): (m, n) Input values
        centroids (ndarray): k centroids
    Returns:
        idx (array_like): (m,) closest centroids
    """
    # Set K
    K = centroids.shape[0]
    # You need to return the following variables correctly
    idx = np.zeros(X.shape[0], dtype=int)
    for i in range(X.shape[0]):
        # Array to hold distance between X[i] and each centroids[j]
        distance = []
        for j in range(centroids.shape[0]):
            norm_ij = np.linalg.norm(X[i] - centroids[j])
            distance.append(norm_ij)
        idx[i] = np.argmin(distance)
    return idx

# GRADED FUNCTION: compute_centpods
def compute_centroids(X, idx, K):
    """
    Returns the new centroids by computing the means of the
    data points assigned to each centroid.
    Args:
        X (ndarray):   (m, n) Data points
        idx (ndarray): (m,) Array containing index of closest centroid for each
                       example in X. Concretely, idx[i] contains the index of
                       the centroid closest to example i
        K (int):       number of centroids
    Returns:
        centroids (ndarray): (K, n) New centroids computed
    """
    # Useful variables
    m, n = X.shape
    # You need to return the following variables correctly
    centroids = np.zeros((K, n))
    for k in range(K):
        points = X[idx == k]
        centroids[k] = centroids[k] = np.mean(points, axis=0)
    return centroids


# You do not need to implement anything for this part
def run_kMeans(X, initial_centroids, max_iters=10, plot_progress=False):
    """
    Runs the K-Means algorithm on data matrix X, where each row of X
    is a single example
    """
    # Initialize values
    m, n = X.shape
    K = initial_centroids.shape[0]
    centroids = initial_centroids
    previous_centroids = centroids
    idx = np.zeros(m)
    # Run K-Means
    for i in range(max_iters):
        # Output progress
        print("K-Means iteration %d/%d" % (i, max_iters - 1))
        # For each example in X, assign it to the closest centroid
        idx = find_closest_centroids(X, centroids)
        # Optionally plot progress
        if plot_progress:
            plot_progress_kMeans(X, centroids, previous_centroids, idx, K, i)
            previous_centroids = centroids
        # Given the memberships, compute new centroids
        centroids = compute_centroids(X, idx, K)
    plt.show()
    return centroids, idx


# Load an example dataset
X = load_data()
# Set initial centroids
initial_centroids = np.array([[3,3],[6,2],[8,5]])
K = 3
# Number of iterations
max_iters = 10
centroids, idx = run_kMeans(X, initial_centroids, max_iters, plot_progress=True)

运行结果:
在这里插入图片描述

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

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

相关文章

嵌入式八股 | 笔试面试 | 校招秋招 | 详细讲解

〇、前言 作者:赛博二哈 本嵌入式八股撰写初衷:当时求职翻遍了我能找到的所有八股,不论是嵌入式的,计算机基础的,C艹的,都很难看下去,细究其原因,有个最大的痛点: 大部…

OCR常用数据集_看数据集区分可识别语言

这里写目录标题 COCO-TEXT 英文Total-Text 英文少量中文IIIT5K[50]、IC03[44]、IC13[34]、IC15[33]、CT80[56]MJSynth 英文SynthText分层文本数据集 (HierText) 英文TextOCR和IntelOCR ???Multi-language dataset (IC19)RCTW17 主要中文MSRA-…

开源语音大语言模型——Qwen-Audio

论文链接:https://arxiv.org/pdf/2311.07919.pdf 开源代码:https://github.com/QwenLM/Qwen-Audio 一、背景 大型语言模型(LLMs)由于其良好的知识保留能力、复杂的推理和解决问题能力,在通用人工智能(AGI…

链表的反转—c++版本

一、迭代反转法 过程分析&#xff1a; 代码实现&#xff1a; #include <iostream>struct LinkNode{ //创建一个结构体做为链表的结点int data; //数据域LinkNode* next; //指针域 };void Print_Link(LinkNode* phead) //打印链表 {while (phead ! nu…

cadence virtuoso simulation文件夹删除

ADE XL仿真结果错误&#xff0c;与预期结果差别太大&#xff0c;与ADE L仿真结果也差别很大。 可能是由于仿真数据过多&#xff0c;卡爆了。 在virtuoso启动路径下&#xff0c;simulation文件夹是仿真过程文件&#xff0c;可以将此文件夹清空。 清空后ADE XL仿真结果正常了。…

P23 C++字符串

目录 前言 01 什么是字符串 02 字符串是怎么工作的呢&#xff1f; 2.1 字符 2.2 字符串 2.3 如何知道指向hello world的这个指针多大 03 使用字符串 04 字符串传参 前言 本期我们将讨论 C 中的字符串。 首先&#xff0c;什么是字符串&#xff1f; 01 什么是字符串 字…

基于OpenCV+YOLOv5实现车辆跟踪与计数(附源码)

导 读 本文主要介绍基于OpenCVYOLOv5实现车辆跟踪与计数的应用&#xff0c;并给出源码。 资源下载 基础代码和视频下载地址&#xff1a; https://github.com/freedomwebtech/win11vehiclecount main.py代码:​​​​​​​ import cv2import torchimport numpy as npfrom tr…

Vue CLI 初体验之如何创建一个项目并打开,以及组件的简单使用案例。

目录 什么是Vue CLI? 如何使用Vue CLI 创建一个项目 1.winr 打开cmd 输入vue create 1127(1127是文件名) 2.配置基础设置 选择Manually select features 选择Router和Vuex 选中vue版本&#xff08;我这里选vue3&#xff09; 剩下的看自己需要&#xff0c;如果不确定就一…

3、Segment Anything

github 创建anaconda环境 conda create -n ASM python3.8下载依赖包 # pytorch>1.7 and torchvision>0.8 conda install pytorch1.11.0 torchvision0.12.0 torchaudio0.11.0 cudatoolkit11.3 -c pytorchpip install githttps://github.com/facebookresearch/segment-a…

13、LCD1602调试工具

LCD1602调试工具 使用LCD1602液晶屏作为调试窗口&#xff0c;提供类似Printf函数的功能&#xff0c;可实时观察单片机内部数据的变化情况&#xff0c;便于调试和演示。 main.c #include <REGX52.H> #include "LCD1602.h" #include "Delay.h"//存储…

快速搭建一个SpringCloud、SpringBoot项目 || 项目搭建要点

1. 基本结构 建立springcloud项目从表入手&#xff0c;分析好需求建立表结构后&#xff0c;使用mybatis-plux生成POJO类&#xff0c;在对应的model模块中。 2. 微服务部分架构 2.1 依赖 service 微服务模块的依赖仅包含如下&#xff0c;数据库等依赖包含在model中&#xff0c…

【解决视觉引导多个位置需要标定多个位置的问题】

** 以下只针对2D定位&#xff0c;就是只有X、Y、Rz三个自由度的情况。** 假设一种情况&#xff0c;当视觉给机器人做引导任务时&#xff0c;零件有多个&#xff0c;分布在料框里&#xff0c;视觉需要走多个位置去拍&#xff0c;那么只需要对第一个位置确定拍照位&#xff0c;确…

力扣6:N字形变化

代码&#xff1a; class Solution { public:string convert(string s, int numRows){int lens.size();if(numRows1){return s;}int d2*numRows-2;int count0;string ret;//第一行&#xff01;for(int i0;i<len;id){rets[i];}//第k行&#xff01;for(int i1;i<numRows-1;…

智能优化算法应用:基于教与学算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于教与学算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于教与学算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.教与学算法4.实验参数设定5.算法结果6.参考文献7.…

超越GPT-4,拥有联网能力,Kimi-Chat大模型已免费使用,国内直接访问

目前ChatGPT的所有免费用户都已可以使用带有语音功能的ChatGPT。 人吧&#xff0c;总是贪婪的&#xff0c;我还想要ChatGPT Plus用户独享的“联网”功能。 目前对于ChatGPT来说&#xff0c;不想交钱&#xff0c;别拥有“联网”能力了&#xff0c;于是我找到了一个后起之秀&…

【差旅游记】新疆哈密回王府印象

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 2023年11月4号&#xff0c;那天的风的确挺大&#xff0c;逛完哈密博物馆考虑要不要去旁边的哈密回王府逛逛。想着来都来了&#xff0c;虽然网上评价不太好&#xff0c;还是去溜达一圈吧&#xff0c;于是决定自己去转转…

为啥网络安全那么缺人,但很多人却找不到工作?

文章目录 一、学校的偏向于学术二、学的东西太基础三、不上班行不行 为什么网络安全的人才缺口那么大&#xff0c;但是大学毕业能找到网安工作的人却很少&#xff0c;就连招聘都没有其他岗位多&#xff1f; 明明央视都说了网络安全的人才缺口还有300多万&#xff0c;现在找不到…

C++ 用ifstream读文件

输入流的继承关系: C++ 使用标准库类来处理面向流的输入和输出: iostream 处理控制台 IOfstream 处理命名文件 IOstringstream 完成内存 string 的 IO每个IO 对象都维护一组条件状态 flags (eofbit, failbit and badbit),用来指出此对象上是否可以进行 IO 操作。如果遇到错误…

vue实战——登录【详解】(含自适配全屏背景,记住账号--支持多账号,显隐密码切换,登录状态保持)

效果预览 技术要点——自适配全屏背景 https://blog.csdn.net/weixin_41192489/article/details/119992992 技术要点——密码输入框 自定义图标切换显示隐藏 https://blog.csdn.net/weixin_41192489/article/details/133940676 技术要点——记住账号&#xff08;支持多账号&…