第7章 机器学习:关于机器学习的深度学习

字数:15559

为了创造一个更加公正的技术世界,我们在创造技术的时候,需要接受更多不同的声音。要做到这一点,我们需要采用传统的解决方案,比如降低准入门槛,解决“管漏现象”问题(管漏问题会使处于职业生涯中期的专业人士退出或停滞不前)。我认为我们还需要增加一个非传统的解决方案——在谈论有关数字化的所有事情时,我们需要有更多的差异。说起来容易,做起来难。有一幅漫画可以说明谈论计算机科学究竟有多难,那是兰德尔·芒罗(Randall Munro)的XKCD漫画作品。画中,一名女子坐在电脑旁,一名男子站在她身后。

“用户拍照时,App后台应该检测一下他们是否在国家公园内。”男子说。

“没问题,GIS(地理信息系统)很容易查到,”女子说,“给我几个小时。”

“另外,再检测用户拍的是不是鸟。”男子又说。

“没问题,我需要一个研究团队,给我五年时间。”女子说。

标题写道:“在计算机科学中,很难说清楚‘简单’和‘几乎不可能’的区别。”[1]

既然很难解释计算机为何无法识别图像中的鸟或区分鹦鹉和牛油果酱,我们需要更多人(可能是更多数据记者?)使用平白的语言来解释复杂的科技问题,以揭开人工智能世界中更多的神秘面纱。

谈论计算太难了,这导致了很多误解。本书中反复提出的观点是,计算机在某些方面表现得非常优秀,而在另外一些方面表现得非常糟糕;而当人们误判计算机在执行任务时的参与程度时,社会问题就会产生。有一个展示了对人类来说非常简单,对计算机来说却非常复杂的典型例子,那就是在一个地板上满是玩具的房间里行走。蹒跚学步的孩子一般可以在不踩到玩具的情况下在房间内行走(当然,她可能会偏不这样干),但机器人做不到。要让机器人在满是玩具的地板上行走,我们必须编写程序记录下关于这些玩具以及它们精确尺寸的所有信息,然后让机器人在其中计算出一条路线。一旦有玩具移动,机器人就要更新数据库文档。我们在第8章中要讨论到的无人驾驶汽车原理,就跟这个玩具房中的假想机器人一样:它们持续不断地更新预编好的世界地图。

使用机器人也有一些可预见的缺陷,那些拥有扫地机器人和宠物的人已经率先发现了。如果宠物在地板上留下了令人作呕的东西,扫地机器人会把它弄得满屋子都是。“老实说,这经常发生。”制作Roomba扫地机器人的iRobot公司发言人于2016年8月对《卫报》说,“我们通常会告诉用户,如果你知道你的狗可能会把家里弄得一团糟,那就别安排你的扫地机在无人看管的情况下工作。家里有小动物,什么事情都有可能发生。”[2]

我可以使用委婉的语言来谈论宠物所做的令人作呕的事情,因为我们可以在不使用精确词语的情况下,使用日常语言来表达事物。如果我说我的狗很可爱,同时又很恶心,你会明白我的意思。你的大脑可以同时吸收这两个互斥的说法,然后猜到我所说的“恶心”是什么意思。在数学语言中,没有这种委婉语。在数学中,一切语言都是高度精确的。计算文化中存在的沟通问题,就有一部分是由日常语言的不精确性和数学语言的精确性所致。举个例子,编程中有一个概念叫“变量”。编写诸如“X=2”之类的内容,就可以给变量赋值,之后你就可以常规地使用X这个变量了。有两种变量:一种是会变的,叫“变量”;一种是不变的,叫“常量”。这对编程者来说是很正常的——一个变量可以是一个常量。但对不是程序员的人来讲,这就不对了——常量是不会变的,一个会变的量怎么可能是一个不会变的量呢?这种表述让人一头雾水。

变量和常量的命名问题并不新鲜。语言一直随着科学的发展而发展。在生物学中,“cell”(细胞)的得名是由于罗伯特·胡克在1665年发现细胞的时候,想起了修道院中僧侣们居住的单人房(cell)的墙壁。随着技术的迅猛发展,今天的命名问题尤其严重。我们正在以惊人的速度采用新的计算概念和硬件,而人们还在根据已存在的概念或工件为新出现的事物发明名称。

虽然计算机科学家和数学家往往在计算机科学和数学方面很出色,但他们这个群体对语言的细微差别往往不太敏感。如果需要给某物命名,他们不会执着于选一个具有理想的内涵和契合的拉丁词根或诸如此类的完美名称。他们只会随便选一个名字,这个名字通常跟他们喜欢的某种东西有关。Python编程语言就是以喜剧团体Monty Python的名字命名的(Monty Python是计算机科学界的净版喜剧,正如《星球大战》是计算机界的净版叙事文本一样)。Web开发框架Django,是以其发明者最喜欢的爵士吉他手金格·莱恩哈特(Django Reinhardt)的名字命名的。Java语言源自一种咖啡的名字。JavaScript与Java无关,与Java差不多同时发明,并且(不幸地)也以咖啡的名称命名。

随着“机器学习”这个术语从计算机科学界进入大多数人的视野,语言上的混淆引发了许多问题。机器学习隐含着计算机有自主权的意味,并且由于它能“学习”,因此具有某种程度的感知能力,而“学习”这个词通常适用于诸如人类这种有感知能力的生命体(或有部分感知能力的动物)。然而,计算机科学家知道,机器“学习”更偏向于表达这样一种隐喻:它意味着机器可以在它已预编程好的、常规的、自动化的任务中得到改进。尽管“学习”有某种隐含的意味,但不代表机器就能获得知识、智慧或者自主选择权。这种类型的语言混淆就是许多人误解计算机的根源。[3]

想象力也让事情变得更加复杂。如何定义人工智能,取决于你对未来的信念。马文·明斯基的学生雷·库兹韦尔(曾因发明一种能发出三角钢琴声的电子音乐合成器而闻名)是奇点理论的支持者,这个理论主张2045年将实现人与机器的融合。奇点在科幻小说中占非常重要的地位。我曾在一个未来学家的峰会上受访,采访者向我提出了一个关于回形针末日理论的问题:“假如你发明了一台生产回形针的机器,将它的任务设定为生产回形针,又教会它制作其他东西,之后它生产出一大堆其他机器,最后所有机器接管了人类世界,会发生什么?”采访者问我:“这就是奇点吗?你会为此担心吗?”想一想还挺有意思的,但这并不合理。你只要把回形针机器的电源拔下来,问题就解决了。而且,这纯粹是一种假设的情况,不是真的。

心理学家斯蒂芬·平克曾在美国电子电机工程师协会会刊《IEEE综览》上发表过一篇关于奇点理论的特刊文章,他写道:“我们没有任何理由相信奇点即将到来。你可以想象未来的样子,但你的想象不能佐证你对未来可能性的预测。想想穹顶城市、喷气通勤背包、水下城市、一英里高的建筑和核动力汽车,这些都是我年幼的时候未来学家们对未来的幻想。它们通通没有实现。纯粹的处理能力可不是什么魔法粉尘,可以神奇地解决我们的所有问题。”[4]

Facebook的扬·莱库也对奇点存疑。他在接受《IEEE综览》采访时表示:“有些人会大肆宣传奇点,比如雷·库兹韦尔,这也是意料中的事。他是一个未来主义者。在对未来的看法上,他喜欢这种实证主义观点。他以这种方式卖了很多书。但据我所知,他对人工智能科学没有任何贡献。他售卖的产品基于技术,有些产品还颇有创意,但在概念上并不新鲜。当然,他也没有发表过任何关于如何在人工智能方面取得进展的论文。”[5]但凡是理智的聪明人,对未来会发生什么是无法达成共识的——部分原因是没有人能看到未来。

我将通过给“机器学习”下定义,并使用一个在数据集上执行机器学习的示例,来尝试向读者说清楚情况。我会以几种不同的方式来解释机器学习,并且演示一些代码,会涉及技术知识。如果技术部分把你搞糊涂了,没关系——你可以先浏览,以后再回头看。

经历了多年人们所谓的“人工智能寒冬”,人工智能在2017年终于大热。21世纪前10年,在主流领域,人们大多忽略了人工智能。在技术界,互联网先流行起来,然后是移动设备,这些都是人们集体想象的焦点。到了21世纪前10年中期,人们开始谈论机器学习。突然间,人工智能又火了。人工智能创业公司一个接一个地创立,被收购。IBM的机器人沃森在《危险边缘》(Jeopardy!)游戏中击败了一名人类选手,一种算法在围棋比赛中击败了人类棋手。即使只看名字,“机器学习”这个名字也很酷。机器能够学习!我们所期望的东西实现了!

起初,我想相信是某个天才已经找到了让机器思考的方法。但仔细观察之后,我才发现不是这么回事。原来,科学家们只是重新定义了“机器学习”这个术语,以便用它来表述他们所从事的工作。他们过于频繁地使用这个词,以至于它的意义发生了改变。

语言就是这样的,它是流动的。英文中的“literally”(“真的”,指字面意义)就是一个很好的例子,它曾经是“figuratively”(“好像”,具有比喻意义)的反义词。20世纪90年代,如果你说“我吃了那个魔鬼辣椒酱之后,我的嘴真的(literally)着火了”,这表示你的嘴上真的有火焰,而你正在使用这个从三级烧伤恢复过来的嘴巴跟我说话。然而,到了21世纪,一大批人开始使用“literally”代替“figuratively”,来表示比喻和强调。“我要是再听一遍约翰·梅尔那首歌,我真的(literally)要杀人了!”这会被理解为“我不想再听一次约翰·梅尔那首歌了”,而不是关于谋杀或伤害的陈述。

1959年,“机器学习”这个术语被《牛津英语词典》收录。在2000年出版的第三版中,《牛津英语词典》开始将“机器学习”视作短语,定义如下:

机器学习(machine learning)名词(计),计算机从经验中学习的能力,是一种基于新采集的信息改进算法的能力。

1959年 《IBM公司研究与开发杂志》(IBM Journal)卷3,211/1我们的计算机具有足够的数据处理能力和计算速度,可以好好利用机器学习技术。

1990年 《新科学家》(New Scientist)9月8日刊,78/1斯坦福大学的道格·莱纳特(Doug Lenat)开发Eurisko程序(第二代机器学习系统程序)时,他还以为他创造出了真正的人工智能。[6]

这个定义没有错,但它并没有完全表达出当代计算机科学家使用这个术语的方式。《牛津计算机科学词典》中对其有更加全面的定义:

机器学习

人工智能的一个分支,涉及从经验中学习的程序结构。“学习”可以有多种形式,包括实例学习、类比学习、概念自主学习和发现学习,等等。

在增量学习模式下,算法会随新数据的到来而持续改进。而单样本学习或批量学习将训练阶段和应用阶段区分开来。当输入的训练数据被明确进行了类标签标记时,那就是监督学习。

大多数算法学习模式凭借系统从大量密切相关的数据中概而括之得出高效且有效的表述,从而提炼出通用性。[7]

这个定义更加贴切,但仍然不完全正确。Scikit-learn是一个非常受欢迎的Python机器学习库,它的官方文档中对“机器学习”有一个不同的定义:“机器学习是学习一个数据集的一些属性,并将它们应用到新数据上。因此,在机器学习中,评估一个算法的常见做法是将数据分成两组:一组为训练集,用以学习数据属性;另一组为测试集,用以检测数据属性。”[8]

一个术语在不同来源之间存在这么多分歧是很少见的,比如“狗”的定义在各处就高度一致。但是,“机器学习”实在太新了,共识太少,所以语言学的定义没能跟上现实也就不足为奇了。

汤姆·米切尔是卡内基梅隆大学计算机科学学院机器学习系弗雷德金[9]教授,他在论文《机器学习中的规则》(“The Discipline of Machine Learning”)中给机器学习下了一个很好的定义。他写道:“对于某类指定任务T、性能指标P和经验E,如果一台机器在T上以P衡量的性能随着经验E而不断自我完善,那么我们称这台机器在从经验E学习。根据我们对T、P、E的具体设定,学习任务也可以这样命名:数据挖掘、自主发现、数据库更新、示例编程,等等。”[10]我认为这是一个很好的定义,因为米切尔用了非常精确的语言来定义“学习”。所谓机器“学习”,并不意味着机器有一个由金属制成的大脑,而是指机器根据人类定义的衡量指标,在执行单个特定任务时更加准确。

这种学习并不等同于智力。程序员及顾问乔治·V.内维尔——尼尔在《美国计算机学会通讯》(Communications of the ACM)上写道:

人类跟计算机进行国际象棋比赛已经有将近50年历史了,但这是否意味着有哪一台计算机拥有智力?不,它们都没有。原因有两个。首先,国际象棋不是对智力进行的测试,它只测试一种技能——下象棋的技能。如果我可以击败一名特级大师级别的棋手,但当你让我把桌上的盐递给你,我却做不到,我能算拥有高智力吗?第二,认为象棋代表智力其实基于一种错误的文化前提——认为优秀的棋手头脑聪明,比周围的人更有天赋。没错,许多聪明的人擅长国际象棋,但国际象棋或任何单一的技能并不代表智力。[11]

机器学习一般有三种类型:监督学习、无监督学习和强化学习。以下是加州大学伯克利分校教授斯图尔特·罗素和谷歌研究主管彼得·诺维格撰写的一本被广泛使用的教科书《人工智能:一种现代的方法》中对这三种类型的定义:

监督学习:计算机被“教师”给定一组示例的输入数据和所需的输出数据,目的是通过将输入数据映射到输出数据,习得一般规则。

无监督学习:给学习算法输入的数据不带标签,使其自行在数据中发现结构。无监督学习的目的可以是无监督学习本身(发现数据中的隐藏模式)或者通过无监督学习达到其他目的(特征学习)。

强化学习:计算机程序在一个动态环境中执行某个动作,并与环境发生交互(如驾驶车辆,或与对手玩游戏)。程序会在试探它的问题空间时收到环境返回的奖励和惩罚方面的反馈。[12]

监督学习是其中最直接的一种方法。机器得到的是训练数据和带标签的输出数据。这相当于我们告诉了机器我们想要找到什么,然后对模型进行微调,让它能够预测到我们已知的事情。

这三种机器学习都依赖于训练数据。训练数据是用于训练和调整机器学习模型的已知数据集。假设我有一份训练数据,是一个大约包含10万个信用卡账户数据的数据库。信用卡公司拥有的客户数据都有什么,你能想到的,这个数据库都有:姓名、年龄、地址、信用评分、利率、账户余额、账户联名者姓名、费用清单、支出金额与日期的记录,等等。假设我们的目的是让机器学习模型能够准确预测可能逾期还款的账户。我们想找出这些人,因为只要逾期还款,账户的利率就会提高,这意味着信用卡公司会获得更多利息。我们手上有这10万个人的逾期还款记录作为训练集。我们可以针对这个数据集运行一个机器学习算法,来预测我们已知的内容。算法会以此形成一个模型,我们可以在测试数据集上使用这个模型。测试集与训练集一样,不同的是测试集没有一个实际逾期还款的账户清单。如果检测可行,之后我们就可以在真实的账户数据上部署这个模型了。

现在已有几种不同的机器学习算法可被应用于已知数据集,比如随机森林、决策树、最近邻、朴素贝叶斯或隐藏式马尔可夫等。记住,算法是计算机执行任务需要遵循的一系列步骤或过程。在机器学习中,算法与变量相结合才可以创建数学模型。凯西·奥尼尔的《数学杀伤性武器》(Weapons of Math Destruction)对模型做了精彩的解读。奥尼尔解释说,我们一直在无意识地给事物建立模型。当我要考虑晚餐做什么时,我会建立一个模型:我的冰箱里有什么食材,我可以用这些食材做什么菜,当晚有谁要来吃饭(通常是我丈夫、我儿子和我),他们有什么饮食偏好。我评估了各种菜,回顾以前做这些菜时的情景——谁经常吃哪种菜、哪种食材上了那张时时更新的避食清单:腰果、冷冻蔬菜、椰子、动物内脏。根据拥有的食材和人们的喜好决定要做的菜,我是在为这一系列特征优化我的烹饪选择。建立一个数学模型,意味着使用数学术语对数据特征和选择进行格式化。[13]

假设我要做一个机器学习模型,首先要抓取数据集。网上的资源库收录了很多有意思的数据集,可用于机器学习实践。它们包括面部表情数据集、宠物数据集或YouTube视频数据集,还有已倒闭的公司(如安然公司)的工作人员发送的电子邮件数据集、20世纪90年代新闻讨论组(如Usenet)的对话数据集、倒闭的社交网络公司(如Friendster)的朋友关系数据集、人们使用流媒体服务(如Netflix)观看的电影数据集、人们用不同的口音表达常用短语的数据集以及人们杂乱的笔迹数据集等等。这些数据集来自那些活跃的企业、网站、大学研究人员、志愿者以及倒闭的公司。这为数不多的标志性数据集被发布到网络上,成为当代所有人工智能的基石。你甚至可以在里面找到自己的数据。我有个朋友甚至曾在一个行为科学档案库里找到了自己蹒跚学步时的视频。她的母亲在她小时候带她参加过一个亲子行为研究项目,研究者仍留有那些视频,而且仍用它来分析当下的世界。

现在,让我们来做一次经典的实践练习:使用机器学习来预测谁在“泰坦尼克号”失事事件中幸存下来。想一下,“泰坦尼克号”撞上冰山后发生了什么事?你的脑海里是不是浮现了莱昂纳多·迪卡普里奥和凯特·温斯莱特在甲板上穿行逃生的画面?那不是真的。但如果你跟我一样看了很多遍这部电影,它可能会歪曲你对事件的回忆。这部电影,你可能至少看过一遍。电影《泰坦尼克号》在美国的票房是6.59亿美元,海外票房高达15亿美元,是1997年全球票房最高的电影,也是有史以来全球第二卖座的电影(《泰坦尼克号》导演詹姆斯·卡梅隆执导的另一部大片《阿凡达》的票房位居全球第一)。《泰坦尼克号》在院线上映了将近一年,部分是由于年轻人的推动,他们到电影院看了一遍又一遍。[14]《泰坦尼克号》已经成为我们集体记忆的一部分,就像真实的“泰坦尼克号”失事灾难一样。我们的大脑总会把真实的事件和虚构的写实小说混淆在一起。这很不幸,但完全正常。这种混淆使得我们对风险的理解更加复杂。

我们基于启发法或非正式规则得出有关风险的结论。启发法产生的知识被当事人容易回想起的故事和情感共鸣的经历影响。比如,《纽约时报》专栏作家查尔斯·布洛小的时候,曾被一条恶狗袭击,那条狗差点撕裂他的脸。他在回忆录中写道,当他成年后,他仍对陌生的狗保持警惕。[15]这是完全合理的。在幼年的时候被大型动物袭击,创伤是极大的。他在余生中再次看到狗时,第一件事肯定是会想到小时候被袭击的情景。阅读这本回忆录时,我与这个小男孩产生了共鸣。当他感到害怕时,我也感到害怕。读了布洛这本书的第二天,我在家附近的公园看到一名男子在遛狗,但没有用牵引绳,我立刻想到了布洛。我想,其他怕狗的人大概会因这条狗没有拴牵引绳而感到不舒服。我不禁想,这条狗会不会突然发狂,如果它发狂,会发生什么。这个故事影响了我对风险的看法。就是出于这种想法,人们才会在多次看了《法律与秩序:特殊受害者》之后,随身带着胡椒喷雾剂,也才会在看了恐怖电影之后,开车要先检查后座上有没有恶心的东西。这种情况,专业术语叫作“可得性启发法”。[16]首先浮现在脑海里的情景通常是我们认为最重要或最常发生的故事。

大概是因为“泰坦尼克号”的灾难深深刻在了人们的集体记忆中,所以它常被用于机器学习的教学。具体说来是这样的:用“泰坦尼克号”上的乘客名单,教学生如何使用数据进行预测。它很适合作为课堂练习,因为几乎所有学生都看过《泰坦尼克号》,或至少知道这场灾难。这对教师非常有价值,因为他们不需要占用课堂时间来回顾历史背景,可以单刀直入,直接讲到预测的部分。

接下来,跟着我玩一遍其中好玩的部分吧。我认为亲眼看一遍机器学习的全过程是非常重要的。如果你有兴趣自己动手做机器学习练习,有很多网站有相关的教程。我们将浏览一个名为DataCamp的网站,这是一个名为Kaggle的站点为参加数据科学竞赛的网友推荐的入门教程网站。[17]Kaggle站点属于谷歌母公司Alphabet旗下,人们在这个网站上竞相分析数据集,以获得高分。数据科学家们会在该网站上组队比赛、磨炼技能,或与别人实操协作。这个网站对于向学生讲授数据科学或查找数据集也很有用。

下面,我们将在DataCamp上做一个“泰坦尼克号”的机器学习教程。我们会使用Python和几个常用的Python库,比如pandas、scikit-learn和numpy。所谓“库”,就是放在互联网某个地方的一小堆函数。将库导入,就是将这些函数提供给我们正在编写的程序使用。你可以借助实体图书馆[18]来理解库的概念。我是纽约市立图书馆的会员。每次我要在一个地方待一周以上,无论是工作还是度假,我都会去当地的图书馆办一张借书证。有了这张借书证,当地图书馆的所有图书和资源都可以为我所用。在我成为某地图书馆会员的那段时间,我既可以使用我的核心资源——纽约市立图书馆的资源,又可以使用一份独特资源——当地图书馆的资源。在Python程序中,我们首先有一大堆Python内置函数,这就好比是纽约市立图书馆的资源。把新库导入程序,则像是办了一张当地图书馆的借书证。例如,我们的程序可以使用核心Python库里的所有好东西,外加研究者和开源开发者们编写的实用函数。就是这些人,编写并发布了scikit-learn库。

我们将要使用的另一个库是pandas。pandas有一个名为DataFrame(数据框)的容器,用来“保存”一组数据。与面向对象的编程一样,这种类型的容器也被称为“对象”。它是编程中的一个通用术语,在现实世界中也一样。在编程中,“对象”就像一个包裹,里面包含了一小部分数据、变量和代码。“对象”这一标签让我们能更好地理解它,我们需要将这种抽象的比特包概念化成某种东西,以便对它做进一步思考和讨论。

首先,我们要将数据分成两组:训练数据和测试数据。我们要开发一个模型,用训练数据来训练它,然后让它在测试数据上运行。还记得广义人工智能和狭义人工智能的说法吗?这就是狭义人工智能。现在,我们输入以下内容:

import pandas as pd

import numpy as np

from sklearn import tree, preprocessing

我们刚刚导入了几个用于分析的库,给它们分别起了别名。Pandas是“pd”,numpy是“np”。现在,我们可以使用pandas库和numpy库中的所有函数了。我们可以选择导入它们的全部函数,也可以只导入一部分。我们从scikit-learn库中只导入两个函数,一个是tree,另一个是preprocessing。

接下来,我们从一个网上找来的CSV文件中导入数据。具体而言,这个CSV文件位于亚马逊网络服务(AWS)的服务器上。我们可以看出这个文件的位置,因为它的基本URL地址(http://后面内容的第一部分)是s3.amazonaws.com。CSV文件的全称是comma separated values(逗号分隔值),它是一种结构化数据文件,每一列数据用半角逗号分隔。我们将从亚马逊网络服务导入两个不同的“泰坦尼克号”数据文件。一个是训练数据集,另一个是测试数据集。这两个数据集均为CSV格式。我们来导入数据:

train_url=

"http://s3.amazonaws.com/assets.datacamp.com/course/Kaggle/

train.csv"

train=pd.read_csv(train_url)

test_url="http://s3.amazonaws.com/assets.datacamp.com/

course/Kaggle/test.csv"

test=pd.read_csv(test_url)

pd.read_csv()的意思是“请调用read_csv()函数,它位于pd(即pandas)库里”。从技术层面讲,我们创建了一个DataFrame对象,并且调用了它的一个内置方法。不管怎么说,现在数据已经导入了。现在将数据导入两个变量:训练和测试。我们将使用训练变量中的数据来创建模型,然后使用测试变量中的数据来测试模型的准确性。

我们来看看训练数据集的开头(或者头几行)是什么。

print(train.head())

这些数据看起来有12列。这些数据列被标记为:PassengerId、Survived、Pclass、Name、Sex、Age、SibSp、Parch、Ticket、Fare、Cabin和Embarked。这些列标题是什么意思?

要回答这个问题,我们需要一个数据字典。绝大多数数据集都带有数据字典,它的数据字典这样解释道:

Pclass:船舱等级(1为一等,2为二等,3为三等)

Survived:是否生还(0为否,1为是)

Name:姓名

Sex:性别

Age:年龄(按年计,不足1的部分表述成小数,推测年龄记作xx .5)

Sibsp:同船的兄弟/姐妹/配偶数量

Parch:同船的父母/子女数量

Ticket:票号

Fare:票价(1970年以前发行的英镑)

Cabin:客舱号

Embarked:登船港口(C为瑟堡,Q为昆斯敦,S为南安普敦)

大多数列都有数据,也有一些列没有数据。看看PassengerId 1,Mr. Owen Harris Braund这个数据的cabin值是NaN。NaN表示“不是数字”(not a number),它和0不一样。0是数字,NaN表示这个变量没有值。这点区别可能对日常生活来说一点也不重要,但在计算机科学中是至关重要的。别忘了,数学语言是精确的。比如,NULL表示空集,它跟NaN或0也不一样。

我们来看看测试数据集的头几行是什么。

print(test.head())

你可以看到,测试集的数据类型跟训练集几乎一模一样,只是没有了“survived”那一列。太棒了!我们的目标是在测试集里面创建一个“survived”列,预测出每位乘客的幸存状态。(当然,有些人已经知道测试数据集中哪些乘客得以幸存,但是,如果测试数据集里有答案,这就算不上什么教程了。)

接下来,我们将对训练数据做一次基本概括统计,以便更好地了解它。我们数据记者将这个过程叫作“采访数据”。我们就像采访人类那样对数据进行采访。人有姓名、年龄、背景;数据集有大小,有许多列数据。向一列数据询问它的平均值,有点像要求一个人写出他的姓氏。

我们可以通过运行describe函数来了解我们的数据。这个函数能够汇编一些基本的汇总统计数据,并将它们放入一个简便的表格中。

train.describe()

训练数据集有891条记录,其中只有714条记录显示了乘客的年龄。在这些有记录的数据中,乘客的平均年龄是29.699118岁。一般人会说平均年龄是30岁。

其中有一些统计数据需要解释。Survived变量的最小值是0,最大值是1。换句话说,这是一个布尔值。一个人要么幸存(1),要么没有幸存(0)。我们可以计算出它的平均值,结果是0.38。同样,我们也可以计算出Pclass的平均值。船票分一等、二等、三等,它的平均值是2.308,不代表有人买了2.308等的船票。

现在,我们对这份数据已经有了一点了解,是时候做一些分析了。我们来看看乘客的数量。我们可以使用value_counts函数来统计。这个函数可以统计出每一列数据中不同的数据分别有多少个值。换句话说:每一个等级的船舱中分别有多少名乘客?我们来看看:

train["Pclass"].value_counts()

1 216

2 184

3 491

Name: Pclass, dtype: int64

训练数据显示,有491名乘客持三等票,184名乘客持二等票,216名乘客持一等票。

我们看看幸存者的数量:

train["Survived"].value_counts()

0 549

1 342

Name: Survived, dtype: int64

训练数据显示,有549人遇难,342人幸存。我们来看看归一化处理后的数字:

print(train["Survived"].value_counts(normalize=True))

0 0.616162

1 0.383838

Name: Survived, dtype: float64

遇难乘客有62%,幸存乘客有38%。换句话说,大部分人死于这场灾难。如果要预测一名随机乘客是否幸存,预测结果可能是,他未能幸存。

至此,可以随时结束这次练习,因为我们已经得到了一个可以做出合理预测的结论。不过,我们可以做得更好,所以不妨继续吧。还有没有什么因素可以帮我们改进预测机制呢?除了Survived,我们的数据集中还有很多列其他的数据:Pclass、Name、Sex、Age、SibSp、Parch、Ticket、Fare、Cabin和Embarked。

Pclass代表乘客的社会经济阶层,这可能是一个有用的预测指标。我们可以猜测,一等票乘客比三等票乘客优先登救生艇。性别也是一个可供合理推算的预测指标。我们知道,“妇女和儿童优先”是海难逃生的常用原则。这条原则可以追溯到1852年英国皇家海军舰艇“伯肯黑德”在南非海岸搁浅的事故。这不是一条放之四海而皆准的原则,但它的有效频次用于社会分析是足够的。

现在,我们来做一些比较,看看能不能找到能用来做预测的变量。

#幸存乘客vs遇难乘客

print(train["Survived"].value_counts())

0 549

1 342

Name: Survived, dtype: int64

#表示为占比

print(train["Survived"].value_counts(normalize=True))

0 0.616162

1 0.383838

Name: Survived, dtype: float64

#幸存男性乘客vs遇难男性乘客

print(train["Survived"][train["Sex"]=='male'].value_counts())

0 468

1 109

Name: Survived, dtype: int64

#幸存女性乘客vs遇难女性乘客

print(train["Survived"][train["Sex"]== 'female'].value_counts())

1 233

0 81

Name: Survived, dtype: int64

#对男性幸存者做归一化处理

print(train["Survived"][train["Sex"]== 'male'].value_counts (normalize=True))

0 0.811092

1 0.188908

Name: Survived, dtype: float64

#对女性幸存者做归一化处理

print(train["Survived"][train["Sex"]== 'female'].value_counts

(normalize=True))

1 0.742038

0 0.257962

Name: Survived, dtype: float64

统计显示,女性乘客中有74%幸存,男性乘客中只有18%幸存。因此,我们可能会对随机乘客的预测结果做调整:如果是女性乘客,我们预测她幸存了;如果是男性乘客,我们预测他没有幸存。

还记得前面我们说到的练习目标吗?在测试集里面创建一个“survived”列,预测出每位乘客的幸存状态。至此,我们可以创建一个survived列,给这74%的女性乘客标记为1(表示“没错,这名乘客幸存了”),给剩下的女性乘客标记为0(表示“不,这名乘客没有幸存”);我们可以给那18%的男性乘客标记为1,给剩下的男性乘客标记为0。

但我们不会这么做,因为这样就意味着算法将仅根据性别来随机分配预测结果。我们知道,数据集中还有其他因素会影响预测结果(如果你想详细了解这一点是如何确定的,建议你看看DataCamp教程或类似的在线教程)。三等舱的女性乘客的情况是什么样的?一等舱的女性乘客呢?与配偶一起乘船的女性情况如何?携带儿童的女性乘客呢?手动计算这些数据是非常烦琐的,我们可以根据已知的因素训练一个模型,来为我们做预测。

我们将使用一种特殊的算法——决策树来构建这个模型。在机器学习中,有很多标准的算法,比如决策树、随机森林、人工神经网络、朴素贝叶斯、k——最近邻和深度学习等。维基百科上有一个非常全面的机器学习算法列表。

这些算法被其开发者打包成像pandas这样的软件。很少有人会自己编写机器学习算法,使用现成的算法要轻松得多。编写新的算法就像发明一门新的编程语言一样,你必须非常上心,而且必须投入大量时间。如果你想问我模型内部的原理,我会摆摆手说:“就是数学呗。”抱歉,如果你真想了解这方面的知识,我建议你阅读其他的相关图书。这些知识很有意思,但不在本书的内容范围内。

现在,我们在训练数据集上训练这个模型。我们从刚才的探索性分析中了解到,票价等级和性别是重要的因素。我们要预测的是乘客的幸存情况。训练数据中已经有了乘客的幸存数据,我们现在要让这个模型去预测出结果,然后与事实做对比。无论对比得出的结果是多少,那就是目前模型的准确率。

大数据世界里有一个公开的秘密:所有的数据都是脏数据,无一例外。数据是由人们四处走动和计算,或是人类制造的传感器收集来的东西。在所有看似有序的数字序列中,都有噪声数据的存在。这里乱糟糟,那里缺胳膊少腿儿,这就是生活。问题是,脏数据不能用来做计算。所以,在机器学习中,为了让函数能跑得顺畅,我们有时候必须先编造出一些东西。

吓坏了吧?我第一次意识到这一点时,也吓坏了。作为一名记者,我怎么能胡编乱造呢?我必须对每一行字进行事实核查,并且向事实核查人、编辑或我的读者证明它是正确的。然而,在机器学习中,人们经常在方便的时候编造一些东西。

现在,在物理学中,你就可以这样做。如果你想知道一个密闭的容器中A点的温度,可以在两个跟A距离相等的点(B点与C点)测量温度,然后假定A点的温度是B点和C点的中间值。而在统计学中,这反而就是正常的工作原理,而这种数据的缺失有助于研究内在不确定性。我们将使用一个名为fillna的函数来填补所有缺失的值:

train["Age"]=train["Age"].fillna(train["Age"].median())

Fillna是一个用以填补缺失值的函数,毕竟缺失值会导致算法无法顺利运行。因此,我们需要把空缺的值填补好。在这里,DataCamp推荐我们使用中位数。

我们来看看数据集中都有什么:

显示训练数据,查看可用特征print(train)

print(train)

[共891行*12列]

如果你阅读了上面数百行内容,那就太厉害了。但如果你略过不读,我也不惊讶。这里列出了许多行数据,而不是使用一个小的子集,是为了让读者对数据科学家感同身受。处理数字行列,你会感觉到价值中立,有时还会感觉非常乏味。而在仅处理数字时,我们很容易忽视“人性”这一因素——我们很容易忘记,每一行数据都代表一个有希望,有梦想,有家人,有过去的真实的人。

看过原始数据,现在我们可以开始处理它了。我们先将原始数据转换为数组,这是一种计算机能够使用的数据结构。

创建两个numpy数组:target、features_one

target=train["Survived"].values

#预处理数据

encoded_sex=preprocessing.LabelEncoder()

#转换成数字

train.Sex=encoded_sex.fit_transform(train.Sex)

features_one=train[["Pclass","Sex","Age", "Fare"]].values

#拟合你的第一个决策树:my_tree_one

my_tree_one=tree.DecisionTreeClassifier()

my_tree_one=my_tree_one.fit(features_one, target)

我们正在做的是在一个名为“my_tree_one”的决策树分类器上运行fit函数。我们要考虑的特征包括Pclass、Sex、Age和Fare,要让算法搞清楚这四个特征之间的关系,以便预测Survived的值。

#查看相关特征的重要度和分数

print(my_tree_one.feature_importances_)

[ 0.12315342 0.31274009 0.22675108 0.3373554 ]

Feature_importances属性显示了每一个预测指标的统计显著性。

这组数值中最大的那个,就是最重要的。

Pclass=0.1269655

Sex=0.31274009

Age=0.23914906

Fare=0.32114535

Fare的数值最大。我们可以得出结论,在“泰坦尼克号”灾难中,票价是决定乘客能否幸存的最重要因素。

至此,我们可以运行一个函数,看看在这个宇宙通用数学约束下的数据集内,我们的预测有多高的准确率。我们使用score函数来算出平均准确度:

print(my_tree_one.score(features_one, target))

0.977553310887

哇!97%!太棒了!如果我考试能得97分,我就心满意足了。现在,我们可以说这个模型的准确率是97%。这个机器刚刚通过创建一个数学模型进行了“学习”。这个模型存储在对象my_tree_one中。

接下来,我们将把这个模型应用于测试数据。记住,测试数据没有“Survived”这列数据。我们要做的是使用模型来预测测试数据的每一名乘客能否幸存。根据这个模型,我们已经知道,票价是最重要的预测指标,但是年龄、性别和船舱等级在数学上也很重要。现在,我们将模型应用到测试数据,看看会发生什么:

#用中位数填补缺失值

test["Fare"]=test["Fare"].fillna(test["Fare"].median())

#用中位数填补年龄的缺失值

test["Age"]=test["Age"].fillna(test["Age"].median())

#预处理数据

test_encoded_sex=preprocessing.LabelEncoder()

test.Sex=test_encoded_sex.fit_transform(test.Sex)

#从测试集提取Pclass、Sex、Age、Fare四个特征

test_features=test[["Pclass","Sex","Age", "Fare"]].values

print('These are the features:\n')

print(test_features)

#对测试集做出预测并显示出来

my_prediction=my_tree_one.predict(test_features)

print('This is the prediction:\n')

print(my_prediction)

#创建一个包含两个列的数据框——PassengerId、Survived,其中Survived存放的是预测结果

PassengerId=np.array(test["PassengerId"]).astype(int)

my_solution=pd.DataFrame(my_prediction, PassengerId,

columns=["Survived"])

print('This is the solution in toto:\n')

print(my_solution)

#检查数据框是否包含418项

print('This is the solution shape:\n')

print(my_solution.shape)

#将你的解答写入CSV文件:my_solution.csv

my_solution.to_csv("my_solution_one.csv",index_label=

["PassengerId"])

这些是特征:

[[ 3. 1. 34.5 7.8292]

[ 3. 0. 47. 7. ]

[ 2. 1. 62. 9.6875] …,

[ 3. 1. 38.5 7.25 ]

[ 3. 1. 27. 8.05 ]

[ 3. 1. 27. 22.3583]]

以下是预测结果:

[ 0 0 1 1 1 0 0 0 1 0 0 0 1 1 1 1 0 1 1 0 0 1 1 0 1 0 1 1 1 0 0 0 1 0 1 0 0 0 0 1 0 1 0 1 1 0 0 0 1 1 1 0 1 1 1 0 0 0 1 1 0 0 0 1 0 0 1 0 0 1 1 0 0 0 1 0 0 1 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 1 1 1 0 1 0 0 0 1 0 0 0 0 0 0 0 1 1 1 0 1 1 0 1 1 0 1 0 0 1 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 1 0 1 0 1 0 0 1 0 0 1 1 0 1 1 1 1 1 0 1 1 0 0 0 0 1 0 1 0 1 1 0 1 1 0 0 1 0 1 0 1 0 0 0 0 0 1 0 1 0 1 0 0 0 0 1 0 1 0 0 0 0 1 0 1 1 0 1 0 0 1 0 1 0 1 0 1 1 1 0 0 1 0 0 0 1 0 0 1 0 0 1 1 1 1 1 1 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 1 1 0 1 0 0 0 1 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 1 1 0 1 1 0 0 1 0 0 1 1 0 0 0 0 0 0 0 1 1 0 1 0 0 0 1 0 1 1 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 1 1 0 0 0 1 0 1 0 0 1 0 1 1 1 1 0 0 0 1 0 0 1 0 0 1 1 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 1 1 0 0 1 0 1 0 0 1 0 1 0 0 0 0 0 1 1 1 1 0 0 1 0 0 0 ]

以下是全部的解答:

[共418行*1列]

这是解空间:

(418, 1)

新增的Survived列数据包含了对测试数据集418名乘客的预测结果。瞧瞧!我们刚完成了机器学习。虽然是入门级的,但它就是机器学习。如果有人说他们“使用人工智能做了一次决策”,通常他们的意思就是“使用机器学习”,而且通常他们所做的事情跟我们刚才的过程差不多。

我们创建了一个Survived列,得到了一个我们认为97%准确的数字。我们了解到,票价是“泰坦尼克号”幸存者数据的数学分析中最具影响力的因素。这就是狭义人工智能。这不是什么值得害怕的事,也并不会引领我们堕入全球被超智能计算机统治的境地。“这些只是统计模型,就像谷歌玩棋牌游戏时使用的模型,或是你的手机用来预测你说的单词以便转录信息一样。”卡内基梅隆大学教授、机器学习研究员扎卡里·利普顿在接受The Register杂志关于人工智能的采访时说,“跟一碗面条相比,它们并没有多出什么了不起的意识。”[19]

对程序员来说,写一个算法很简单。你把算法写出来,部署下去。嗯,看起来能用,就不再跟进了。下回再拿出来用,可能会稍微调一调,看准确率会不会提高。你会尽量获得最高的准确率,然后接着做下一件事。

与此同时,这些数字会在世界范围内产生影响。从这些数据得出支付更高票价的乘客更有可能在海难中幸存这一结论,是非常不明智的。然而,得出这个结论在统计学上是合法的。如果我们要计算保险费率,我们可以说,高价票乘客在冰山事故中有较低的死亡率,因此这代表着一种较低的提前赔付风险。支付高票价的人要比支付低票价的人富有,这使我们可以向富人收取较低的保险费。保险的重点就在于让风险在大量人群中平均分配。我们可以为保险公司赚更多钱,但推销出去的不是最好的产品。

这些类型的计算技术用于“价格优化”,或用于将客户精细分配到非常小的组别里,以便对不同的客户组显示不同的价格。从保险业到旅游业,价格优化无处不在。价格优化常常造成价格歧视。ProPublica和《消费者报告》2017年的一项分析发现,在加利福尼亚州、伊利诺伊州、得克萨斯州和密苏里州,一些大型保险公司向居住在少数族裔社区的人收取的同类意外保险费用,要比其他地区的人多出30%。[20]《华尔街日报》2014年的一项分析发现,Staples.com网站上的同一款普通订书机对不同的客户会显示不同的价格。价格或高或低,取决于机器估计的客户邮政编码。[21]东北大学的克里斯托·威尔逊、戴维·拉泽和其他研究员发现,Homedepot.com和旅游网站会依据用户浏览网站时使用的是手机还是电脑,分别显示不同的价格。[22]亚马逊在2000年就承认尝试过使用差别定价策略。亚马逊的CEO杰夫·贝索斯为此公开致歉,称这是“一个错误”。[23]

在一个不平等的世界里,如果我们根据世界的实际情况来制定定价算法,那么女性、穷人和少数族裔客户就会不可避免地被收取更多的费用。研究数学的人常常对此感到惊讶。而妇女、穷人和少数族裔则不会。种族、性别和阶级会以各种明显和不正当的方式影响商品的定价。对于理发、干洗、剃须刀甚至除臭剂,对女性的收费都高于男性。亚裔美国人在SAT预备课程上被收取的费用要比其他人高出一倍。[24]餐馆的非裔美国服务员得到的小费要比他们的白人同事少。[25]贫穷往往意味着要为日常必需品支付更高的费用。使用分期付款计划购买家具,总价格比直接购买要高。发薪日贷款[26]的利率远远高于银行贷款利率。如果用于房屋居住的费用不足家庭月收入的30%,那么会被认为其家庭负担得起住房。但由于与经济不稳定相关的各种因素,贫穷的租户经常被迫为住房支付更多费用。社会学家帕特·夏基在对马修·德斯蒙德的《扫地出门:美国城市的贫穷与暴利》和米切尔·迪尼耶的《犹太人居住区:一个地方的诞生,一个观念的历史》这两本民族志图书的评论中这样写道:“在密尔沃基,大多数贫困的租户在房屋租赁上要花费至少一半的收入,有三分之一的人甚至要为此花费至少80%的收入。”[27]不平等是不公平的,但并不罕见。如果机器学习模型只是简单地复制实际的世界,那我们就无法走向一个更加公正的社会。“该技术具有强大的吸引力,它让人们希望预测未来的古老愿望和现代化的统计能力交汇在了一起。”法学教授、人工智能伦理专家弗兰克·帕斯奎尔在《黑箱社会》中写道,“然而,在保密的氛围中,不良信息可能会被误用,从而导致不公平的,甚至是灾难性的预测结果。”[28]

我们在使用机器学习做社会决策时会遇到问题,部分原因是那些数字掩盖了重要的社会背景。在“泰坦尼克号”的例子中,我们选择了一个分类器——乘客的幸存状态,并且利用一些特征来预测这个分类器。但实际上,还有其他可能的因素存在。例如,“泰坦尼克号”数据集只包括年龄、性别和其他因素,我们只能基于已有的数据来建立预测指标。但是,由于这是一项人类工作,而不是数学事件,所以还有其他因素在起作用。

我们来回顾一下“泰坦尼克号”失事那个夜晚。1912年4月14日,“泰坦尼克号”曾多次收到附近船只发出的结冰警告。晚上11时40分,“泰坦尼克号”撞上冰山。午夜刚过,船长爱德华·约翰·史密斯召集乘客,开始从“泰坦尼克号”撤离。史密斯下了命令:“让妇女和儿童上船,然后把小艇放下。”大副威廉·默多克负责右舷的救生艇,二副查尔斯·莱特勒负责左舷的救生艇。他们对船长的命令理解不一。默多克认为,船长让妇女和儿童优先上救生艇。莱特勒认为,船长只允许妇女和儿童上救生艇。当周围的妇女和儿童都上了救生艇后,默多克允许男性乘客也登上救生艇。莱特勒让周围的妇女和儿童都上了救生艇,哪怕艇上还有空位,他照样把救生艇往水里降。即使救生艇没有满载65人,两人都将救生艇降到水中。船上的乘客太多了,没有足够的救生艇:这艘可容纳3 547人的船,却只配了20艘救生艇。最可信的记录显示,“泰坦尼克号”轻装上阵,搭载着892名船员和1 320名乘客。

我们可以就救生艇的编号做一个有意思的测试。默多克在右舷的救生艇编号都是奇数,莱特勒在左舷的救生艇编号都是偶数。从救生艇的单双号看来,男性乘客的幸存率可能不一样,因为负责双号救生艇的莱特勒不让男性乘客上艇。但问题是,数据集中并没有救生艇编号。这是一个深刻而难以克服的大问题。除非在模型中加载这个因子,并且以计算机能够计算的方式表述,否则就不能算数。不是所有重要的东西都能被计算在内。计算机无法从数据集中跳脱出来,并且找到可能重要的额外因素,但是人类可以。

不过,这当中还存在虚假因果关系的问题。倘若我们有救生艇的编号数据,从计算的角度来看,单号救生艇上的男性乘客更有机会幸存。如果根据这个结论来制定决策,为了在紧急情况下让更多男性获救,我们可能会决定给所有的救生艇都编上奇数号码。显然,这太荒谬了。关键在于两名副官,而不是救生艇的编号。

还有两位年轻人也混淆了纯粹的数学解释。沃尔特·洛德的《此夜永难忘》是一本讲述“泰坦尼克号”海难的非虚构畅销书,记录了这艘巨轮最后几个小时的感人故事。[29]洛德讲述了17岁的杰克·赛耶与父母在欧洲度过一个漫长的假期后,在法国瑟堡登上了“泰坦尼克号”。赛耶在船上结识了新朋友米尔顿·朗,这是一个与他年龄相仿的坐头等舱旅行的年轻人。两位年轻人在海难危机加剧时,都在帮助其他乘客脱险。他们帮着将妇女和儿童送入救生艇,到凌晨2点,几乎所有救生艇都下了水。凌晨2时15分,最后一批救生艇下水。这时,船身向左舷倾斜,大浪冲过来,撞在甲板上。主厨约翰·柯林斯站在甲板上,手里抱着一个婴儿。他正在帮助一名乘务员和一名带着两个孩子的统舱女乘客。他们都被瞬间吞入海里。巨浪的力量将婴儿从他的怀里冲走。

赛耶和朗目睹了甲板上的混乱。突然间,灯熄灭了,海水已经涨到二号锅炉房水箱的位置了。月亮、星星和救生艇上的提灯成了唯一的光源,船身渐渐下沉,光线慢慢飘远。二号烟囱坍塌了。赛耶和朗环顾四周,救生艇已经走远,目光所及之处再无救援船了。他们意识到这一刻已经到来,该跳了。他们握了手,祝彼此好运。洛德写道:

朗跨过了栏杆,而塞耶叉开双腿跨在上面,开始解大衣的扣子。朗手拉着栏杆,身子已在栏杆外面。他抬头朝塞耶看了一眼,问道:“你跳吗,小子?”

“你先跳,我马上就下来。”塞耶向他保证道。

朗面对着船舷,松手坠入海里。10秒钟后,塞耶把另一条腿也跨过栏杆,面向大海坐在栏杆上。他现在离水面不过10英尺[30]高,便用力一推,尽力往远处跳去。

在这两种弃船逃生的方法中,塞耶显然是正确的。

塞耶游到了附近一艘翻倒的救生艇上,与其他40人一起紧紧抓住救生艇,才得以幸存。他看着“泰坦尼克号”断成两半,船头和船尾在一片残骸中滑落到水中。塞耶听到人们在水里哭泣,声音听起来像蝗虫。最终,12号救生艇把塞耶和其他人从冰冷的海水中救了出来。几个小时之后,救援人员抵达。塞耶在救生艇里瑟瑟发抖,直到第二天早上8点半,乘客们才被“卡帕西亚号”救起。

塞耶和朗这两个年轻人年纪相仿,体力相当,社会地位相同,而且在这场灾难中幸存的机会也完全相同。他们的差异归结到最终的那一跳。塞耶尽他所能跳到远离船身的地方,朗则跳到了船身近处的海里。朗被吸入了无底的深渊,而塞耶活了下来。让我不安的是,无论计算机对塞耶和朗的预测结果是什么,都是错的。计算机的预测仅仅基于票价等级、年龄和性别,但实际的关键因素是他们最后那一跳的差异。计算机从根本上就是错的。朗遇难的随机性,正是造成我们对“泰坦尼克号”乘客幸存情况的统计预测不可能达到100%准确的原因。因为人类不是统计数据,也永远不会是统计数据。

这就印证了“数据的不合理有效性”原则。除非你处处留心可能出现的偏差和无序,否则人工智能就只是表面看起来那样利落。关于通过计算机科学解释世界的研究,我最喜欢的一个解释来自谷歌研究人员阿隆·哈勒维、彼得·诺维格和费尔南多·佩雷拉的一篇论文。他们写道:

尤金·维格纳在文章《数学在自然科学中不合理的有效性》中探讨了为什么那么多物理学规律可以使用如此简单的数学公式(如f=ma或e=mc2)来巧妙地表达。与此同时,涉及人类的科学被证实,比起涉及基本粒子的科学,它们对精简优雅的数学更具抵抗力。经济学家因没能简洁地模型化人类行为而患有“物理学嫉妒症”。而一本非正式、不完整的英语语法书就超过1 700页。也许,当论及自然语言处理或者相关的学科,我们注定只能面对复杂的理论,而这些理论也注定不像物理公式般优雅。倘若如此,我们就不应表现得仿佛我们的目的是创造极其优雅的理论一样,而应该接受这种复杂性,并且利用我们这位最好的盟友:数据的不合理有效性。[31]

数据是不合理有效的,甚至迷人魂魄。这就解释了我们为何得以建立一个看起来能以97%的准确率预测“泰坦尼克号”海难中乘客是否生还的分类器,以及计算机为何能击败人类围棋冠军。这也解释了机器为何不会考虑人类在现实灾难场景下遇到的任何偶然事件。只要我们仔细了解机器学习的过程,就能发现这一点。数据确实非常有效。然而,这种数据驱动的方法会让机器忽略许多人类认为非常重要的因素。

人类建立法律和社会,是为了适应人类认为重要的所有事情。以数据为驱动所做的决策,很少有完全符合这些复杂规则的。数据的不合理有效性也出现在翻译、语音控制的智能家居设备和手写识别领域。机器不会以人类的理解方式去理解单词和单词组合。用于语音识别和机器翻译的统计方法,依赖含大量短单词序列的大数据库、n-grams之类的语言模型,以及概率。人们通常谈论的都是同样的事物,搜索的也是同样的事物,普遍常识也相当普遍。几十年来,谷歌一直致力于解决这些问题。他们有这些常见主题领域中最好的科学家,而且他们拥有的数据比以往任何人所能拥有的都多。谷歌图书语料库、《纽约时报》语料库,还有所有人使用谷歌搜索过的所有记录的语料库——其实,把这些记录都加载到一个巨大的数据库中,用来计算所有单词在其他单词附近出现的频率,结果都具有不合理有效性。我们来看一个简单的例子。在n-grams语言模型中,“船”经常出现在“水”附近,所以两者可能是相关的。“船”与“水”相关的概率要高于“船”与“选民”或者“船”与“臭虫”的相关性,因此搜索“船”会得到一些跟船和水相关的术语或文档,而不是那些跟船和臭虫相关的东西。其实这不是真正的学习,只是受了学习这一概念的启发。如果你去阅读搜索背后的计算过程(可以在网上找到),会发现这些计算一点也不神奇,只是纯粹的数学而已。计算机能在足够的时间内正确处理足够多的事情,以至于我们可能会倾向于认为它基本上是正确的——但它也有可能因错误的原因而得到正确的结果。

社会问题的决策不仅仅是计算,因此如果我们仅使用数据来做涉及社会和价值判断的决策,社会问题就会随之而来。我们知道,持一等票的乘客在“泰坦尼克号”海难中有较大的幸存率,但是如果采用一个模式,认为头等舱乘客在灾难中就该比二等舱或三等舱乘客有更高的幸存率,那就错了。我们也不应该根据有缺陷的模型(比如我们创建的那个模型)给出的建议来行事。我们的“泰坦尼克号”计算模型可以用于论证为何要向头等舱乘客收取较少的旅行保险费。但这是极其荒谬的——我们不应该惩罚那些没有足够的钱买头等舱的人。最重要的是,我们现在应该明白,有些事情是机器永远也学不会的,而人类的判断、强化和解释永远都是有必要的。

[1] See https://xkcd.com/1425, and note that the hidden text on the online version of the comic refers to a famous anecdote about Marvin Minsky.

[2] Solon, “Roomba Creator Responds to Reports of ‘Poopocalypse.’”

[3] Busch, “A Dozen Ways to Get Lost in Translation”; van Dalen, “The Algorithms behind the Headlines”; ACM Computing Curricula Task Force, Computer Science Cur ricula 2013.

[4] IEEE Spectrum, “Tech Luminaries Address Singularity.”

[5] Gomes, “Facebook AI Director Yann LeCun on His Quest to Unleash Deep Learn ing and Make Machines Smarter.”

[6] “machine, n.”

[7] Butterfield and Ngondi, A Dictionary of Computer Science.

[8] Pedregosa et al., “Scikit-Learn: Machine Learning in Python.”

[9] 弗雷德金(Fredkin)教授是卡内基梅隆大学纪念为人工智能做出巨大贡献的物理学家爱德华·弗雷德金(Edward Fredkin)所设的教席。——译者注

[10] Mitchell, “The Discipline of Machine Learning.”

[11] Neville-Neil, “The Chess Player Who Couldn’t Pass the Salt.”

[12] Russell and Norvig, Artificial Intelligence.

[13] O’Neil, Weapons of Math Destruction.

[14] Grazian, Mix It Up.

[15] Blow, Fire Shut Up in My Bones.

[16] Tversky and Kahneman, “Availability.”See also Kahneman, Thinking, Fast and Slow; Slovic, The Perception of Risk; Slovic and Slovic, Numbers and Nerves; Fischhoff and Kadvany, Risk.

[17] See https://www.datacamp.com for more on the Titanic data science tutorial. I’ve omitted some parts of the tutorial for readability.

[18] 在英文中,“库”与“图书馆”都是library。——译者注

[19] Quach, “Facebook Pulls Plug on Language-Inventing Chatbots?”

[20] Angwin et al. “A World Apart.”

[21] Valentino-DeVries, Singer-Vine, and Soltani, “Websites Vary Prices, Deals Based on Users’ Information.”

[22] Hannak et al., “Measuring Price Discrimination and Steering on E-Commerce Web Sites.”

[23] Heffernan, “Amazon’s Prime Suspect.”

[24] Angwin, Mattu, and Larson, “Test Prep Is More Expensive——for Asian Students.”

[25] Brewster and Lynn, “Black-White Earnings Gap among Restaurant Servers.”

[26] 发薪日贷款(payday loan)是一种借款人承诺在发薪后偿付的短期贷款。——译者注

[27] Sharkey, “The Destructive Legacy of Housing Segregation.”

[28] Pasquale, The Black Box Society.

[29] Lord, A Night to Remember; Brown, “Chronology——Sinking of S.S. TITANIC.”

[30] 1英尺= 30.48厘米。——编者注

[31] Halevy, Norvig, and Pereira, “The Unreasonable Effectiveness of Data,”8.


第6章 人的问题第8章 你不开车,车可不会自己走