讲座 | 如何轻松有效地预处理数据

作者:Siraj Raval
课堂:The Best Way to Prepare a Dataset Easily | Bilibili | Youtube
源码:llSourcell.Prepare dataset challenge | Github

本课堂的核心是讲述数据分析前夕的数据预处理过程,包括准备数据阶段和处理数据阶段。再具体以实例:通过大脑扫描公共数据集来建模、分析,预测某人是否在冥想。

更新进度

  • 2018.11.20:重新整理「数据预处理」章节,细化了预处理的细节,且重新整理了预处理的结构;

准备数据

  • 准备数据阶段:决定使用何种数据,这跟你试图解决的问题相关。
  • 关于数据来源:能使用公共数据集解决的问题,尽量使用公共数据集。若公共数据集无法满足你的需求,引用毛主席的老话:没有条件便自己创造条件。即我们通过网络爬虫形式,把原始网页中的数据扒取下来,自己来 “创造” 数据集。

公共数据集

谷歌高级搜索

  • 官方网址Google 高级搜索
  • 使用方式:顾名思义,即通过高级搜索的限制条件去获得更精确的搜索结果。具体地,我们侧重关注以下检索项,可获得意想不到的效果。
    • 关键字部分:填写问题相关的关键词;
    • 网站或域名:填写 .edu.gov.org 等,即为确保数据的权威可靠性,尽可能从教育、政府、组织机构中获取公共数据集;
    • 文件类型:可指定为 csv ( 逗号分隔值 )、xls ( Microsoft Excel ) 等文件类型,Python 对 csv、xls 提供了较好的库支持,为了更便捷进行数据处理,则优先选择此类格式的文件。

Kaggle

  • 官方网址Kaggle
  • 推荐理由:Kaggle 由 Anthony Goldbloom 创立,主要为开发商和数据科学家提供举办机器学习竞赛、托管数据库、编写和分享代码的平台 ( 与谷歌达成合作关系 )。由此可见:

    • Kaggle 的每个竞赛都是独立的,无需设置项目范围然后收集数据,这让你有时间专注其它技能。
    • Kaggle 的每个数据集都有要解决的现实问题,要面向参与竞赛的人群,让参赛者更容易掌握业务知识和数据集的结构特征,因此数据集的描述是不可缺少的。

      不妨体验下 Kaggle 社区提供的入门案例 泰坦尼克:灾难中的机器学习,其相关的数据集描述:Titanic: Machine Learning from Disaster

  • 入门指南:参考文章 机器之心. Kaggle 如何入门. zhihu.com 整理而得。

    • 选择一种编程语言:你是一个毫无经验的新手,推荐 Python,因这是一种通用编程语言,你可以在整个流程中都使用它。

    • 学习探索数据的基础:加载、浏览和绘制你的数据(即探索性分析)的能力,因为它可以为你将在模型训练过程中做的各种决策提供信息。

      若你选择了 Python 路线,推荐使用专门为这个目的设计的 Seaborn 库。其中有高层面的绘图函数,可以绘制许多最常见和有用的图表。可参考资料:

    • 训练你的第一个机器学习模型:将数据集分成独立的训练集和测试集,交叉验证避免过拟合以及使用合适的表现评价指标。对于 Python,最好的通用机器学习库是 Scikit-Learn。可参考资料:

    • 解决入门级竞赛Getting Started 竞赛非常适合初学者,因为它们给你提供了低风险的学习环境,并且还有很多社区创造的教程。

      Kaggle 的竞赛分成四个类别:
      Featured:通常是由公司、组织甚至政府赞助的,奖金池最大。
      Research:研究方向的竞赛,只有很少或没有奖金。它们也有非传统的提交流程。
      Recruitment:这些是由想要招聘数据科学家的公司赞助的。目前仍然相对少见。
      Getting Started:这些竞赛的结构和 Featured 竞赛类似,但没有奖金。它们有更简单的数据集、大量教程和滚动的提交窗口让你可以随时输入。

网络爬虫

网站 API

  • 当公共数据集无法满足我们的需求时,则需要自定义采集数据。而采集数据则通过网络爬虫实现。值得注意的是,并不是所有的网页,都需要我们花费大功夫去扒取获得,而是它们本身就提供了调用数据的 API。
  • 当然,也有 Github 大神搜集并整理了较实用的 API:TonnyL. Awesome APIs

网页爬虫

  • Beautiful Soup:Beautiful Soup 是一个可以从 HTML 或 XML 文件中提取数据的 Python 库。
  • Web Magic:Web Magic 是一个简单灵活的 Java 爬虫框架。基于 WebMagic,你可以快速开发出一个高效、易维护的爬虫。

处理数据

  • 为什么要对数据预处理:确保数据质量,以保证预测的结果更精确。而数据质量涉及许多因素,例如准确性、完整性、一致性、可信性和可解释性,针对不同的特性,都有对应的 处理策略

    注意,数据预处理的主要任务之间存在许多重叠工作,若前面章节有阐述的,后面涉及的则略过。

  • 数据预处理的主要任务:

    • 数据清洗:缺失值处理、光滑噪声数据、识别和删除离群点。

      关于数据清洗,也推荐阅读具有实操意义的一篇博文:TowardsDataScience. How to Handle Missing Data

    • 数据集成:多个数据源的数据合并,存放于同一个数据仓库中。

      • 实体识别问题:来自多个信息源,各数据源中的实体之间如何匹配,这涉及实体识别问题。如不同数据来源于不同数据库中,现实意义上它们是同一实体,但它们属性的元数据表达却不同 ( 如主键 )。
      • 冗余和相关分析:集成多个数据源,数据中可能有多组属性重复存在。而冗余可被相关分析检测到,如针对分类 ( 标称 ) 属性的卡方检验、数值属性的相关系数、数值属性的方差和协方差。
      • 元组重复:元组级检测重复。
    • 数据归约:在尽可能保持数据原貌前提下,最大限度精简数据量。策略包括:
      • 维归约:也称为特征归约,减少所考虑的属性的个数。方法包括:小波变换、主成分分析、属性子集选择等。当然利用冗余和相关分析也是可行的。
      • 数量归约:用替代的、较小的数据表示形式替换原数据。方法包括:回归和对数-线性模型、聚类、降维等。
    • 数据变换:主要思想是将数据变换或统一成适合数据挖掘的形式。方法可以是数据归一化、数据离散化、概念分层等。

      • 特征构造:由给定的属性构造新的属性并添加至属性集中。
      • 聚集分解:对数据进行 汇总 或者 聚集。如聚集日销售数据。与之相对的是 分解,如常见的 “日期” 属性,不同的需求,我们要解构的粒度是不同的。如预测当日的气温变化,则我们可把年和月份剔除。
      • 归一化:针对每一个特征 ( 维度 ),去均值和方差归一化。即把属性数据按比例缩放,让所有特征在统一数量级上运作,如此一来数据指标之间就有了可比性。
      • 离散化:把属性值的原始值用区间标签或者概念标签替换,即这些标签可递归地组织成更高层概念,导致数值属性的 概念分层

        例如,我们 对年龄进行分层:1 to 17 为 Adolescent;18 to 45 为 Adult;46 以上为 Senior。

数据清洗

  • 缺失值处理:某些实例数据中属性值为空,我们通过遍历数据集将其剔除。若数据集中存在大量实例含有缺失值的情况,则我们采用 填补缺失值 的方法。值得注意的是,根据不同情况,填补缺失值有多种方式:

    • 人工填写缺失值。
    • 使用全局常量填充缺失值:N/A 或者 $\infty $。
    • 使用属性的中心度量:若是对称的数据分布,则使用均值;若是倾斜的数据分布,则使用中位数。
    • 使用最可能的值填充缺失值:回归、贝叶斯形式化的推理工具或决策树。

      某些情况下,缺失值并不意味数据有错误。例如在申请信用卡时,要求填写申请人的驾驶执照号,没有的人可填写 “无” 或者不填。

  • 光滑噪声:噪声指数据中存在着错误或异常 ( 偏离期望值 ) 的数据,这些数据对数据的分析造成了干扰。我们可通过 分箱回归离群点分析 等噪声光滑技术来消除噪声。

    • 分箱:考察数据的近邻 ( 周围的值 ) 来光滑有序数据值。
    • 回归:用一个函数拟合数据来光滑数据。
    • 离群点分析:五数概括 ( 中位数、四分位数、最大最小观测值 )、箱线图与离群点;或通过聚类来检测离群点。

数据集成

  • 实体识别问题
    • 问题描述:来自多个信息源,各数据源中的实体之间如何匹配,这涉及实体识别问题。如不同数据来源于不同数据库中,现实意义上它们是同一实体,但它们属性的元数据表达却不同 ( 如主键 )。
    • 解决方法:每个属性的元数据包含名字、含义、数据类型和属性的允许值范围,以及处理空值的空值规则。这样的元数据可帮助我们避免模式集成的错误。
  • 冗余和相关分析:这里讨论的冗余是对应于数据的属性 ( 特征 ) 层面讨论的。
    • 分类 ( 标称 ) 属性的 卡方检验 ( $\chi^2$ ),发现属性 A、B 之间的相关联系。
    • 数值数据的 相关系数:计算属性 A、B 之间的相关系数 ( 又称 Pearson 积矩系数 ),估计这两个属性的相关度。
    • 数值数据的 协方差:协方差和方差是两个类似的度量 ( 方差可理解为协方差的特殊形式 ),其作用是评述两个属性如何一起变化。

数据归约

  • 维归约:也称为特征归约,减少所考虑的属性的个数。

    • 通俗理解:即从原有的特征中删除不重要或不相关的特征。比如,某些实例数据中属性值与所研究的问题无关,我们可以选择性地剔除。

      本课堂实例中,是预测志愿者是否在冥想。而相关数据集呈现三种特征:精神专注度、冷静度以及志愿者的年龄。而志愿者是否发生冥想活动,很明显与性别无关,则可选择性地剔除该属性。

    • 方法包括:小波变换、主成分分析、属性子集选择等。当然利用冗余和相关分析也是可行的。

  • 数量规约:用替代的、较小的数据表示形式替换原数据。

    • 通俗理解:即通过对特征进行重组来减少特征的个数。比如,某些实例数据中属性 ( 维度 ) 太多,我们人类大脑是难以理解它的。则我们可通过降维方法以及可视化工具,以二维或者三维的的形式复现数据 ( 的特征 )。
    • 方法包括:回归和对数-线性模型、数据立方体聚集、聚类、降维等。

数据变换

  • 归一化:针对每一个特征 ( 维度 ),去均值和方差归一化。即把属性数据按比例缩放,让所有特征在统一数量级上运作,如此一来数据指标之间就有了可比性。
  • 离散化:把值用区间标签或者概念标签替换,即这些标签可递归地组织成更高层概念,导致数值属性的 概念分层
    • 数值属性:在实际操作中,即把连续型特征的值离散化,使之成为少量的区间,每个区间映射到一个离散符号。这种技术的好处在于简化了数据描述,并易于理解数据和最终的挖掘结果。
    • 标称 (分类) 属性:标称属性具有有穷多个不同值,且值之间无序。例如地位位置、年龄层次等。对于标称属性,我们需要人工定义概念分层。
  • 向量化:当我们已基本完成数据处理阶段的工作,得到可供使用的数据集。那么紧接着的步骤,即把实例数据转换成 特征向量 ( 向量是特征的数值表示形式 ),所有实例的特征向量组成 特征矩阵。然后,在 Python 中通过 NumpyPandas 包装,即实际上让 narray 数组成为特征矩阵的存储和运算的媒介。

    当完成以上流程后,数据预处理阶段即可告一段落,紧接着便可开始开始训练模型了。

    由于篇幅的缘故,数据预处理的讨论暂到此为止。当然,数据预处理的内容不仅如此,更详细的理论细节可参详 Jiewei Han 的《数据挖掘:概念与技术》$^{[1]}$。 而数据预处理在 Python 中如何实现,则参考 Keras 之父弗朗索瓦·肖莱的 《Python深度学习》$^{[2]}$。

参考资料