童增再次致函要求日本政府对南京大屠杀谢罪

中国青年报客户端北京12月12日电(中国青年报·中国青年网记者 张蕾)今年12月13日是第6个南京大屠杀死难者国家公祭日。12月初,南京大屠杀幸存者95岁的胡信佳老人和91岁的金茂芝老人相继离世,侵华日军南京大屠杀遇难同胞纪念馆的统计数据显示,今年已有13位南京大屠杀幸存者去世,登记在册的在世南京大屠杀幸存者只剩78人。

近日,中国民间对日索赔联合会会长童增再次致函日本驻华大使横井裕转日本政府及日本首相安倍晋三,要求日本政府对南京大屠杀进行认真反省谢罪,对所有二战受害者真诚道歉赔偿。函件中写道,12月13日即将来临,82年前侵华日军在中国制造了惨绝人寰的南京大屠杀,“今天我们重提往事,不是因为第6个国家公祭日,而是因为日本政府未曾正视历史,也从未谢罪道歉”。“在又一个南京大屠杀纪念日和全国公祭日来临之际,我们真诚希望日本政府能从日本全国人民的福祉出发,从维护亚洲和世界的长久和平出发,对南京大屠杀进行认真反省谢罪,对所有二战受害者真诚道歉赔偿”。

最后,在对所有数据进行初步清洗之后,让我们看看我们的分析有多少出租车行程。

在本文的前一部分中,我们简要介绍了 trip_distance 列,在从异常值中清除它的同时,我们保留了所有小于 100 英里的行程值。这仍然是一个相当大的截止值,特别是考虑到黄色出租车公司主要在曼哈顿经营。Trimih 距离列描述出租车在接到乘客和乘客下车位置之间行驶的距离。然而,为了避免交通堵塞或道路工程等原因,人们通常可能会选择不同的路线。因此,作为 trip_distance 列的对应项,让我们计算上车和下车位置之间的最短可能距离,我们称之为 arc_distance:

上面代码块最酷的地方是它需要的内存可以忽略不计!它在过滤 Vaex 数据帧时,不会生成数据的副本,相反,它只创建对原始对象的引用,并在其上应用二进制掩码。掩码选择显示哪些行并用于将来的计算。这为我们节省了 100GB 的 RAM。

我们看到出租车价格,以及小费随着岁月的流逝而增加。现在让我们来看一下出租车的 trip_distance 和 arc_distance,出租车是以年为单位行驶的:

纽约市彩色热图编码:平均票价金额(左)和票价金额与行程的平均比率

每周每天和每天小时的平均小费百分比

对于一个超过 10 亿个样本的 Vaex 数据帧,在笔记本电脑上使用四核处理器进行 8 个聚合的分组操作只需不到 2 分钟

出行距离列中极端离群值的存在是考察出租车出行持续时间和平均速度的动机。这些功能在数据集中不易获得,但计算起来很简单:

使用 describe 方法获得数据帧的高级概述。注意,数据帧包含 18 列,但在此屏幕截图中只有前 7 列可见

再一次注意,单元执行时间非常短。这是因为显示 Vaex 数据帧或列只需要从磁盘读取前 5 行和后 5 行。这就引出了另一个重要的问题:Vaex 只会在必须的时候遍历整个数据集,它会尽可能少地传递数据。

从上面的图表我们可以看出,旅行次数随着距离的增加而减少。在大约 100 英里的距离上,分布会有一个很大的下降。目前,我们将使用此作为截止点,以消除基于行程距离的极端异常值:

南京市人民政府官网近日发布《关于南京大屠杀死难者国家公祭仪式有关事项的通告》,通告说,2019年12月13日上午将举行国家公祭仪式活动,当日10时01分至10时02分,南京全城将鸣笛致哀。

弧长计算公式涉及面广,包含了大量的三角函数和算法,特别是在处理大型数据集时,计算量很大。如果表达式或函数只使用来自 Numpy 包的 Python 操作和方法编写,Vaex 将使用机器的所有核心并行计算它。除此之外,VAEX 支持通过 NUBBA(使用 LLVM)或 Pythran(通过 C++加速)及时编译,从而提供更好的性能。如果你碰巧有一个 NVIDIA 图形卡,你可以通过 jit_CUDA 方法使用 CUDA 来获得更高的性能。

在我们的旅程结束之前,让我们再停一站,调查一下乘客如何支付乘车费用。数据集包含付款类型列,因此让我们看看它包含的值:

为了说明这个概念,让我们在一个数据集上做一个简单的探索性数据分析,这个数据集非常大,可以放入一个典型的笔记本电脑的 RAM 中。在这篇文章中,我们将使用纽约(NYC)出租车数据集,其中包含 2009 至 2015 年之间的超过 10 亿个标志性黄色出租车。数据可以从这个网站下载,并以 CSV 格式提供。完整的分析可以在这个 Jupyter notebook 中单独查看。

现在让我们研究出租车的平均速度,同时也为数据限制选择一个合理的范围:

我们看到上述三种分布图都有很长的尾巴。在尾部的某些值可能是合法的,而其他值可能是错误的数据输入。无论如何,现在我们还是保守一点,只考虑票价、总票价和小费低于 200 美元的行程。我们还要求票价金额、总金额值大于 0 美元。

我们今天使用的数据集跨越了 7 年。我们可以看到,随着时间的推移,一些收益的数量是如何演变的。使用 Vaex,我们可以快速执行核心分组和聚合操作。让我们来探讨 7 年来票价和行程是如何演变的:

在上面的单元块中,我们执行一个分组操作,然后是 8 个聚合,其中 2 个在虚拟列上。上面的单元块在我的笔记本电脑上执行不到 2 分钟。这相当令人印象深刻,因为我们使用的数据包含超过 10 亿个样本。不管怎样,让我们看看结果。以下是多年来驾驶出租车的费用演变过程:

使用 Vaex 打开内存映射文件只需要 0.052 秒,即使它们超过 100 GB

有趣的是,arc_distance 从来没有超过 21 英里,但是出租车实际行驶的距离可以是 5 倍大。事实上,有数百万的出租车旅行,下车位置在上车地点 100 米(0.06 英里)以内!

现在,让我们检查一下乘客计数栏。在一次出租车行程中记录的乘客人数最多为 255 人,这似乎有点极端。让我们计算一下每一位乘客的出行次数。这很容易通过值计数方法实现:

从上图中我们可以看出,乘客数超过 6 人的旅行可能是罕见的异常值,或者只是错误的数据输入。上面也有大量的 0 名乘客的旅行。既然现在我们还不知道这些旅行是否合理,那就让我们把它们过滤掉吧。

在处理这些数据集时,通常使用 3 种策略。第一个是对数据进行子抽样。它的缺点是显而易见的:可能会错过关键的部分,或者更糟的是,不看全部内容可能会对数据和它表达的事实有所曲解。还有一个策略是使用分布式计算。虽然在某些情况下这是一种有效的方法,但它会带来管理和维护集群的巨大开销。想象一下,必须为一个不在 RAM 范围内的数据集(比如在 30-50GB 范围内)设置一个集群会是什么样子的。对我来说,这似乎难以承受。或者,你可以租用一个强大的云实例,该实例具有处理相关数据所需的足够内存。例如,AWS 提供了具有兆字节 RAM 的实例。在这种情况下,你仍然需要管理云数据存储桶,在每次实例启动时等待从存储桶到实例的数据传输,处理将数据放到云上带来的遵从性问题,并处理在远程计算机上工作带来的所有不便。当然,成本就更不用说了,虽然起价很低,但随着时间的推移,成本往往会越来越高。

对于用 numpy 编写的复杂表达式,vaex 可以在 Numba、Pythran 甚至 CUDA(如果你有 NVIDIA GPU)的帮助下使用即时编译来大大加快计算速度

无论如何,让我们首先从极端异常值或错误的数据输入中清除这个数据集。一个好的开始方法是使用 describe 方法获得数据的高层次概述,该方法显示每个列的样本数、缺少的值数和数据类型。如果列的数据类型是数字,则平均值、标准偏差以及最小值和最大值也将被显示。所有这些统计数据都是通过对数据的一次传递来计算的。

平均票价和总金额,以及乘客每年支付的小费百分比

纽约市黄色出租车数据预览

描述方法很好地说明了 Vaex 的功耗和效率:所有这些统计数据都是在我的 MacBook Pro(15″, 2018, 2.6GHz Intel Core i7, 32GB RAM)上 3 分钟之内计算出来的。其他的库或方法需要分布式计算或 100GB 以上的云实例来执行相同的计算。有了 Vaex,你所需要的只是数据,你的笔记本电脑只需要几 GB 的内存。

在简单的情况下,当我们只关心为提供的服务获得最大票价时,最佳接送乘客的区域是纽约机场以及主要的大道,如 Van Wyck 高速公路和 Long Island 高速公路。当我们把旅行的距离考虑进去时,我们得到的是一张稍微不同的图片。 Van Wyck 高速公路、Long Island 高速公路大道以及机场仍然是接送乘客的好地方,但它们在地图上的重要性要小得多。然而,在 Hudson 河的西侧出现了一些新的热点地区,这些地区似乎可以赚到相当的利润。

童增写给日本政府要求其对南京大屠杀谢罪的信函。(中国民间对日索赔联合会供图)

从 descripe 的输出来看,很容易注意到数据中包含了一些严重的异常值。首先,让我们从检查取货地点开始。删除异常值的最简单方法是简单地绘制出上下车的位置,并直观地定义我们希望重点分析的纽约市的区域。由于我们使用的数据集太大了,直方图是最有效的可视化方法。用 Vaex 创建和显示直方图和热图是如此的快,这样的绘图可以更好地互动!

纽约 10 亿多个出租车出行的票价、总金额和小费的分布情况。在笔记本电脑上创建这些图只用了 31 秒!

让我们先找出平均来说能带来最好收益的接送乘客的地点。天真地说,我们可以画出一张接送地点的热图,用平均票价进行编码。然而,出租车司机自己也有成本,例如,他们得付燃料费。因此,把乘客带到很远的地方可能会导致更高的票价,但这也意味着更大的油耗和时间损失。此外,要从偏远的地方找到一个乘客带去市中心的某个地方可能不那么容易,因此在没有乘客的情况下开车回去可能会花销很大。一种解决方法是用车费和旅行距离之比的平均值对热图进行颜色编码。让我们考虑这两种方法:

出租车平均速度的分布

从上面的图中我们可以看到 95% 的出租车使用都不到 30 分钟就能到达目的地,尽管有些旅程可以花费 4 到 5 个小时。你能想象在纽约被困在出租车里超过 3 个小时吗?不管怎样,让我们开诚布公,考虑一下总共持续不到 3 小时的所有旅行:

上图显示,出行距离和弧线距离都有小幅增加,这意味着,平均而言,人们每年的出行都会稍微远一点。

左:行程距离和弧距离的比较;右:弧距<100 米的行程分布。

一周中每天和一天中每小时的车费与出行距离的平均比率

第一步是将数据转换为内存可映射文件格式,如 Apache Arrow、Apache Parquet 或 HDF5。将 CSV 数据转换为 HDF5 的示例可以在这里找到。一旦数据是内存可映射格式,用 Vaex 打开它是即时的(0.052 秒!),尽管磁盘上的数据超过 100GB:

为什么这么快?使用 Vaex 打开内存映射文件时,实际上没有数据读取。Vaex 只读取文件元数据,如磁盘上数据的位置、数据结构(行数、列数、列名和类型)、文件描述等。那么,如果我们想检查数据或与数据交互呢?打开一个数据集会生成一个标准数据框,检查它的速度是否也很快:

让我们把注意力转移到出租车旅行的成本上。从 describe 方法的输出中,我们可以看到 fare_amount、total_amount 和 tip_amount 列中有一些异常值。首先,这些列中的任何值都不应为负。与此相反,这些数字表明,一些幸运的司机几乎成了百万富翁,只有一辆出租车。让我们看看在一个相对合理的范围内,这些量的分布:

开出租车是一项相当灵活的工作。为了更好地利用这种灵活性,知道什么时候开车是最有益的。为了回答这个问题,我们制作一个图表,显示每天和一天中每小时的车费与出行距离的平均比率:

Vaex 是一个开源的数据框架库,它可以在与硬盘大小相同的表格数据集上进行可视化、探索、分析甚至机器学习。为此,Vaex 采用了一些概念,如内存映射、高效的核心外算法和延后计算。所有这些都被一个和 pandas 类似的 API 类绑定起来,任何人都可以马上开始使用它。

让我们做一个与前面的旅行距离相似的练习。由于这是一个连续变量,我们可以绘制行程的分布。参考最小和最大距离,我们用一个更合理的范围绘制一个柱状图。

出租车每年旅行的平均行程和弧距。

一旦我们以交互方式决定要关注纽约市的哪个区域,我们就可以简单地创建一个过滤数据框:

我们还有 11 亿多次旅行!通过这样大量的数据,可以获得一些关于出租车旅行的宝贵见解。

上面的数字是有道理的:最好的收入发生在高峰时段,特别是在一周工作日的中午。作为出租车司机,我们的一小部分收入是出租车公司的,所以我们可能会对哪一天的顾客给的小费最多感兴趣。因此,让我们生成一个类似的图,这次显示平均小费百分比:

上面的图很有趣。它告诉我们,乘客喜欢在早上 7 点到 10 点之间和在本周早些时候的晚上给出租车司机小费。如果你在凌晨 3 点或 4 点接乘客,不要指望会有太大的小费。结合上面两个地块的分析,早上 8 点到 10 点是上班的好时间:每个人每英里可以获得不错的车费和满意的小费。

根据上图,我们可以推断出出租车平均速度在 1 到 60 英里每小时的范围内,因此我们可以更新过滤后的 DataFrame:

多年来的黄色出租车公司

童增在接受中国青年报·中国青年网记者采访时表示:“国家公祭日的设立,表明中国人民反对当年日本发动的侵华战争、捍卫人类尊严、预防战争悲剧重演的和平理念和坚定立场。这也启发我在2014年南京大屠杀死难者国家公祭日来临前几天致信当时的木寺昌人大使转日本首相安倍晋三,要求日本政府就南京大屠杀战争罪行谢罪,并进行相应的赔偿。”2018年10月日本首相安倍晋三访华前夕,童增也致信给日本大使馆,要求日本首相安倍晋三访问中国期间前往南京大屠杀死难者纪念馆参观并道歉。

上面的代码块需要的内存为零,不需要时间执行!这是因为代码导致创建虚拟列。这些列仅包含数学表达式,并且仅在需要时计算,否则,虚拟列的行为与任何其他常规列一样。请注意,其他标准库在相同的操作中需要 10GB 的 RAM。

纽约 10 亿多次出租车出行持续时间的直方图

假设我们是一个未来的出租车司机,或出租车公司的经理,并有兴趣使用这个数据集来学习如何最大限度地提高我们的利润,降低我们的成本,或者只是改善我们的工作生活。

纽约出租车数据集的行程距离直方图

在本文中,我将向你展示一种新的方法:只要数据可以被存进笔记本电脑、台式机或服务器的硬盘上,那么这种方法可以让使用几乎任意大小的数据进行数据科学研究更快、更安全、更方便。