【机器学习实战】利用EM聚类算法对王者荣耀英雄进行聚类

目录

一、EM算法的步骤

二、EM算法的工作原理

三、在sklearn中创建GMM模型

四、工作流程

五、实战环节

1. 导包

2. 加载数据

3. 数据可视化分析

4. 特征工程

5. 数据规范化

6. 建模并产生结果,写入文件

7. 显示聚类后的结果

8. 聚类结果的评估


本篇理论性不多,主要是部分总结及实战内容。

一、EM算法的步骤

EM算法(英文叫做Expectation Maximization,最大期望算法)三个主要的步骤:

  1. 初始化参数
  2. 观察预期
  3. 重新估计

 

二、EM算法的工作原理

EM算法一般用于聚类,也就是无监督模型里面,因为无监督学习没有标签,EM算法可以先给无监督学习估计一个隐状态(即标签),有了标签,算法模型就可以转换成有监督学习,这时就可以用极大似然估计法求解出模型最优参数。其中估计隐状态流程应为EM算法的E步,后面用极大似然估计为M步。

下面介绍一下两种不同类型的聚类算法:

  • 硬聚类算法:如K-Means ,是通过距离来区分样本之间的差别的,且每个样本在计算的时候只能属于一个分类。
  • 软聚类算法:如EM 聚类,它在求解的过程中,实际上每个样本都有一定的概率和每个聚类相关。

EM 算法相当于一个框架,你可以采用不同的模型来进行聚类,比如 GMM(高斯混合模型),或者 HMM(隐马尔科夫模型)来进行聚类。

  • GMM 是通过概率密度来进行聚类,聚成的类符合高斯分布(正态分布)。
  •  HMM 用到了马尔科夫过程,在这个过程中,我们通过状态转移矩阵来计算状态转移的概率。

 

三、在sklearn中创建GMM模型

本案例采用GMM高斯混合模型。因此将介绍下如何在sklearn中创建GMM聚类。

gmm = GaussianMixture(n_components=1, covariance_type='full', max_iter=100)

看一下这几个参数

1. n_components:即高斯混合模型的个数,也就是我们要聚类的个数,默认值为 1。如果你不指定 n_components,最终的聚类结果都会为同一个值。

2. covariance_type:代表协方差类型。一个高斯混合模型的分布是由均值向量和协方差矩阵决定的,所以协方差的类型也代表了不同的高斯混合模型的特征。协方差类型有 4 种取值:

  • covariance_type=full,代表完全协方差,也就是元素都不为 0;
  • covariance_type=tied,代表相同的完全协方差;
  • covariance_type=diag,代表对角协方差,也就是对角不为 0,其余为 0;
  • covariance_type=spherical,代表球面协方差,非对角为 0,对角完全相同,呈现球面的特性。

3. max_iter:代表最大迭代次数,EM 算法是由 E 步和 M 步迭代求得最终的模型参数,这里可以指定最大迭代次数,默认值为 100。

创建完GMM聚类器之后,可以传入数据让它进行迭代拟合。我们使用 fit 函数,传入样本特征矩阵,模型会自动生成聚类器,然后使用 prediction=gmm.predict(data) 来对数据进行聚类,传入你想进行聚类的数据,可以得到聚类结果 prediction。

 

四、工作流程

我们使用王者荣耀英雄数据集来进行聚类,数据包括 69 名英雄的 23 个特征属性。这些属性分别是,英雄,最大生命,生命成长,初始生命,最大法力,法力成长,初始法力,最高物攻,物攻成长,初始物攻,最大物防,物防成长,初始物防,最大每5秒回血,每5秒回血成长,初始每5秒回血,最大每5秒回蓝,每5秒回蓝成长,初始每5秒回蓝,最大攻速,攻击范围,主要定位,次要定位。 

王者荣耀英雄数据集链接:https://github.com/cystanford/EM_data

先划分一下流程:

整个训练过程基本上都会包括三个阶段:

  1. 首先加载数据集;

  2. 在准备阶段,我们需要对数据进行探索,包括采用数据可视化技术,让我们对英雄属性以及这些属性之间的关系理解更加深刻,然后对数据质量进行评估,是否进行数据清洗,最后进行特征选择方便后续的聚类算法;

  3. 聚类阶段:选择适合的聚类模型,这里我们采用 GMM 高斯混合模型进行聚类,并输出聚类结果,对结果进行分析。

 

五、实战环节

1. 导包

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

from sklearn.preprocessing import StandardScaler
from sklearn.mixture import GaussianMixture

2. 加载数据

# 数据加载,避免中文乱码问题
data_original = pd.read_csv('dataset/heros.csv', encoding = 'gb18030')

3. 数据可视化分析

data_original.head().append(data_original.tail()) # 显示前5行和后5行数据
 英雄最大生命生命成长初始生命最大法力法力成长初始法力最高物攻物攻成长初始物攻...最大每5秒回血每5秒回血成长初始每5秒回血最大每5秒回蓝每5秒回蓝成长初始每5秒回蓝最大攻速攻击范围主要定位次要定位
0夏侯惇7350288.8330717469443032111.570159...983.35751371.5711528.00%近战坦克战士
1钟无艳7000275.0315017609543031811.000164...923.14348371.5711514.00%近战战士坦克
2张飞8341329.43450100010030110.570153...1154.1435750.000514.00%近战坦克辅助
3牛魔8476352.8353719261044702738.357156...1174.21458421.7861714.00%近战坦克辅助
4吕布7344270.0356400034312.360170...973.0715400.000014.00%近战战士坦克
64阿轲5968192.8326900042717.860177...812.2145000.000028.00%近战刺客NaN
65娜可露露6205211.9323918089745038515.140173...792.28647381.5711614.00%近战刺客NaN
66兰陵王6232210.0329218229845038815.500171...993.35752461.9291914.00%近战刺客NaN
676700237.5337517849644032810.860176...812.64344381.5711628.00%近战战士坦克
68百里守约5611185.1301917849644041015.860188...682.07139381.5711628.00%远程射手刺客
# 对英雄属性之间的关系进行可视化分析

# 设置plt正确显示中文
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号

# 用热力图呈现特征之间的相关性
corr = data.corr()
plt.figure(figsize=(14,14))
# annot=True显示每个方格的数据
sns.heatmap(corr, annot=True)
plt.show()

我们将 18 个英雄属性之间的关系用热力图呈现了出来,中间的数字代表两个属性之间的关系系数,最大值为 1,代表完全正相关,关系系数越大代表相关性越大。

从图中你能看出来“最大生命”“生命成长”和“初始生命”这三个属性的相关性大,我们只需要保留一个属性即可。同理我们也可以对其他相关性大的属性进行筛选,保留一个。 这既是对原有属性进行降维。

4. 特征工程

# 相关性大的属性保留一个,因此可以对属性进行降维
features_remain = [u'最大生命', u'初始生命', u'最大法力', u'最高物攻', u'初始物攻', u'最大物防', u'初始物防', 
                   u'最大每5秒回血', u'最大每5秒回蓝', u'初始每5秒回蓝', u'最大攻速', u'攻击范围']
data = data_original[features_remain]
data
 最大生命初始生命最大法力最高物攻初始物攻最大物防初始物防最大每5秒回血最大每5秒回蓝初始每5秒回蓝最大攻速攻击范围
073503307174632115939710198371528.00%近战
170003150176031816440910092371514.00%近战
2834134501003011535041251155514.00%近战
3847635371926273156394109117421714.00%近战
473443564034317039099970014.00%近战
.......................................
6459683269042717734989810028.00%近战
656205323918083851733598679381614.00%近战
666232329218223881713428599461914.00%近战
6767003375178432817638810781381628.00%近战
685611301917844101883299468381628.00%远程

5. 数据规范化

我们能看到“最大攻速”这个属性值是百分数,不适合做矩阵运算,因此我们需要将百分数转化为小数。我们也看到“攻击范围”这个字段的取值为远程或者近战,也不适合矩阵运算,我们将取值做个映射,用 1 代表远程,0 代表近战。然后采用 Z-Score 规范化,对特征矩阵进行规范化。

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)

6. 建模并产生结果,写入文件

# 构造GMM聚类
gmm = GaussianMixture(n_components=30, covariance_type='full')
gmm.fit(data)
# 训练数据
prediction = gmm.predict(data)
print(prediction)
# 将分组结果输出到CSV文件中
data_original.insert(0, '分组', prediction)
data_original.to_csv('./EM_data/heros_out.csv', index=False, sep=',')
[ 2 13  6  8 26  3  0  6 21 13  7 13 21 20 17  7 27 21 26  5  9  5  5  5
  5  5  5  1  4 23 20  4 16  4 23  4  4 19 12 16 16  4  4  4 29 16 13 12
 13 29 24 14 10 11 11  2 25 13 22 26 25 10 15  2 18 14 14 28  1]

我们采用了 GMM 高斯混合模型,并将结果输出到 CSV 文件中。聚类个数为 30。

7. 显示聚类后的结果

data_group = pd.read_csv('./EM_data/heros_out.csv')
data_group.sort_values('分组')
 分组英雄最大生命生命成长初始生命最大法力法力成长初始法力最高物攻物攻成长...最大每5秒回血每5秒回血成长初始每5秒回血最大每5秒回蓝每5秒回蓝成长初始每5秒回蓝最大攻速攻击范围主要定位次要定位
60芈月6164281.5310510001002899.786...772.3574400.00000.00%远程法师坦克
681百里守约5611185.1301917849644041015.860...682.07139381.5711628.00%远程射手刺客
271成吉思汗5799198.0302717429344039415.000...662.07137361.5001542.00%远程射手NaN
632哪吒7268270.4348318089745032011.500...983.21453381.5711628.00%近战战士NaN
552杨戬7420291.5333916949142032511.360...983.35751361.5001528.00%近战战士NaN
02夏侯惇7350288.8330717469443032111.570...983.35751371.5711528.00%近战坦克战士
53亚瑟8050316.3362200034613.000...1063.6435500.000014.00%近战战士坦克
314甄姬5584181.6304120021084902969.357...712.00043441.8571814.00%远程法师NaN
334干将莫邪5583171.0318919461044902929.500...711.85745411.7141714.00%远程法师NaN
414小乔5916202.0308819881074902637.857...752.21444431.7861814.00%远程法师NaN

第一列代表的是分组(簇),我们能看到百里守约和成吉思汗分到了一组,哪吒、杨戬和夏侯惇是一组,亚瑟自己是一组,甄姬、干将莫邪和小乔是一组。

聚类的特点是相同类别之间的属性值相近,不同类别的属性值差异大。

8. 聚类结果的评估

聚类和分类不一样,聚类是无监督的学习方式,也就是我们没有实际的结果可以进行比对,所以聚类的结果评估不像分类准确率一样直观,那么有没有聚类结果的评估方式呢?这里我们可以采用 Calinski-Harabaz 指标,代码如下:

from sklearn.metrics import calinski_harabaz_score
print(calinski_harabaz_score(data, prediction))
20.273576816244606

指标分数越高,代表聚类效果越好,也就是相同类中的差异性小,不同类之间的差异性大。当然具体聚类的结果含义,我们需要人工来分析,也就是当这些数据被分成不同的类别之后,具体每个类表代表的含义。

 

 

 
 
  • 10
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 机器学习是一种通过利用算法和模型,使计算机能够从数据中学习和识别模式以做出决策或预测的技术。聚类算法机器学习中用于将数据分组成不同类别或簇的一种方法。而MATLAB是一种功能强大的数值计算和科学编程环境,具有丰富的工具箱和函数来支持机器学习和图像处理。 MATLAB中的聚类算法可以通过分析图像的像素值或特征来将图像中的像素分为不同的组。聚类算法的目标是使同一组内的像素具有相似的特征,而不同组的像素具有不同的特征。 在使用MATLAB进行图像聚类时,首先需要选择适当的聚类算法,如k-means、谱聚类或层次聚类等。然后,将图像加载到MATLAB中,并将其转换为适当的数据表示形式,例如像素值的向量或特征矩阵。 接下来,需要选择适当的聚类参数,如聚类的数量、距离度量方法和停止准则等。然后,使用所选的聚类算法对图像进行聚类,并将像素分配到不同的簇中。 一旦完成聚类,就可以根据每个簇的像素值或特征来进行组内或组间的图像处理。例如,可以为每个簇选择不同的颜色,以便直观地可视化聚类结果。还可以根据簇的特征进行进一步的分析和处理,例如物体检测、图像分割或图像检索等。 总之,机器学习MATLAB聚类算法对图像进行处理,通过将图像中的像素分组成不同的簇,实现对图像的分析和处理,为图像处理和计算机视觉等领域提供了强大的工具和方法。 ### 回答2: 机器学习matlab聚类算法可以应用于图像处理中,通过对图像中的像素进行聚类分析,实现对图像的分割、表征和分类等任务。 在图像分割的应用中,聚类算法可以将图像中的像素按照相似性进行聚类,将相似的像素分为同一类别。通过分割,可以将图像中的目标区域从背景中提取出来,为后续的图像识别、特征提取等任务提供基础。 在图像表征的应用中,聚类算法可以将图像中的像素进行聚类,并为每个聚类赋予一个代表性的特征向量。这些特征向量可以用于描述图像的内容和特征,比如颜色直方图、纹理特征等。通过聚类得到的特征向量,可以对整个图像集进行整体分析和比对。 在图像分类的应用中,聚类算法可以将图像集中的图像进行分组,将相似的图像归为同一类别。通过聚类得到的类别信息,可以实现图像集的自动分类和标记,降低人工处理的工作量。 总之,机器学习matlab聚类算法在图像处理中具有广泛的应用,可以实现图像分割、表征和分类等任务,为图像处理领域的研究和应用提供强大的工具和方法。 ### 回答3: 机器学习(matlab)聚类算法对图像进行处理是一种常见的图像分析和处理技术。聚类算法是一种无监督学习方法,可以将相似的图像分成一组。这种技术可以用于图像识别、图像分类和图像检索等任务。 在图像处理中,聚类算法可以通过计算图像像素的相似度来将图像分成不同的类别。常见的聚类算法有K均值聚类、层次聚类和谱聚类等。这些算法可以根据图像的像素值、颜色、纹理或其他特征来对图像进行分组。 聚类算法对图像的处理可以帮助我们理解图像的结构和内容。例如,通过将图像分成不同的类别,我们可以识别出图像中的不同物体或场景。这对于图像检索和图像分类非常有用。 机器学习(matlab)聚类算法在图像处理中的应用非常广泛。例如,可以将聚类算法应用于图像分割,将图像中的不同对象分开。聚类算法还可以应用于图像压缩,通过将相似的像素分组来减小图像文件的大小。 此外,聚类算法还可以用于图像的特征提取。通过对图像进行聚类分析,我们可以发现图像中的重要特征,并将其用于其他图像处理任务,比如目标检测和图像识别。 总之,机器学习(matlab)聚类算法对图像的处理可以帮助我们理解图像的结构和内容,实现图像分割、压缩和特征提取等任务。这种技术在计算机视觉和图像处理领域具有重要的应用价值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值