内容简介:王者荣耀这幺久了,还没上王者?哈哈哈,看过来,是不是对英雄理解的不够透彻呢,是不是还没有很好的为英雄分类呢,今天就来看看英雄分类一、EM 聚类简介二、爬取网上的英雄初始属性值
王者荣耀这幺久了,还没上王者?哈哈哈,看过来,是不是对英雄理解的不够透彻呢,是不是还没有很好的为英雄分类呢,今天就来看看英雄分类
技术栈
一、EM 聚类简介
二、爬取网上的英雄初始属性值
三、做成饼图
EM 聚类简介
EM 英文名是 Expectation Maximization,也叫最大期望算法。
在统计计算中,最大期望(EM)算法是在概率(probabilistic)模型中寻找参数最大似然估计或者最大后验估计的算法,其中概率模型依赖于无法观测的隐藏变量(Latent Variable)。
最大期望算法经过两个步骤交替进行计算,第一步是计算期望(E),利用对隐藏变量的现有估计值,计算其最大似然估计值;第二步是最大化(M),最大化在 E 步上求得的最大似然值来计算参数的值。M 步上找到的参数估计值被用于下一个 E 步计算中,这个过程不断交替进行。
进行英雄聚类
使用 sklearn 库中的的 EM 聚类算法框架,采用高斯混合模型
from sklearn.mixture import GaussianMixture
一些主要参数意义如下,其他参数可以查看相关文档
n_components:混合高斯模型个数,也就是想要的聚类个数,默认为1
covariance_type:协方差类型,包括{‘full’,‘tied’, ‘diag’, ‘spherical’}四种,分别对应完全协方差矩阵(元素都不为零),相同的完全协方差矩阵(HMM会用到),对角协方差矩阵(非对角为零,对角不为零),球面协方差矩阵(非对角为零,对角完全相同,球面特性),默认‘full’ 完全协方差矩阵
max_iter:最大迭代次数,默认100
所以可以构造 GMM 聚类如下:
# 构造 GMM 聚类 gmm = GaussianMixture(n_components=20, covariance_type='full')
有一份如下结构的数据:
可以看到,涉及到的属性非常多,初始的属性设置如下:
feature = ['1级物理攻击', '15级物理攻击', '每级成长', '1级生命', '15级生命', '生命成长值', '1级物理防御', '15级物理防御', '每级物理防御成长', '攻速成长', '1级每5秒回血', '15级每5秒回血', '1级最大法力', '15级最大法力', '最大法力成长', '1级每五秒回蓝', '15级每5秒回蓝', '近/远程?', '移速', '定位', '个人建议分路']
属性降维
可以先通过热力图来判断下哪些属性是强相关的,只保留唯一属性
import seaborn as sns import matplotlib.pyplot as plt corr = data[feature].corr() plt.figure(figsize=(14, 14)) sns.heatmap(corr, annot=True) plt.show()
可以看到,其中”1级最大法力“,”15级最大法力“,”最大法力成长“,是强相关的,由此可以做出属性筛选,最终保留的属性如下:
features_remain = ['15级生命', '15级物理攻击', '15级物理防御', '15级最大法力', '15级每5秒回血', '15级每5秒回蓝', '移速', '攻速成长', '近/远程?']
数据规范化
将攻击范围字段(”近/远程?“)转换为 0 和 1
data_new['近/远程?'] = data_new['近/远程?'].map({'远程': 1, '近程': 0})
EM 聚类计算
采用高斯混合模式,并把生成的类别写入 csv 文件中
# 构造 GMM 聚类 gmm = GaussianMixture(n_components=20, covariance_type='full') gmm.fit(data_new) # 训练数据 prediction = gmm.predict(data_new) # print(prediction) hero_data.insert(0, '分组', prediction) hero_data.to_csv('hero_out.csv', index=False, sep=',', encoding='gb18030')
饼图输出
为了更加直观的查看各个英雄的分组情况,这里使用饼图来做可视化 首先取出数据的”分组“和”名称“两个字段,并对”分组“字段进行分组处理
df = hero_data[['分组', '名称']] grouped = df.groupby(['分组'])
然后取出分组中的数值,并用 pyecharts 来画饼图
from pyecharts import Pie k = [] for name, group in grouped: k.append({name: list(group['名称'].values)}) kk = [] for i in k: for k, v in i.items(): kk.append(v) length = [] key = [] for i in kk: key.append(str(i)) length.append(len(i)) pie = Pie('英雄完全属性分类图', title_pos='center') pie.add("", key, length, is_label_show=True, legend_pos="bottom", legend_orient="vertical",) pie.render()
抓取英雄初始属性
要想获得更加全的英雄数据,还是需要到网上抓取,这样才能够保证英雄的数量是最新的。这里我使用的是db.18183.com/ 网站的数据,页面如下:
获取英雄页面 URL
使用 BeautifulSoup 来定位到 class 为 mod-iconlist 的 ul 元素,里面保存的就是各个英雄的页面
url = 'http://db.18183.com/' url_list = [] res = requests.get(url + 'wzry').text content = BeautifulSoup(res, "html.parser") ul = content.find('ul', attrs={'class': "mod-iconlist"}) hero_url = ul.find_all('a') for i in hero_url: url_list.append(i['href'])
抓取详细信息
循环抓取到的 URL 列表,抓取每个英雄的详细信息
base_url = 'http://db.18183.com/' detail_list = [] for i in url: # print(i) res = requests.get(base_url + i).text content = BeautifulSoup(res, "html.parser") name_box = content.find('div', attrs={'class': 'name-box'}) name = name_box.h1.text hero_attr = content.find('div', attrs={'class': 'attr-list'}) attr_star = hero_attr.find_all('span') survivability = attr_star[0]['class'][1].split('-')[1] attack_damage = attr_star[1]['class'][1].split('-')[1] skill_effect = attr_star[2]['class'][1].split('-')[1] getting_started = attr_star[3]['class'][1].split('-')[1] details = content.find('div', attrs={'class': 'otherinfo-datapanel'}) # print(details) attrs = details.find_all('p') attr_list = [] for attr in attrs: attr_list.append(attr.text.split(':')[1].strip()) detail_list.append([name, survivability, attack_damage, skill_effect, getting_started, attr_list])
保存到 csv 文件
open 一个文件,把对应的列表字段存入
with open('all_hero_init_attr.csv', 'w', encoding='gb18030') as f: f.write('英雄名字,生存能力,攻击伤害,技能效果,上手难度,最大生命,最大法力,物理攻击,' '法术攻击,物理防御,物理减伤率,法术防御,法术减伤率,移速,物理护甲穿透,法术护甲穿透,攻速加成,暴击几率,' '暴击效果,物理吸血,法术吸血,冷却缩减,攻击范围,韧性,生命回复,法力回复\n') for i in details: try: rowcsv = '{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}'.format( i[0], i[1], i[2], i[3], i[4], i[5][0], i[5][1], i[5][2], i[5][3], i[5][4], i[5][5], i[5][6], i[5][7], i[5][8], i[5][9], i[5][10], i[5][11], i[5][12], i[5][13], i[5][14], i[5][15], i[5][16], i[5][17], i[5][18], i[5][19], i[5][20] ) f.write(rowcsv) f.write('\n') except: continue
数据清理
因为这个网站可能做的不是很用心,有些属性会存在两个百分号和为空的情况,如图:
所以需要处理下。
对于两个百分号,直接使用 notepad++ 把所有的 %% 的替换为单 % 即可
对于为空的字段,使用如下代码处理,填为 0
# 把空值设置为0 data_init = data_init.fillna(0)
完成
对于数据规范化,GMM 聚类和饼图呈现,都和前面类似,不再赘述,下面来看看饼图效果
虽然通过这两张饼图,没有办法一下子提高你手残的毛病,但是明确了英雄的分类,不是离王者更近了一步吗
完整代码在这里: github.com/zhouwei713/…
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 设计模式——迭代器模式(遍历王者荣耀和英雄联盟英雄信息)
- Python爬取王者荣耀英雄皮肤高清图片
- 深入浅出聚类算法!如何对王者英雄聚类分析,探索英雄之间的秘密
- 2019年英雄帖
- 王者编程大赛之三 — 01背包
- 说说Flutter中的无名英雄 —— Focus
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。