Check your data! 数据预处理血泪教训

上图是一个经典的数据分析/数据挖掘步骤链(pipeline)。在将数据送到(load)你选择的model之前,数据必须经过提取(select/extract)、预处理(preprocess)包括转化(transform)才能形成一个单纯的算法model可以理解的结构化形式。

提到这个长长的数据处理的过程,有类似经验的人都会感叹一句:道阻且艰... 数据处理占据了整个数据分析/数据挖掘周期的80%-90%的时间;大量的ad hoc的工作存在于提取(select/extract)的环节:正则表达式,匪夷所思的细节,不合规范的形式...

然而,对于ad hoc并没有更好的办法,只能见招拆招,并且熟练程度和踩过坑的个数成正比。我因为踩过的坑不算多,就不强行总结经验了(事实上,提取环节的经验总结应该是领域/任务相关的, 比如采用问卷调查的社会学研究的数据提取 https://www.socialresearchmethods.net/kb/statprep.php)。提取来的数据通常被填充入有行列结构的数据表中,在此之后,数据预处理的经验在不同任务中也就有更多的共同点。

这篇中以我的经验为模板+参考资料,总结一下数据预处理的要点。

数据预处理的经验步骤基本可以分为:

  • 数据清洗 (data cleaning)
  • 数据整合 (data integration)
  • 数据转化 (data transformation):正则化(normalization) 等等
  • 其他:离散化(discretization), 减少使用的变量(data reduction)等等

参考 http://www.cs.ccsu.edu/~markov/ccsu_courses/datamining-3.html, http://www.iasri.res.in/ebook/win_school_aa/notes/Data_Preprocessing.pdf

数据清洗主要包括填充未知值,处理噪声和异常值等等。在我的经验里,如果使用数据的目的不是为了分析数据集性质本身,而是将数据作为训练/测试一个算法的输入的话,我认为这一步应当适当地削减 - 最多做到用平均值来代替未知值就可以了。一方面,如果数据集足够大,可以将异常值直接丢弃,或者不加处理地喂给算法,也不会让结果产生很大的浮动。另一方面,算法评估中有一项『对于噪声的敏感程度』(对有数学表达的解可以用perturbation analysis来度量噪声对于结果的理论影响,对没有数学表达的算法直接用加入不同级别噪声的多次模拟实验结果来判断);在没有ground-truth的完整数据集的情形下,我们最好还是使用当前的未人工填充的数据集中的完整部分。

在数据清洗中,我认为最基本的是进行数据表检查,需要检查的项目包括:

检查单个数据表基本项目:

  • 条目个数
  • 所有条目格式一致
  • 文本文件检查开头结尾的冗余字符(' ', ' ', 空格, 逗号...)
  • 条目中每一项的数据类型一致/格式一致情况;将头尾的冗余字符全部去掉
  • 异常数据和空值的情况

如果说数据清洗不慎会略微影响算法的结果好坏,数据整合(data integration)中产生的错误则是数据使用的错误,会直接使得算法无法生成有效的结果。一般来说,如果运行算法发现结果很类似random的情形,就需要检查一下在数据整合中哪个环节出错了。

数据整合是个非常头疼的问题。数据整合是把多个来源的数据进行整合,因此一定要事先生成一张权威的索引表,用来标注数据项的主体在所有数据表中的唯一标识。若是成功生成了一张索引,可以说数据整合就完成了一大半。

在数据整合中,需要检查的项目主要有:

多个数据表交叉检查 - 发生于preprocess: data integration中

  • 对照索引/别名表(如果没有必须生成),检查其他数据表中的条目对索引/别名的覆盖情况
  • 记录下没有完全匹配索引/别名的情况

整合完数据后,就可以进一步进行数据项属性值的处理了,这也是任务相关的内容,这方面我经验(踩坑)还不多,因此不做总结。

其他

数据预处理是很多零碎的任务逻辑松散地组合在一起。由于数据预处理是上游环节的任务,在之后的算法运行与分析中,一遇到奇怪问题,首先就会本能地怀疑是不是预处理的环节出错了。这是一种复杂的心情:

  • 不希望数据预处理出错,这样就要从头来一边;
  • 希望最好是数据预处理而不是算法本身的问题,因为数据预处理的问题更容易解决。

无论如何,有件事是确定的:在之后的环节中,你会无数次遇到各种冒出来的问题,而大部分问题都会让你怀疑数据预处理过程中出了错误,因此需要无数次地转头确认你之前所做的数据预处理。

人的记忆始终是存在遗忘的,并且遗忘没有规律的事物的速度比你想象的还要快(血泪教训)...因此,在进行数据预处理时,要同时进行文本记录。社会学研究中建议研究者们建立一个codebook,记录:

  • variable name 变量名称 - 索引/别名
  • variable description 变量描述 - 属性名
  • variable format (number, data, text) 变量格式 - 数据类型
  • instrument/method of collection 采集方法 - 处理步骤
  • date collected 采集日期 - 日志
  • respondent or group 对象 - 背景介绍
  • variable location (in database) 变量位置 - 单个数据表以及数据库结构描述
  • notes 笔记 - 其他备忘

写尽量清晰详尽的日志。当你在后续过程中遇到问题,转而回头翻看数据预处理,你会为自己当时保留了详细的记录而感到庆幸。

原文地址:https://www.cnblogs.com/manqing/p/6678642.html