在机器学习任务中,数据集的质量优劣对数据分析的结果影响非常大,所谓Garbage in, garbage out,数据决定模型的上限,因此数据质量成为数据分析流程不可或缺的一个环节。即使是像Kaggle那样主办方已经把数据集准备好的场景,也需要评估train set和test set的分布是否一致,存不存在偏斜等。如果两者不一致,可能会导致离线cv分数非常高,可是在leaderborad却下跌了很多,以至于大量花在模型调参上的功夫其实都白费了。
本文不对数据采集的过程深入探讨,即不讨论怎么在数据采集过程中保证数据的准确性;而是聚焦在对现有的数据集,如何快速高效地评估数据集的质量,找出数据集中存在的瑕疵问题。
通常我们使用pandas手工地检查数据集,不停地做出假设然后验证;现在介绍给大家一个神器:Facets
Facets
Facets是Google的一个开源项目,用于帮助理解和分析机器学习数据集的可视化工具。该项目使用基于Typescript编写的PloymerWeb组件,可以轻松地嵌入到Jupyter notebook或网页。
Facets包含2个可视化组件:Overview 和 Dive。可使用Overview了解数据集每个特征的分布,或使用Dive研究个别样本的细节。这两个组件让你可以轻松地调试自己的数据,这在机器学习中与调试模型一样重要。
若想通过机器学习得到理想的结果,需要深入地理解数据。然而数据集可能包含数以亿计的数据点,每个数据点又包含数百个(甚或数千个)特征,因此,直观地理解整个数据集几乎是不可能的。可视化工具有助于发现大型数据集的微妙之处并从中发现真知灼见。一张图片传达的信息胜过千言万语,而一个直观的可视化工具则更胜一筹。
Facets自动帮助用户快速理解其数据集特征的分布情况,并且能够在同一个视图中比较多个数据集(如训练集和测试集)。将妨碍机器学习过程的常见数据问题暴露到眼前,例如,异常的特性值、缺失值比例很高的特征、分布不均的特征,以及数据集之间偏态分布的特征。
Overview展示了训练集和测试集的分布
在图表中,这些特征按照"不均匀性"排序,分布最不均匀的特征位于顶部。红色的数字则暗示可能的故障点,例如 高比例的缺失值、同一特征在不同数据集之间分布差异很大等
有两种使用Facets的方法:
- 在官网直接上传并可视化用户自己的数据集,而不必安装或设置任何软件,甚至不需要数据离开您的计算机
- 使用jupyter notebook的Extension(文章后面有安装教程)
Overview介绍
Overview提供了一个或多个数据集的high-level视图,用以给出可视化形式的feature-by-feature的统计分析,以及数据集之间的统计比较。该工具可以处理数值型特征、类别型(字符串)特征
Overview可以帮助揭露数据集的潜在问题:
- 不符合预期的特征取值
- 缺失值
- train/validate/test数据集的偏斜
Overview可视化的核心目的是 "异常检测"和"数据集间的分布比较"
生成Feature statistics
overview可以通过pip安装:
pip
TensorFlow 也需要被安装:之所以不在pip的依赖文件中,是允许用户自由选择安装cpu或gpu版本
目前支持两种数据源格式:
- ProtoFromDataFrames():TfRecord files of tensorflow Example protocol buffers
- ProtoFromTfRecordFiles():pandas DataFrames
以DataFrame为例:
from facets_overview.generic_feature_statistics_generator importimport pandas as
df = pd.DataFrame({'num' : [1, 2, 3, 4], 'str' : ['a', 'a', 'b', None]})proto = GenericFeatureStatisticsGenerator().ProtoFromDataFrames([{'name': 'test', 'table': df}])
feature statistics protocol buffer 是核心的数据结构,它存储了关于数据集的所有统计信息,使用GenericFeatureStatisticsGenerator()。ProtoFromDataFrames()函数生成。该函数的参数是一个dict的列表,每个字典描述一个数据集。
大数据集
这里的大数据集是指数据量大到无法一次全部读入内存。
分布式版本参见Facets Overview Spark project
对结果进行可视化
jupyter noetbook平台
安装jupyter插件
Note that for using Facets Overview in a Jupyter notebook, there are two considerations:
- In the notebook, you will need to change the path that the Facets Overview python code is loaded from to the correct path given where your notebook kernel is run from.
- You must also have the Protocol Buffers python runtime library installed: https://github.com/protocolbuffers/protobuf/tree/master/python. If you used pip or anaconda to install Jupyter, you can use the same tool to install the runtime library.
When visualizing a large amount of data in Dive in a Juypter notebook, as is done in the Dive demo Jupyter notebook, you will need to start the notebook server with an increased IOPub data rate. This can be done with the command jupyter notebook --NotebookApp.iopub_data_rate_limit=10000000.
生成HTML
from IPython.core.display importimportprotostr = base64.b64encode(proto.SerializeToString()).decode("utf-8")HTML_TEMPLATE = """<link rel="import" href="/nbextensions/facets-dist/facets-jupyter.html" > <facets-overview id="elem"></facets-overview> <script> document.querySelector("#elem").protoInput = "{protostr}"; </script>"""html = HTML_TEMPLATE.format(protostr=protostr)display(HTML(html))
protoInput 属性可以接收三种形式的DatasetFeatureStatisticsList protocol buffer:
- An instance of the DatasetFeatureStatisticsList javascript class, which is the class created by the protocol buffer compiler buffer.
- A UInt8Array containing the serialized binary of a protocol buffer.
- A string containing the base-64 encoded serialized protocol buffer, as shown in the code example above.
报错解决方法: 关键在于href="/nbextensions/facets-dist/facets-jupyter.html" 这里使用的是相对引用,因此 需要注意notebook的工作路径 我采用的办法是,直接把notebook放在 C:\ProgramData\jupyter下面。
Overview的价值?
是的,确切地讲,用pandas手动来进行这个层面的分析已经是一种最佳实践了。但是我们很容易忘记了要详细检查数据中每一列的所有指标。而这个工具就能确保我们不再遗忘这重要一步,并且将所有反常之处都标记出来。
数据结构解读 & Google序列化工具——Pb
Overview的可视化依靠feature statistics protocol buffer. Pb的messages存储了多个数据集、各个特征的统计量汇总。
顶层proto是DatasetFeatureStatisticsList,是一个DatasetFeatureStatistics的列表;每一个 DatasetFeatureStatistics表示单个dataset的多个特征统计量。
DatasetFeatureStatistics包含了一组FeatureNameStatistics;每个表示单个特征的各种统计量。
特征的数据类型不同(数值型、字符型、原始字节),特征统计量也不同。
数值型特征,特征统计量包含 min, mean, median, max and standard deviation。
字符型特征,特征统计量包含 average length, number of unique values and mode。
Feature statistics 包含了一个可选的field以支持带权重的统计量。
如果数据集包含样本权值信息,那么可以被用来计算带权重的统计量。
如果proto包含了weighted字段,那么可视化中会显示带权重的统计量,且用户可以在unweighted 与weighted 之间切换。
Feature statistics还包含了一个可选字段,用于 自定义统计量。
如果想要跟踪和可视化某些特征额外的统计量,可以在custom stats字段中添加。
以custom stat names到 custom stat values(numbers或strings)的映射形式。
Dive
Dive是一个工具,用来交互式探索高维的海量数据,使用户能够在higl-level与low-level之间切换自如。每一个样本,被表示为一个单独的项,样本可以通过它们的属性值被faceting/bucketing;让你更加清晰地洞察数据,甚至还能让你通过缩放来查看某一特定的数据。
从这里开始,很多事情都会变得很有趣。你可以按照行和列来撷取数据中一小个“facet”,观察它在所有特征值中的情况。就好比你在网购一双鞋,然后通过过滤工具筛选大小、品牌和颜色。Dive使得挖掘出复杂数据集的模式和异常值变得更加简单。
有兴趣可以直接去facets网站上,尝试上传你的数据并开始探索。
拓展
Protocol buffers
Protocol Buffers以下简称pb,是google开发的一个可以序列化 反序列化object的数据交换格式,类似于xml,但是比xml 更轻,更快,更简单。而且以上的重点突出一个跨平台,和xml json等数据序列化一样,跨平台跨语言。
归根到底,pb还是一个序列化反序列化工具,那么使用上来说其实我个人认为是没有json那么简单的,但是却可以保证即使是在python这种动态语言中,数据类型也不会出现错误。他的使用需要定义一个.proto文件,该文件里面会定义好数据类型和格式。我在这里就不再搬运各语言对应的字段,因为这些官方文档中都写的非常清楚。这里直接上最简单的使用。
安装:
直接在GitHub 上下载已经编译好了的 binary文件:protoc-3.6.1-win32.zip
gihub源码编译
下载源码
git clonecd
然后通过setup.py安装package:
python setup.py install
python setup.py build 是python编译这个module的过程, 这个过程比较复杂,最后会生成build文件夹。除去build过程后的install过程,就是复制build/lib下面的文件到用户指定的lib库。