数据分析实战45讲
陈旸
清华大学计算机博士
立即订阅
17165 人已学习
课程目录
已完结 48 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 你为什么需要数据分析能力?
免费
第一模块:数据分析基础篇 (16讲)
01丨数据分析全景图及修炼指南
02丨学习数据挖掘的最佳路径是什么?
03丨Python基础语法:开始你的Python之旅
04丨Python科学计算:用NumPy快速处理数据
05丨Python科学计算:Pandas
06 | 学数据分析要掌握哪些基本概念?
07 | 用户画像:标签化就是数据的抽象能力
08 | 数据采集:如何自动化采集数据?
09丨数据采集:如何用八爪鱼采集微博上的“D&G”评论
10丨Python爬虫:如何自动化下载王祖贤海报?
11 | 数据科学家80%时间都花费在了这些清洗任务上?
免费
12 | 数据集成:这些大号一共20亿粉丝?
13 | 数据变换:考试成绩要求正态分布合理么?
14丨数据可视化:掌握数据领域的万金油技能
15丨一次学会Python数据可视化的10种技能
16丨数据分析基础篇答疑
第二模块:数据分析算法篇 (20讲)
17 丨决策树(上):要不要去打篮球?决策树来告诉你
18丨决策树(中):CART,一棵是回归树,另一棵是分类树
19丨决策树(下):泰坦尼克乘客生存预测
20丨朴素贝叶斯分类(上):如何让机器判断男女?
21丨朴素贝叶斯分类(下):如何对文档进行分类?
22丨SVM(上):如何用一根棍子将蓝红两色球分开?
23丨SVM(下):如何进行乳腺癌检测?
24丨KNN(上):如何根据打斗和接吻次数来划分电影类型?
25丨KNN(下):如何对手写数字进行识别?
26丨K-Means(上):如何给20支亚洲球队做聚类?
27丨K-Means(下):如何使用K-Means对图像进行分割?
28丨EM聚类(上):如何将一份菜等分给两个人?
29丨EM聚类(下):用EM算法对王者荣耀英雄进行划分
30丨关联规则挖掘(上):如何用Apriori发现用户购物规则?
31丨关联规则挖掘(下):导演如何选择演员?
32丨PageRank(上):搞懂Google的PageRank算法
33丨PageRank(下):分析希拉里邮件中的人物关系
34丨AdaBoost(上):如何使用AdaBoost提升分类器性能?
35丨AdaBoost(下):如何使用AdaBoost对房价进行预测?
36丨数据分析算法篇答疑
第三模块:数据分析实战篇 (7讲)
37丨数据采集实战:如何自动化运营微博?
38丨数据可视化实战:如何给毛不易的歌曲做词云展示?
39丨数据挖掘实战(1):信用卡违约率分析
40丨数据挖掘实战(2):信用卡诈骗分析
41丨数据挖掘实战(3):如何对比特币走势进行预测?
42丨当我们谈深度学习的时候,我们都在谈什么?
43丨深度学习(下):如何用Keras搭建深度学习网络做手写数字识别?
第四模块:数据分析工作篇 (2讲)
44丨如何培养你的数据分析思维?
45丨求职简历中没有相关项目经验,怎么办?
加餐 (1讲)
加餐丨在社交网络上刷粉刷量,技术上是如何实现的?
结束语 (1讲)
结束语丨当大家都在讲知识和工具的时候,我更希望你重视思维和实战
数据分析实战45讲
登录|注册

29丨EM聚类(下):用EM算法对王者荣耀英雄进行划分

陈旸 2019-02-18
今天我来带你进行 EM 的实战。上节课,我讲了 EM 算法的原理,EM 算法相当于一个聚类框架,里面有不同的聚类模型,比如 GMM 高斯混合模型,或者 HMM 隐马尔科夫模型。其中你需要理解的是 EM 的两个步骤,E 步和 M 步:E 步相当于通过初始化的参数来估计隐含变量,M 步是通过隐含变量来反推优化参数。最后通过 EM 步骤的迭代得到最终的模型参数。
今天我们进行 EM 算法的实战,你需要思考的是:
如何使用 EM 算法工具完成聚类?
什么情况下使用聚类算法?我们用聚类算法的任务目标是什么?
面对王者荣耀的英雄数据,EM 算法能帮助我们分析出什么?

如何使用 EM 工具包

在 Python 中有第三方的 EM 算法工具包。由于 EM 算法是一个聚类框架,所以你需要明确你要用的具体算法,比如是采用 GMM 高斯混合模型,还是 HMM 隐马尔科夫模型。
这节课我们主要讲解 GMM 的使用,在使用前你需要引入工具包:
from sklearn.mixture import GaussianMixture
我们看下如何在 sklearn 中创建 GMM 聚类。
首先我们使用 gmm = GaussianMixture(n_components=1, covariance_type=‘full’, max_iter=100) 来创建 GMM 聚类,其中有几个比较主要的参数(GMM 类的构造参数比较多,我筛选了一些主要的进行讲解),我分别来讲解下:
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《数据分析实战45讲》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(27)

  • 王彬成
    有一个疑惑,在数据规范化的时候,为何Z-Score进行规范化,而不是Min-Max进行规范化,虽然最后的结果是差不多的。
    请问在数据规范化时,何时用Z-Score进行规范化,何时是Min-Max
    2019-02-24
    1
    12
  • 哆哩咪fa👻
    才买的课,请问有vx群或者可以相互沟通的群么
    2019-02-18
    10
  • iamtalent123
    老师,请问有没有什么方法在得到相关性系数后,自动筛选出不太相关的特征呢?在特征比较多的时候,自己一个一个的看是不是有点太费时了?
    2019-03-20
    5
  • Grandia_Z
    画热力图时 为什么没有“最大攻速”和“攻击范围”这两项
    2019-02-18
    1
    5
  • Frank
    老师,covariance_type这个参数,什么情况下选择什么类型,能不能再说的详细点儿呢?
    2019-03-10
    4
  • third
    思考:为什么分类越少,反而指标分数越高,分类效果越好?
    总样本过少,分成的类越多,每个类的所拥有的个体相对越少,类中个体差异变大,导致指标分数变低
    为3个
    [2 2 1 2 1 1 1 1 2 2 2 2 2 0 2 2 2 2 1 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0
     0 0 0 0 0 0 0 0 0 2 0 2 0 1 0 1 0 0 2 2 0 0 1 2 1 1 2 1 0 0 0 0]
    34.74970397246901

    为30
    [ 1 20 5 13 26 15 14 5 8 20 16 20 13 0 22 16 19 22 26 10 6 4 10 4
      4 4 10 12 3 27 0 27 29 3 27 3 3 24 27 18 29 3 3 27 3 18 20 27
     20 3 21 11 2 23 23 1 28 11 25 26 28 2 17 1 9 11 11 7 12]
    24.220124542171177
    2019-02-20
    4
  • 許敲敲
    最后一个 data_to_csv()也最好加上encoding='gb18030';不然会乱码

    编辑回复: 嗯 中文的话需要需要注意这个。

    2019-02-19
    4
  • 高桥凉瓜
    之所以热力图不显示最大攻速和攻击范围,是因为这两列的数据的类型是string,想要在热力图也显示这两项的话可以在构建热力图前就进行数据清洗:
    ```
    data[u'最大攻速'] = data[u'最大攻速'].apply(lambda x: float(x.strip('%'))/100)
    data[u'攻击范围']=data[u'攻击范围'].map({'远程':1,'近战':0})
    ```
    2019-03-27
    3
  • 从未在此
    问下老师,当几个特征相关性较大时,怎么选择最具有代表性的那个呢

    编辑回复: 相关性比较大的时候,可以任意选择其中一个,因为这些指标相关性比较大,所以你选择哪一个其实结果都相差不大。当然对于相关性比较大,不同人的理解是不同的额,比如你可以定义相关性大于0.9或者相关性大于0.8。

    2019-02-18
    3
  • 周飞
    1.不做特征选择的情况下,得到的Calinski_Harabaz 分数 大约是 23.1530273621 ,做特征选择的情况下 大约是:21.2142191471.
    2.聚类个数为3的时候 Calinski_Harabaz 分数 大约是 22.9119297953 。聚类个数为30的时候 Calinski_Harabaz 分数 大约是 21.2142191471
    2019-04-27
    1
  • 白夜
    这个相关性的计算原理能扩展讲讲吗?蛮好奇的
    2019-02-18
    1
  • 从未在此
    还有,非数值型的特征怎么进行聚类?

    编辑回复: 非数值的类型需要先转化为数值类型,比如“远程”转化为1,“近战”转化为0。这样才能做矩阵的运算。

    2019-02-18
    1
  • 挠头侠
    老师能否说明一下不同的协方差类型会带来一个什么样的效果呢?
    2019-05-14
  • 全部特征,聚类个数为3个:
    [0 0 2 0 2 2 2 2 0 0 0 0 0 0 0 0 0 0 2 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1
     1 0 1 1 1 1 1 1 1 0 0 0 1 2 0 2 0 0 0 0 0 1 2 0 2 2 0 2 1 1 0 1]
    22.91192979526994
    全部特征:聚类个数为30个
    [16 12 11 13 2 2 19 11 3 12 15 12 13 8 24 15 25 13 21 27 26 7 27 7
      7 7 27 22 28 1 8 1 29 28 1 1 28 6 20 18 29 28 28 1 28 18 12 20
     12 28 17 14 21 4 4 16 0 12 23 21 0 5 9 16 10 14 14 16 22]
    22.211084900636873
    2019-04-20
  • 滨滨
    为什么分类越少,反而指标分数越高,分类效果越好?
    总样本过少,分成的类越多,每个类的所拥有的个体相对越少,类中个体差异变大,导致指标分数变低
    2019-04-05
  • hlz-123
    老师,同一程序每次运行结果不一样,有时赵云和孙悟空聚在一类,有时赵云和兰陵王聚在一类,这种情况正常吗?
    2019-03-24
  • 三硝基甲苯
    在同样30个类的时候,没有任何特征过滤的时候分数大概是23附近,若是每种最大 成长 最初这三个里面去掉成长的话分数大概是19-21左右,若是只保留最大那一项,则分数可以到44-46左右。


    聚类30个和聚类3个分数差距,3个的分数比30个高
    2019-03-16
  • mickey
    # -*- coding: utf-8 -*-
    import sys
    reload(sys)
    sys.setdefaultencoding('utf8')

    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('./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秒回蓝', u'最大攻速', u'攻击范围']
    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()

    pd.set_option('mode.chained_assignment', None)
    data[u'最大攻速'] = data[u'最大攻速'].apply(lambda x: float(x.strip('%')) / 100)
    data[u'攻击范围'] = data[u'攻击范围'].map({u'远程': 1, u'近战': 0})

    # 采用 Z-Score 规范化数据,保证每个特征维度的数据均值为 0,方差为 1
    ss = StandardScaler()
    data = ss.fit_transform(data)

    #print(data)

    # 构造 GMM 聚类
    gmm = GaussianMixture(n_components=3, covariance_type='full')
    gmm.fit(data)
    # 训练数据
    prediction = gmm.predict(data)
    print(prediction)

    # 将分组结果输出到 CSV 文件中
    data_ori.insert(0, '分组', prediction)
    data_ori.to_csv('./hero_out2.csv', index=False, sep=',', encoding='utf-8')

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

        分组 英雄 最大生命 生命成长 初始生命 ... 初始每5秒回蓝 最大攻速 攻击范围 主要定位 次要定位
    0 0 夏侯惇 7350 288.8 3307 ... 15 28.00% 近战 坦克 战士
    ...
    43 1 张良 5799 198.0 3027 ... 18 14.00% 远程 法师 NaN
    ...
    68 2 百里守约 5611 185.1 3019 ... 16 28.00% 远程 射手 刺客

    [69 rows x 24 columns]
    23.869655882044263
    2019-03-01
  • mickey
    问题1:
    data[u'最大攻速'] = data[u'最大攻速'].apply(lambda x: float(x.strip('%')) / 100)
    会产生 SettingWithCopyWarning 警告
    解决方法:使用 pd.set_option('mode.chained_assignment', None) 屏蔽警告

    问题2:
    导出文件时,会报UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
    解决方法:
    设置编码 data_ori.to_csv('./hero_out.csv', index=False, sep=',', encoding='utf-8')
    2019-03-01
  • mickey
    跑案例提示如下,请问老师怎么破?谢谢。

    SettingWithCopyWarning:
    A value is trying to be set on a copy of a slice from a DataFrame.
    Try using .loc[row_indexer,col_indexer] = value instead

    See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
      data[u'最大攻速'] = data[u'最大攻速'].apply(lambda x: float(x.strip('%')) / 100)
    E:\DevelopTool\Python\Python27\lib\site-packages\pandas\core\indexes\base.py:3259: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal
      indexer = self._engine.get_indexer(target._ndarray_values)
    G:/Program/python/Geekbang/DataAnalysis/Part01/Lesson29/01_GMM.py:31: SettingWithCopyWarning:
    A value is trying to be set on a copy of a slice from a DataFrame.
    Try using .loc[row_indexer,col_indexer] = value instead

    See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
      data[u'攻击范围'] = data[u'攻击范围'].map({'远程': 1, '近战': 0})
    E:\DevelopTool\Python\Python27\lib\site-packages\sklearn\preprocessing\data.py:625: DataConversionWarning: Data with input dtype int64, float64 were all converted to float64 by StandardScaler.
      return self.partial_fit(X, y)
    E:\DevelopTool\Python\Python27\lib\site-packages\sklearn\utils\extmath.py:776: RuntimeWarning: invalid value encountered in true_divide
      updated_mean = (last_sum + new_sum) / updated_sample_count
    ...
    Traceback (most recent call last):
      ...
    ValueError: Input contains NaN, infinity or a value too large for dtype('float64').
    2019-03-01
收起评论
27
返回
顶部