使用EM算法完成聚类任务

EM算法(Expectation-Maximization Algorithm)是一种基于迭代优化的聚类算法,用于在无监督的情况下将数据集分成几个不同的组或簇。EM算法是一种迭代算法,包含两个主要步骤:期望步骤(E-step)和最大化步骤(M-step)。

 

在EM算法中,假设我们有一个数据集,但是我们不知道数据集中的数据是如何分布的。我们希望将这个数据集分成K个不同的簇,其中每个簇代表一种不同的数据分布。每个簇都由其均值和协方差矩阵表示。EM算法的主要思想是:在开始时随机地初始化这些簇,然后通过E-step和M-step交替迭代来优化簇的均值和协方差矩阵,直到收敛。

具体来说,EM算法的工作原理如下:

  1. 初始化:随机选择K个中心点作为初始的簇中心,并计算它们的均值和协方差矩阵。

  2. E-step:对于每个数据点,计算其属于每个簇的概率(即责任因子),根据这些概率对每个点进行分组。

  3. M-step:对于每个簇,使用加权最小二乘法计算其新的均值和协方差矩阵。

  4. 重复E-step和M-step,直到收敛(即责任因子和中心点的变化小于预定义的阈值)。

  5. 输出最终的簇中心和它们对应的均值和协方差矩阵,以及每个数据点所属的簇。

使用EM算法完成王者荣耀英雄聚类任务

上面介绍了EM 算法的概念,接下来看个简单的Demo代码,下面的Demo代码是读取原始的csv文件数据,然后使用EM算法进行聚类处理。该文件中记录了不同的hero在最大生命、生命长度等特征上的值。可以看到Demo代码中主要是三个步骤,步骤一:通过热力图选取部分特性,实际就是降纬处理,步骤二:对数据进行归一化处理,步骤三:创建GaussianMixture,传入数据进行无监督训练,然后输出分类结果。

# -*- coding: utf-8 -*-
import pandas as pd
import csv
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.mixture import GaussianMixture
from sklearn.preprocessing import StandardScaler

# 数据加载,避免中文乱码问题
data_ori = pd.read_csv('./em/heros.csv', encoding='gb18030')
features = [
    u'最大生命', u'生命成长', u'初始生命', u'最大法力', u'法力成长', u'初始法力', u'最高物攻', u'物攻成长',
    u'初始物攻', u'最大物防', u'物防成长', u'初始物防', u'最大每5秒回血', u'每5秒回血成长', u'初始每5秒回血',
    u'最大每5秒回蓝', u'每5秒回蓝成长', u'初始每5秒回蓝'
]
data = data_ori[features]

# 对英雄属性之间的关系进行可视化分析
# 设置 plt 正确显示中文
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
# 用热力图呈现 features_mean 字段之间的相关性
corr = data[features].corr()
plt.figure(figsize=(14, 14))
# annot=True 显示每个方格的数据
sns.heatmap(corr, annot=True)
plt.show()

# 相关性大的属性保留一个,因此可以对属性进行降维
features_remain = [
    u'最大生命', u'初始生命', u'最大法力', u'最高物攻', u'初始物攻', u'最大物防', u'初始物防', u'最大每5秒回血',
    u'最大每5秒回蓝', u'初始每5秒回蓝'
]
data = data_ori[features_remain]
# data[u'最大攻速'] = data[u'最大攻速'].apply(lambda x: float(x.strip('%')) / 100)
# data[u'攻击范围'] = data[u'攻击范围'].map({'远程': 1, '近战': 0})
# 采用 Z-Score 规范化数据,保证每个特征维度的数据均值为 0,方差为 1
ss = StandardScaler()
data = ss.fit_transform(data)
# 构造 GMM 聚类
gmm = GaussianMixture(n_components=30, covariance_type='full')
gmm.fit(data)
# 训练数据
prediction = gmm.predict(data)
print(prediction)
# 将分组结果输出到 CSV 文件中
data_ori.insert(0, '分组', prediction)
data_ori.to_csv('./hero_out.csv', index=False, sep=',')

from sklearn.metrics import calinski_harabaz_score

print(calinski_harabaz_score(data, prediction))

下图是分类后的结果,详细信息如下所示:

 在上面的Demo代码中使用到了GaussianMixture方法,该方法是一个用于拟合高斯混合模型(GMM)的类,Demo代码中传入了分类的数量和协方差类型。该方法实际包含很多输入参数,各个参数含义如下所示:

  • n_components:GMM中的分类数量,默认为1。
  • covariance_type:GMM中各个分量的协方差类型。可选的值为"full"(完全协方差矩阵)、"tied"(相同的协方差矩阵)、"diag"(对角协方差矩阵)和"spherical"(各向同性的协方差矩阵)。默认为"full"
  • tol:EM算法的收敛容差,默认为1e-3。
  • reg_covar:协方差矩阵对角线上的正则化参数。该参数用于确保协方差矩阵是半正定的,以避免数值计算的问题。默认为0。
  • max_iter:EM算法的最大迭代次数,默认为100。
  • n_init:使用不同的初始化策略进行训练的次数。模型将选择具有最佳性能的初始化策略。默认为1。
  • init_params:用于控制初始化策略的参数。默认为"kmeans",表示使用K-Means算法初始化GMM的均值和协方差矩阵,也可以设置为一个元组,例如("random", {"means": means_init, "covars": covars_init}),表示使用随机值初始化GMM的均值和协方差矩阵。
  • weights_init:GMM各个分量的权重初始化值。默认为None,表示使用初始化策略(即init_params)来初始化权重。
  • means_init:GMM各个分量的均值初始化值。默认为None,表示使用初始化策略(即init_params)来初始化均值。
  • precisions_init:GMM各个分量的协方差矩阵的逆矩阵初始化值。默认为None,表示使用初始化策略(即init_params)来初始化协方差矩阵。
  • random_state:控制随机数生成器的种子,以便在多次运行中得到相同的结果。默认为None
  • warm_start:如果为True,则使用上一次拟合的结果作为初始化值,并继续从上一次停止的地方训练。默认为False
  • verbose:控制训练过程中的详细程度。默认为0,表示不输出任何信息。
  • verbose_interval:控制训练过程中输出信息的频率。默认为10,表示每迭代10次输出一次信息。

上面的init_params参数控制初始化策略,默认是kmeans,即用K-Means算法初始化GMM的均值和协方差矩阵,前面介绍过K-Means算法,该算法也可以完成聚类任务,那么EM算法和K-means算法有什么区别呢?

EM算法与K-Means算法区别

  1. 簇形状:K-means算法假定每个簇都是由一个中心点和周围的数据点组成的球形簇,而EM算法则假定每个簇可以由任意形状的高斯分布表示。

  2. 簇数量:在K-means算法中,需要预先指定要划分的簇数量K,而在EM算法中则不需要预先指定,可以自动确定最佳的簇数。

  3. 算法原理:K-means算法通过计算每个数据点到簇中心的距离,将数据点分配到最近的簇中。而EM算法则是基于最大似然估计,利用期望最大化算法(Expectation-Maximization Algorithm)来优化簇的均值和协方差矩阵。

  4. 鲁棒性:K-means算法对离群点非常敏感,因为它使用平方误差和来计算距离,而EM算法则对离群点的影响较小,因为它使用高斯分布模型来建模每个簇。

  5. 数据类型:K-means算法适用于数值型数据,而EM算法也适用于混合数据类型,比如文本和图像数据。

  6. 算法复杂度:K-means算法的时间复杂度为O(nki),其中n是数据点的数量,k是簇的数量,i是迭代次数。而EM算法的时间复杂度通常比K-means算法更高,因为它需要估计每个簇的均值和协方差矩阵,这通常需要更多的计算量。

总的来说,EM算法和K-means算法都是用于无监督的聚类问题的算法。但K-means算法更简单,更快速,对于非球形簇和离群点的处理不如EM算法。EM算法更灵活,能够处理更多的数据类型和簇形状,但是通常需要更多的计算时间。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

态势标绘专题介绍

介绍 这个专栏是专门针对基于Cesium来实现态势标绘的专题专栏,专栏主要实现了30余种态势几何形状的标绘和编辑、文本的标绘和编辑、图片的标绘和编辑以及简单模型的标绘,同时支持标绘结果的导出以及导入。包括最终编写成的一个完整的Vue3.2+TS+Cesium1.107.2的标绘组件。专栏…

Java JVM虚拟机内部体系结构

JVM(Java虚拟机)是一个抽象机器。 它是一个提供可以执行Java字节码的运行时环境的规范。JVM可用于许多硬件和软件平台(即JVM是平台相关的)。 什么是JVM? JVM(Java虚拟机)是: 指定Java虚拟机的工作的规范。 但实现提供程序是独立的选择算法。 其实现是由…

【Hive实战】Hive的压缩池与锁

文章目录 Hive的压缩池池的分配策略自动分配手动分配隐式分配 池的等待超时Labeled worker pools 标记的工作线程(自定义线程池)Default pool 默认池Worker allocation 工作线程的分配 锁Turn Off ConcurrencyDebuggingConfigurationhive.support.concur…

如何跳出Java中的多层嵌套循环?

在Java中,要跳出多层嵌套循环,可以使用带有标签的break语句。通过在外层循环前加上一个标签,然后在内层循环中使用break语句后跟标签名称,可以实现跳出多层循环的目的。 以下是使用标签和break语句跳出多层嵌套循环的示例代码&…

BUG:pm2启动verdaccio报错:Invalid or unexpected toke

输入命令: pm2 state verdaccio 问题描述: pm2 logs verdaccio报错翻译:数据格式错误 导致我呢提原因,没有找到运行文件, 发现问题:因为命令默认查找verdaccio是去系统盘查找。 解决方式 1:…

Hadoop_HDFS_常见的文件组织格式与压缩格式

参考资料 1. HDFS中的常用压缩算法及区别_大数据_王知无_InfoQ写作社区 2. orc格式和parquet格式对比-阿里云开发者社区 3.Hadoop 压缩格式 gzip/snappy/lzo/bzip2 比较与总结 | 海牛部落 高品质的 大数据技术社区 4. Hive中的文件存储格式TEXTFILE、SEQUENCEFILE、RCFILE…

【家庭公网IPv6】

家庭公网IPv6 这里有两个网站: 1、 IPV6版、多地Tcping、禁Ping版、tcp协议、tcping、端口延迟测试,在本机搭建好服务器后,可以用这个测试外网是否可以访问本机; 2、 IP查询ipw.cn,这个可以查询本机的网络是否IPv6访问…

Java面向对象 - 常用类——Object类

什么是Object类 Java中有一个比较特殊的类,就是 Object类,它是所有类的父类,如果一个类没有使用extends关键字明确标识继承另外一个类,那么这个类就默认继承 Object类。因此,Object 类是 Java 类层中的最高层类&#x…

c++11 标准模板(STL)(std::basic_filebuf)(七)

定义于头文件 <fstream> template< class CharT, class Traits std::char_traits<CharT> > class basic_filebuf : public std::basic_streambuf<CharT, Traits> std::basic_filebuf 是关联字符序列为文件的 std::basic_streambuf 。输入序…

基于 STM32+FPGA 的通用工业控制器设计(一)系统方案设计

本章首先介绍了现有 PLC 系统的概况&#xff0c;然后提出了本文设计的通用工业控制器的 整体方案架构&#xff0c;分析了硬件和软件上需要实现的功能&#xff0c;最后对各部分功能进行分析并提 出具体的实现方案。 2.1 PLC 系统简介 可编程逻辑控制器&#xff08; Progra…

RocketMQ, Dashboard, 控制台安装

文章说明 本文主要说明RocketMQ的控制台&#xff08;Dashboard&#xff09;的安装过程。工作中一直用的是别人装好的&#xff0c;这次终于自己亲手装了一遍。 由于每次都要启动三个应用&#xff0c;比较烦&#xff0c;于是我写了一键启动脚本&#xff0c;分享给大家。这个脚本…

7. Spring Boot 配置文件

目录 1. 配置文件作用 2. 配置文件格式 3. properties 配置文件说明 3.1 properties 基本语法 3.2 读取配置文件 3.3 缺点 4. yml 配置文件说明 4.1 properties 基本语法 4.2 读取配置文件 4.3 yml 配置不同的数据类型 布尔值 整数值 null 值 配置对象 配置集合 …

国产化 | 记一次基于达梦创建数据库模式思考过程

开篇 首先&#xff0c;我们先来了解一下达梦数据库中用户与模式的概念&#xff0c;以及用户与模式之间的关系。 用户&#xff1a;主要是用来登录连接数据库&#xff0c;以及操作数据库对象等等。 模式&#xff1a;数据库中相关对象的集合。 关系&#xff1a;用户&#xff0…

基于VUE3+Layui从头搭建通用后台管理系统(前端篇)六:后台主页功能实现下

一、本章内容 接上一章,继续实现后端主页内容,主要实现工具栏对应相关内容的实现,包括系统消息、系统公告、全屏切换、语言切换、主题切换等。 1. 详细课程地址: 待发布 2. 源码下载地址: 待发布 二、界面预览 三、开发视频 基于VUE3+Layui从头搭建通用后台管理系统合集…

Elasticsearch:使用 Elasticsearch ingest pipeline 丰富数据

在我之前的文章&#xff1a; Elasticsearch&#xff1a;如何使用 Elasticsearch ingest 节点来丰富日志和指标 Elasticsearch&#xff1a;enrich processor &#xff08;7.5发行版新功能&#xff09; 我有详细描述如何使用 ingest pipeline 来丰富数据。在今天的文章中里&am…

【已解决】 Celery 报错:AttributeError: ‘EntryPoints‘ object has no attribute ‘get‘

【已解决】 Celery 报错&#xff1a;AttributeError: EntryPoints object has no attribute get 1、起因2、实验环境3、解决方案 1、起因 今天闲来无事学习 Celery 分布式任务队列&#xff0c;写好代码发布并执行&#xff0c;报错了 AttributeError: EntryPoints object has n…

【数据结构】实验七:字符串

实验七 字符串实验报告 一、实验目的与要求 1&#xff09;巩固对串的理解&#xff1b; 2&#xff09;掌握串的基本操作实现&#xff1b; 3&#xff09;掌握 BF 和 KMP 算法思想。 二、实验内容 1. 给定一个字符串ababcabcdabcde和一个子串abcd,查找字串是否在主串中出现。…

Oracle 多条记录根据某个字段获取相邻两条数据间的间隔天数,小于31天的记录都筛选出来

需求描述&#xff1a;在Oracle中 住院记录记录表为v_hospitalRecords&#xff0c;表中FIHDATE入院时间&#xff0c;FBIHID是住院号&#xff0c; 我想查询出每个患者在他们的所有住院记录中是否在一个月内再次入院(相邻的两条记录进行比较)&#xff0c;并且住院记录大于一的患者…

【高分论文密码】大尺度空间模拟预测与数字制图教程

详情点击链接&#xff1a;【高分论文密码】大尺度空间模拟预测与数字制图 一&#xff0c;R语言空间数据及数据挖掘关键技术 1、R语言空间数据及应用特点 1)R语言基础与数据科学 2)R空间矢量数据 3)R栅格数据 2、R语言空间数据挖掘关键技术 二&#xff0c;R语言空间数据高…