第一章 关于数据

数据这个词来源于拉丁文“datum”,意思是“已知的东西”。虽然“数据”这个术语从1500年代就被使用了,但是现代的用法是在1940年代和1950年代随着电子计算机开始输入,处理和输出数据时才出现的。这一章讨论数据的本质,并对没有计算机科学背景的初学者介绍一些关键概念。

万维网的发明者Tim Berners-Lee经常被引用的一句话是:“数据不是信息,信息不是知识,知识不是理解,理解不是智慧。”这有点像金字塔, 数据就是建筑下面用来做地基的原材料,而信息,知识,理解和智慧代表金字塔更高的层次。在某种意义下来说,数据科学家的主要目标是去帮助人们把数据转换成信息以及金字塔的更高层。但是在实现这个目标之前,我们应该清楚地知道数据究竟是什么。(注意到这本书把“数据”这个词处理成了名词复数——而在平常你可能经常听到人们把这个词作为单数。)如果你学过计算机科学或者数学,你可能会发现这一章的讨论有一点多余,所以跳过它们没问题。但如果你没有学过那些,可以接着读下面关于数据——数据科学家的工作中最基本的元素——的介绍。

关于数据,我们现在了解并且谈论的大部分内容来源于一个叫做Claude Shannon的美国数学家的工作。Shannon在第二次世界大战前后研究了很多关于数据和信息的数学和工程问题。Shannon说:“通信的最基本问题是如何在一点近似或完全的再现另一点的内容。”这句话概括了在本书中的至关重要的想法,即数据是从源传递到接收方的信息。想想最简单的,你可以用手机给别人发短信,甚至当面告知来传递信息。假如一个朋友问题你一个问题,你明天可不可以去他家吃晚饭。你可以回答去或者不去。你可以在电话里对她说去不去。但你可能信号不好,所以你的朋友可能听不到。你也可以发短信告诉他去不去,这样你就得指望她的电话是开着的,这样才能收到短信。你也可以当面告诉你的朋友,然后指望她没有把耳机声音开得很大以至于听不到你。在这三种情况中,你都有一个“比特”的信息想传达给你的朋友,去或者不去,而目标是减少她对于你明天去不去吃晚饭这件事的不确定性。假设信息没有混淆和丢失的传递过去了,那么你就成功的向她传递了一比特的信息。Claude Shannon发展了一些现在被称之为“信息论”的数学,用以量化从源到接收方传递的数据是如何通过提供信息而减少不确定性的。现在世界上大量的电脑网络设备和软件——还有互联网——都是在解决这个简单的工作:把信息的比特从源传输到目的地。

一旦我们熟悉“比特”作为信息的最基本单位——“是”或“不是”——之后,我们可以把比特组合到一起形成更复杂的结构。首先,让我们稍微转换一下标签。我们不用“不是”而改用0,再把“是”换成1。现在我们变成了一个数字,虽然只有一个数字但是有两个状态:0或者1(我们现在不允许任何更大的数字,比如3或者7)。这事是上是“比特”这个词的院士含义,也即“二进制数字”的简写。一个简单的二进制数字可以是0或1,但是这阻止不了在我们的信息中使用多个数字。看下表这个例子:

意义 第二个数字 第一个数字
0 0
也许 0 1
可能 1 0
一定 1 1

在这里我们开始使用2个二进制数字——2比特——建立了我们想传递给朋友关于晚饭的4个信息的“密码说明书”。如果我们很确定我们不参加,我们就给她发送信息 0 0。如果我们很确定参加,我们就给她发送 1 1。但我们还有两种可能性,“也许”由 0 1表示,“可能”由 1 0表示。我们可以比较一下用一个比特表示的“是或不是”和两个比特表示的4种信息。事实上,每次你加一个比特,你所能传递的信息个数就会加倍。所以3个比特就会有8个选择,4个比特就会有16个选择。如果有5个比特,你会有多少种选择呢?

当我们有8个比特——这提供了256种组合——我们终于得到了一个可以实际使用的大小了。8个比特通常被叫做一个“字节”——这个术语可能是衍生于比特这个词。(你可以在网上找一找“nybble”这个词!)一字节的组合个数足够给字母表中的所有字母编码,包括大写字母和小写字母。有一个旧标准叫做“ASCII”——美国信息交换标准码—— 它把8比特的模式对应到字母表中的字母,标点,和一些其他标记符号。比如比特模式0100 0001表示大写字母A,而下一个模式0100 0010表示大写字母B。你可以在网上找到ASCII表(比如http://www.asciitable.com/),那里有所有的组合。要注意编码可能实际上不是用二进制表示因为对人类来说,读很长的一串0和1是很麻烦的。所以你可能看到的是等价的16进制编码,8进制编码或者我们熟悉的10进制编码。虽然你可能还记得高中数学课上学过的进制转换,但是最好还是实际练习一下——尤其是二进制,十六进制和十进制的转换。你也可能喜欢可汗学院上的Vi Hart的“二进制手舞”视频(在http://www.khanacademy.org上搜索,或者点击本章末尾给出的链接)。我们这本书的大多数工作是在十进制下进行的,但是关于数据的更复杂的工作通常需要理解16进制并要知道一个16进制数字,比如0xA3,是怎么转换成一个比特模式。搜索“二进制转换教程”,你会找到很多有用的网站。

把字节组合成更大的结构

既然我们知道了字节是由一些比特(通常是8个)构成的,它可以用来存储和传输事物比如字母和标点符号,用这种想法我们可以开始构建更大的东西。首先容易看出,我们可以把字节组合成列表来构造一“串”字母,这就是经常被谈论的“字符串”。如果我们有一些文本,比如“this is a piece of text”,我们可以用一些字节表示它:

0111010001101000011010010111001100100000011010010111001100100000011000010010000001110000011010010110010101100011011001010010000001101111011001100010000001110100011001010111100001110100

没人想看这样的东西,更别说手动编码和解码了,幸运的是,我们现在用的电脑和软件可以自动转换和存储。比如,当我们让开源数据语言“R”去存储"this is a piece of text"时,如:myText<- "this is a piece of text"

我们知道在电脑内部有很长一串0和1用来表示我们刚才存储的文本。顺便提一下,为了之后可以再次调用这段文本,我们可以为它建立一个存储标签(上面的“myText”)。每次我们想看看这段文本或者想用它干些其他事,我们可以使用标签“myText”去打开电脑中我们存放代表我们的文本那一长串二进制数字的那一块内存。由小于号(“<”)和短横线(“-”)组成的向左指的箭头在R中的意思是把右边的东西(引文)赋值给左边(我们标记为“myText”的存储区域)。一些人把这个叫做赋值箭头,在一些计算机语言中,它用来告诉读或者写代码的人信息的流向。

从计算机的角度来看,存储,记忆和操作数字要比文本容易的多。我们记得一个8比特的字节可以容纳256种组合,所以只使用这么小的一个空间我们就可以存储数字0到255(当然,我们也可以存1到256,但是计算机中的多数计数是从0而不是1开始的)。但是255也不够我们使用。我们不能仅用255以下计数多数城市中的房子数量也不能计算一个大停车场里的车辆个数。如果我们把两个字节合在一起构成16比特,我们就可以计数从0到65535,但这对于如今世界上的一些大数字来说还是不够的(比如,仅仅美国就有超过2亿辆汽车)。多数时候,如果我们想自由的表示一个整数(没有小数的数字),我们把4个字节放在一起。4个字节放在一起是32比特,这允许我们最大存储到4294967295。

当我们开始存储负数或者有小数的数的时候事情就有些复杂了。如果你对此好奇,搜索“补码”可以知道一个带符号的数字是怎么存储的,搜索“浮点”可以知道带小数的数字是如何存储的。对于我们这本书而言,主要应该知道文本的存储方式和数字是不同的,而整数和浮点的存储方式也是不同的。之后我们会发现有时会要求我们把这两种表示法相互转化,所以知道一个数是如何表示的总是很重要的一件事。

到目前为止我们主要了解了如何在同一时间存储一个东西,比如一个数字或者一个字母,但是当我们处理数据时,我们经常需要同时存储一组相关的东西。最简单的方法就是用元素的列表存储,在列表中的元素的存储方式都相同。比如,我们可以有整数的列表,列表中的每一个元素是你的一个家人的年龄。列表可能看起来是这样的:43,42,12,8,5。前两个数字是父母的年龄,后三个数字是孩子的年龄。自然的,在电脑中每个数字都是用二进制存储,但幸运的是我们不需要用二进制打出它们,我们也不需要阅读二进制。因为没有小数,它们是纯整数,一个32比特的整数(4字节)足够存储它们了。这个列表包含的元素具有相同的“类型”。开源数据编程语言“R”中的一个列表中的所有元素的类型都是“向量”。我们在R中可以通过枚举数字来容易的建立一个向量,在一个括号里用逗号分隔:c(43,42,12,8,5)

括号前面的字母“c”代表联结。这有些晦涩,但是适当的练习之后就很容易掌握。我们也可以用类似之前我们学到的方法来给我们的向量用一个名字存储(记住一个向量是一个具有相同类型元素的列表):myFamilyAges <- c(43,42,12,8,5)

我们刚刚建立了我们的第一个“数据集”。当然,它很小,只有5个元素,但用它可以展示数据的一些核心概念。下面是一个回顾:

  • 在计算机的内部,所有的数据都以二进制存储。一个二进制数字,或者说比特,是我们可以从一个地方传输到另一个地方的最小的数据块。
  • 虽然所有的数据都用二进制存储,但是电脑和软件可以帮助我们用更方便的形式呈现数据。三种重要的表现方式是:“字符”用来表示文本,“整数”用来表示小数点后面没有小数的数字,“浮点”用来表示有小数的数。在我们的小数据中的数的列表是整数。
  • 数字和文本可以放入列表,开源语言“R"中叫做向量。一个向量具有长度,意思是它里面元素的个数,还有一个“类型”代表数据在向量中的存储类型。我们刚才使用的向量的长度是5,类型是整数。
  • 为了保存我们在哪里存储了数据,多数电脑语言,包括R,允许我们给一段电脑内存一个标签。我们给那个5个元素的向量一个名字“myFamiliAges”。一些人可能把具有名字的列表叫做“变量”,因为它的值可以变化,这取决于你在使用列表中的哪个成员。
  • 如果我们把一个或多个变量集合起来变成一个有意义的群体,我们把它叫做“数据集”。通常来说,数据集只有一个变量是没有什么意义的,所以通常我们至少需要两个变量。但是,严格来说,即使是我们的很简单的“myFamilyAges”也算作是一个数据集,虽然是一个很小的数据集。

在这本书的后面我们会安装并运行开源“R”数据语言,学习如何创建数据集,在这些数据集中整理信息,对数据集进行简单的计算和变换。

章节挑战

理解“布尔逻辑”的意义和“且”,“或”,“非”和“异或”的规则。你学完后,不要看,在一张纸上写下所有代表这些规则的二进制操作。

资源

下一节:数据科学与其他领域诸如数学或统计学完全不同。数据科学是一种实用的活动,数据科学家提供需求,并且帮助数据使用者解决问题。在解决一个问题之前,首先需要明确该问题,而这个过程却并不总是看起来那么明显。在这一章中,我们将要讨论如何识别数据问题。