【机器学习】聚类(二):原型聚类:LVQ聚类(学习向量量化)

文章目录

  • 一、实验介绍
    • 1. 算法流程
    • 2. 算法解释
    • 3. 算法特点
    • 4. 应用场景
    • 5. 注意事项
  • 二、实验环境
    • 1. 配置虚拟环境
    • 2. 库版本介绍
  • 三、实验内容
    • 0. 导入必要的库
    • 1. LVQ类
      • a. 构造函数
      • b. 闵可夫斯基距离
      • c. LVQ聚类过程
      • e. 聚类结果可视化
    • 2. 辅助函数
    • 3. 主函数
      • a. 命令行界面 (CLI)
      • b. 数据加载
      • c. 模型训练及可视化
    • 4. 运行脚本的命令
    • 5. 代码整合

  学习向量量化LVQ)是一种原型聚类算法,它在寻找原型向量以刻画数据集聚类结构的过程中利用了样本的类别标记。相较于一般聚类算法,LVQ通过监督信息辅助聚类,使得原型向量更好地代表各个聚类簇。

一、实验介绍

1. 算法流程

在这里插入图片描述

  在学习过程中,LVQ算法通过样本的类别标记来引导原型向量的学习,使得原型向量更好地代表各个聚类簇。算法的性能高度依赖于初始化、学习率的设定以及停止条件的选择。

2. 算法解释

  • 在初始化阶段,原型向量通过随机选取相应类别标记的样本进行初始化。
  • 在学习过程中,算法通过计算距离和类别标记的一致性来引导原型向量的学习。相似类别的样本有助于更新原型向量,从而更好地代表该类别。

3. 算法特点

  • LVQ算法结合了监督学习和聚类,通过使用类别标记进行引导,更好地适应样本的分布。
  • 对于有监督信息的数据集,LVQ通常能够获得更具有判别性的聚类结果。
  • 学习率η的选择对算法的性能有影响,需要根据具体情况进行调整。

4. 应用场景

  • 适用于样本集带有类别标记的情况,尤其在需要获得判别性聚类结果的场景中。
  • 在需要将样本分配到与其最相似的原型向量所代表的簇中的应用中表现良好。

5. 注意事项

  • 初始原型向量的选择可能影响最终聚类结果,因此在具体应用中需要仔细选择初始原型向量。
  • 学习率的选择需要谨慎,过大的学习率可能导致原型向量的不稳定更新,而过小的学习率可能使得算法收敛缓慢。

二、实验环境

1. 配置虚拟环境

conda create -n ML python==3.9
conda activate ML
conda install scikit-learn matplotlib seaborn pandas

2. 库版本介绍

软件包本实验版本
matplotlib3.5.2
numpy1.21.5
pandas1.4.4
python3.9.13
scikit-learn1.0.2
seaborn0.11.2

三、实验内容

0. 导入必要的库

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import argparse
import random

1. LVQ类

  • __init__ :初始化LVQ聚类的参数
  • minkowski_distance 函数:计算两个样本点之间的闵可夫斯基距离
  • fit 方法:执行LVQ聚类的迭代过程
  • visualization 函数:使用Seaborn和Matplotlib可视化聚类结果

a. 构造函数

class LVQ(object):def __init__(self, features, labels, p=2, eta=0.1, max_iters=10, epsilon=1e-6, seed=0):# 初始化LVQ类的属性self.features = features          # 样本特征self.num_samples, self.num_features = self.features.shapeself.labels = labels              # 样本标签self.num_classes = len(np.unique(self.labels))  # 类别数self.p = p                        # Minkowski距离的阶数self.eta = eta                    # 学习率self.max_iters = max_iters        # 最大迭代次数self.epsilon = epsilon            # 停止条件,更新幅度小于epsilon时停止self.seed = seed                  # 随机种子self.proto = None                 # 原型向量

b. 闵可夫斯基距离

    def minkowski_distance(self, x, y=0):return np.linalg.norm(x - y, ord=self.p)
  • 使用了NumPy的 linalg.norm 函数,其中 ord 参数用于指定距离的阶数。

c. LVQ聚类过程

    def fit(self):random.seed(self.seed)# 每类中随机选择一个原型向量self.proto = np.array([random.choice(self.features[self.labels == c]) for c in range(self.num_classes)])for i in range(self.max_iters):index = random.randint(0, self.num_samples-1)    # 随机选取一个样本xj = self.features[index]          # 样本特征yj = self.labels[index]            # 样本标签dist = [self.minkowski_distance(d) for d in xj - self.proto]   # 计算到各个原型向量的距离min_idx = np.argmin(dist)delta = self.eta * (xj - self.proto[min_idx])if yj == min_idx:# 更新原型向量self.proto[min_idx] += deltaelse:self.proto[min_idx] -= delta# 更新原型向量if self.minkowski_distance(delta) < self.epsilon:break
  • 在初始化原型向量后,LVQ通过迭代过程不断调整原型向量,以适应样本的分布。
  • 随机选择一个样本,计算该样本与所有原型向量的距离,并找到最近的原型向量。
  • 根据样本标签和最近原型向量的类别标记更新原型向量。

e. 聚类结果可视化

    def visualization(self):current_palette = sns.color_palette()sns.set_theme(context="talk")clu_idx = np.zeros_like(self.labels, dtype=np.int64)for i, x in enumerate(self.features):dist = [self.minkowski_distance(d) for d in x - self.proto]clu_idx[i] = np.argmin(dist)for c in range(self.num_classes):x = self.features[clu_idx == c]sns.scatterplot(x=x[:, 0], y=x[:, 1], alpha=0.8, color=current_palette[c])sns.scatterplot(x=[self.proto[c][0]], y=[self.proto[c][1]], color=current_palette[c], marker='+', s=500)plt.show()

2. 辅助函数

def order_type(v: str):if v.lower() in ("-inf", "inf"):return -np.inf if v.startswith("-") else np.infelse:try:return float(v)except ValueError:raise argparse.ArgumentTypeError("Unsupported value encountered")
  • order_type 函数:用于处理命令行参数中的 -p(距离测量参数),将字符串转换为浮点数。

3. 主函数

a. 命令行界面 (CLI)

  • 使用 argparse 解析命令行参数
	parser = argparse.ArgumentParser(description="LVQ Demo")parser.add_argument("-m", "--max-iters", type=int, default=400, help="Maximum iterations")parser.add_argument("-p", type=order_type, default=2., help="Distance measurement")parser.add_argument("--eta", type=float, default=0.1, help="Learning rate")parser.add_argument("--eps", type=float, default=1e-6)parser.add_argument("--seed", type=int, default=110, help="Random seed")parser.add_argument("--dataset", type=str, default="./lvq.1.csv", help="Path to dataset")args = parser.parse_args()

b. 数据加载

  • 从指定路径加载数据集。
	df = pd.read_csv(args.dataset, header=None)features = df.iloc[:, [0, 1]].to_numpy()labels = df.iloc[:, 2].to_numpy()

在这里插入图片描述

c. 模型训练及可视化

	model = LVQ(features, labels, p=args.p, eta=args.eta, max_iters=args.max_iters, epsilon=args.eps, seed=args.seed)model.fit()model.visualization()

在这里插入图片描述
在这里插入图片描述

4. 运行脚本的命令

  • 通过命令行传递参数来运行脚本,指定聚类数目、初始化模式、最大迭代次数等。
python LVQ.py -k 3 --mode random -m 100 -p 2 --seed 0 --dataset ./lvq.1.csv

5. 代码整合

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import argparse
import randomclass LVQ(object):def __init__(self, features, labels, p=2, eta=0.1, max_iters=10, epsilon=1e-6, seed=0):self.features = featuresself.num_samples, self.num_features = self.features.shapeself.labels = labelsself.num_classes = len(np.unique(self.labels))self.p = pself.eta = etaself.max_iters = max_itersself.epsilon = epsilonself.seed = seedself.proto = Nonedef minkowski_distance(self, x, y=0):return np.linalg.norm(x - y, ord=self.p)def fit(self):random.seed(self.seed)# 每类中随机选择一个原型向量self.proto = np.array([random.choice(self.features[self.labels == c]) for c in range(self.num_classes)])for i in range(self.max_iters):index = random.randint(0, self.num_samples-1)    # 随机选取一个样本xj = self.features[index]          # 样本特征yj = self.labels[index]            # 样本标签dist = [self.minkowski_distance(d) for d in xj - self.proto]   # 计算到各个原型向量的距离min_idx = np.argmin(dist)delta = self.eta * (xj - self.proto[min_idx])if yj == min_idx:# 更新原型向量self.proto[min_idx] += deltaelse:self.proto[min_idx] -= delta# 更新原型向量if self.minkowski_distance(delta) < self.epsilon:breakdef visualization(self):current_palette = sns.color_palette()sns.set_theme(context="talk")clu_idx = np.zeros_like(self.labels, dtype=np.int64)for i, x in enumerate(self.features):dist = [self.minkowski_distance(d) for d in x - self.proto]clu_idx[i] = np.argmin(dist)for c in range(self.num_classes):x = self.features[clu_idx == c]sns.scatterplot(x=x[:, 0], y=x[:, 1], alpha=0.8, color=current_palette[c])sns.scatterplot(x=[self.proto[c][0]], y=[self.proto[c][1]], color=current_palette[c], marker='+', s=500)plt.show()def order_type(v: str):if v.lower() in ("-inf", "inf"):return -np.inf if v.startswith("-") else np.infelse:try:return float(v)except ValueError:raise argparse.ArgumentTypeError("Unsupported value encountered")if __name__ == '__main__':parser = argparse.ArgumentParser(description="LVQ Demo")parser.add_argument("-m", "--max-iters", type=int, default=400, help="Maximum iterations")parser.add_argument("-p", type=order_type, default=2., help="Distance measurement")parser.add_argument("--eta", type=float, default=0.1, help="Learning rate")parser.add_argument("--eps", type=float, default=1e-6)parser.add_argument("--seed", type=int, default=110, help="Random seed")parser.add_argument("--dataset", type=str, default="./lvq.1.csv", help="Path to dataset")args = parser.parse_args()df = pd.read_csv(args.dataset, header=None)features = df.iloc[:, [0, 1]].to_numpy()labels = df.iloc[:, 2].to_numpy()model = LVQ(features, labels, p=args.p, eta=args.eta, max_iters=args.max_iters, epsilon=args.eps, seed=args.seed)model.fit()model.visualization()

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

构建SQL Server链接服务器:实现跨服务器数据访问及整合

点击上方蓝字关注我 在SQL Server数据库管理中&#xff0c;链接服务器是一项强大的功能&#xff0c;允许在一个SQL Server实例中访问另一个SQL Server实例的数据。这种功能为数据库管理员提供了灵活性&#xff0c;使其能够跨不同服务器进行数据交互&#xff0c;开辟了更多的应用…

Spring的依赖注入,依赖注入的基本原则,依赖注入的优势

文章目录 Spring的依赖注入依赖注入的基本原则依赖注入有什么优势查找定位操作与应用代码完全无关。有哪些不同类型的依赖注入实现方式&#xff1f;构造器依赖注入和 Setter方法注入的区别 Spring的依赖注入 控制反转IoC是一个很大的概念&#xff0c;可以用不同的方式来实现。…

【开源】基于Vue.js的陕西非物质文化遗产网站

文末获取源码&#xff0c;项目编号&#xff1a; S 065 。 \color{red}{文末获取源码&#xff0c;项目编号&#xff1a;S065。} 文末获取源码&#xff0c;项目编号&#xff1a;S065。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 设计目标2.2 研究内容2.3 研究方法与…

智慧城市运营管理平台解决方案:PPT全文61页,附下载

关键词&#xff1a;智慧城市建设方案&#xff0c;智慧城市解决方案&#xff0c;智慧城市的发展前景和趋势&#xff0c;智慧城市建设内容&#xff0c;智慧城市运营管理平台 一、智慧城市运营平台建设背景 随着城市化进程的加速&#xff0c;城市面临着诸多挑战&#xff0c;如环…

【H5 Canvas】【平面几何】特殊图形绘制(箭头/正多边/正多尖角形等)

文章目录 直线/弧线 箭头 直线/弧线 箭头 // startX,startY 起始坐标 // endX,endY 结束坐标 // radian 圆弧角度,取值[0&#xff0c;PI]; 0表示画直线箭头&#xff0c;否则画圆弧箭头 CanvasRenderingContext2D.prototype.drawArrow function(startX,startY,endX,endY,radia…

路径规划之A*算法

系列文章目录 路径规划之Dijkstra算法 路径规划之Best-First Search算法 路径规划之A*算法 路径规划之A*算法 系列文章目录前言一、前期准备1.1 算法对比1.2 数学式方法1.3 启发式方法 二、A*算法2.1 起源2.2 思想2.3 启发式函数2.4 过程2.5 案例查看 前言 之前提过Dijkstra算…

Spring面向切面编程(AOP);Spring控制反转(IOC);解释一下Spring AOP里面的几个名词;Spring 的 IoC支持哪些功能

文章目录 Spring面向切面编程(AOP)什么是AOPSpring AOP and AspectJ AOP 的区别&#xff1f;Spring AOP中的动态代理如何理解 Spring 中的代理&#xff1f;解释一下Spring AOP里面的几个名词Spring在运行时通知对象Spring切面可以应用5种类型的通知&#xff1a;什么是切面 Aspe…

pyhon数据分析A股股票策略实际买卖总结(每月末更新数据)

简介 本篇文章主要记录python数据分析a股股票选股后实际买卖的记录。 选股策略 低位寻股&#xff0c;筛选出低位股价股票已经做过调整的股票&#xff0c;做短线交易&#xff08;不超过7天&#xff09;&#xff0c;不贪&#xff0c;小赚即走。分三个时段&#xff0c;开盘三十…

使用VC++设计程序:实现常见的三种图像插值算法:最近邻插值,双线性插值,立方卷积插值

图像放大的三种插值算法 获取源工程可访问gitee可在此工程的基础上进行学习。 该工程的其他文章&#xff1a; 01- 一元熵值、二维熵值 02- 图像平移变换&#xff0c;图像缩放、图像裁剪、图像对角线镜像以及图像的旋转 03-邻域平均平滑算法、中值滤波算法、K近邻均值滤波器 04-…

定长子网划分和变长子网划分问题_二叉树解法_通俗易懂_配考研真题

引入:定长子网划分和变长子网划分的基本概念 定长子网划分和变长子网划分的基本概念 目前常用的子网划分&#xff0c;是基于CIDR的子网划分&#xff0c;也就是将给定的CIDR地址块划分为若干个较小的CIDR地址块。 定长子网划分: 使用同一个子网掩码来划分子网&#xff0c;因…

Qt4用子类化ProxyModel和子类化MainWindow实现全表筛选,中文排序和复制粘贴

目录 1 需求 2 子类化ProxyModel实现全表筛选 3 字符串列表实现中文排序 3.1 Qt5中文排序 3.2 Qt4排序 4 表格的复制粘贴 5 应用 1 需求 模型视图编程是Qt开发的基本功&#xff0c;其中有几个关键问题需要解决&#xff1a; 全表筛选&#xff0c;或者说多列搜索中文排序…

文件元数据批量修改:mp3音频和mp4视频的元数据如何批量修改

在数字媒体处理和管理的日常工作中&#xff0c;文件元数据的批量修改是一个常见的需求。元数据&#xff0c;或者称为文件信息&#xff0c;可以包括文件的创建日期、修改日期、文件名、文件大小、标签等。在音乐和视频处理领域&#xff0c;例如对mp3音频和mp4视频文件&#xff0…