# 十三、预测 数据科学的一个重要方面,是发现数据可以告诉我们未来的什么事情。气候和污染的数据说了什么几十年内温度的事情?根据一个人的互联网个人信息,哪些网站可能会让他感兴趣?病人的病史如何用来判断他或她对治疗的反应? 为了回答这样的问题,数据科学家已经开发出了预测的方法。在本章中,我们将研究一种最常用的方法,基于一个变量的值来预测另一个变量。 方法的基础由弗朗西斯·高尔顿爵士(Sir Francis Galton)奠定。我们在 7.1 节看到,高尔顿研究了身体特征是如何从一代传到下一代的。他最著名的工作之一,是根据父母的高度预测子女的身高。我们已经研究了高尔顿为此收集的数据集。`heights `表包含了 934 个成年子女的双亲身高和子女身高(全部以英寸为单位)。 ```py # Galton's data on heights of parents and their adult children galton = Table.read_table('galton.csv') heights = Table().with_columns( 'MidParent', galton.column('midparentHeight'), 'Child', galton.column('childHeight') ) heights ``` | MidParent | Child | | --- | --- | | 75.43 | 73.2 | | 75.43 | 69.2 | | 75.43 | 69 | | 75.43 | 69 | | 73.66 | 73.5 | | 73.66 | 72.5 | | 73.66 | 65.5 | | 73.66 | 65.5 | | 72.06 | 71 | | 72.06 | 68 | (省略了 924 行) ```py heights.scatter('MidParent') ``` 收集数据的主要原因是能够预测成年子女的身高,他们的父母与数据集中相似。 在注意到两个变量之间的正相关之后,我们在第 7.1 节中做了这些预测。 我们的方法是,基于新人的双亲身高周围的所有点来做预测。 为此,我们编写了一个名为`predict_child`的函数,该函数以双亲身高作为参数,并返回双亲身高在半英寸之内的,所有子女的平均身高。 ```py def predict_child(mpht): """Return a prediction of the height of a child whose parents have a midparent height of mpht. The prediction is the average height of the children whose midparent height is in the range mpht plus or minus 0.5 inches. """ close_points = heights.where('MidParent', are.between(mpht-0.5, mpht + 0.5)) return close_points.column('Child').mean() ``` 我们将函数应用于`Midparent`列,可视化我们的结果。 ```py # Apply predict_child to all the midparent heights heights_with_predictions = heights.with_column( 'Prediction', heights.apply(predict_child, 'MidParent') ) # Draw the original scatter plot along with the predicted values heights_with_predictions.scatter('MidParent') ``` 给定双亲身高的预测值,大致位于给定身高处的垂直条形的中心。这种预测方法称为回归。 本章后面我们会看到这个术语的来源。 我们也会看到,我们是否可以避免将“接近”任意定义为“在半英寸之内”。 但是首先我们要开发一个可用于很多环境的方法,来决定一个变量作为另一个变量的预测值有多好。 ## 相关性 在本节中,我们将开发一种度量,度量散点图紧密聚集在一条直线上的程度。 形式上,这被称为测量线性关联。 `hybrid`表包含了 1997 年到 2013 年在美国销售的混合动力车的数据。数据来自佛罗里达大学 [Larry Winner 教授](http://www.stat.ufl.edu/~winner/)的在线数据档案。这些列为: + `vehicle`:车的型号 + `year`:出厂年份 + `msrp`: 2013 年制造商的建议零售价(美元) + `acceleration`: 加速度(千米每小时每秒) + `mpg`: 燃油效率(英里每加仑) + `class`: 型号的类别 (省略了 143 行) 下图是`msrp`与`acceleration`的散点图。 这意味着`msrp`绘制在纵轴上并且`acceleration`在横轴上。 ```py hybrid.scatter('acceleration', 'msrp') ``` 注意正相关。 散点图倾斜向上,表明加速度较大的车辆通常成本更高;相反,价格更高的汽车通常具有更大的加速。 `msrp`与`mpg`的散点图表明了负相关。 `mpg`较高的混合动力车往往成本较低。 这似乎令人惊讶,直到你明白了,加速更快的汽车往往燃油效率更低,行驶里程更低。 之前的散点图显示,这些也是价格更高的车型。 ```py hybrid.scatter('mpg', 'msrp') ``` 除了负相关,价格与效率的散点图显示了两个变量之间的非线性关系。 这些点似乎围绕在一条曲线周围,而不是一条直线。 但是,如果我们只将数据限制在 SUV 类别中,价格和效率之间仍然负相关的,但是这种关系似乎更为线性。 SUV 价格与加速度之间的关系也呈线性趋势,但是斜率是正的。 ```py suv = hybrid.where('class', 'SUV') suv.scatter('mpg', 'msrp') ``` ```py suv.scatter('acceleration', 'msrp') ``` 你会注意到,即使不关注变量被测量的单位,我们也可以从散点图的大体方向和形状中得到有用的信息。 事实上,我们可以将所有的变量绘制成标准单位,并且绘图看起来是一样的。 这给了我们一个方法,来比较两个散点图中的线性程度。 回想一下,在前面的章节中,我们定义了`standard_units`函数来将数值数组转换为标准单位。 ```py def standard_units(any_numbers): "Convert any array of numbers to standard units." return (any_numbers - np.mean(any_numbers))/np.std(any_numbers) ``` 我们可以使用这个函数重新绘制 SUV 的两个散点图,所有变量都以标准单位测量。 ```py Table().with_columns( 'mpg (standard units)', standard_units(suv.column('mpg')), 'msrp (standard units)', standard_units(suv.column('msrp')) ).scatter(0, 1) plots.xlim(-3, 3) plots.ylim(-3, 3); ``` ```py Table().with_columns( 'acceleration (standard units)', standard_units(suv.column('acceleration')), 'msrp (standard units)', standard_units(suv.column('msrp')) ).scatter(0, 1) plots.xlim(-3, 3) plots.ylim(-3, 3); ``` 我们在这些数字中看到的关联与我们之前看到的一样。 另外,由于现在两张散点图的刻度完全相同,我们可以看到,第二张图中的线性关系比第一张图中的线性关系更加模糊。 我们现在将定义一个度量,使用标准单位来量化我们看到的这种关联。 ### 相关系数 相关系数测量两个变量之间线性关系的强度。 在图形上,它测量散点图聚集在一条直线上的程度。 相关系数这个术语不容易表述,所以它通常缩写为相关性并用`r`表示。 以下是一些关于`r`的数学事实,我们将通过模拟观察。 + 相关系数`r`是介于`-1`和`1`之间的数字。 + `r`度量了散点图围绕一条直线聚集的程度。 + 如果散点图是完美的向上倾斜的直线,`r = 1`,如果散点图是完美的向下倾斜的直线,`r = -1`。 函数`r_scatter`接受`r`值作为参数,模拟相关性非常接近`r`的散点图。 由于模拟中的随机性,相关性不会完全等于`r`。 调用`r_scatter`几次,以`r`的不同值作为参数,并查看散点图如何变化。 当`r = 1`时,散点图是完全线性的,向上倾斜。 当`r = -1`时,散点图是完全线性的,向下倾斜。 当`r = 0`时,散点图是围绕水平轴的不定形云,并且变量据说是不相关的。 ```py r_scatter(0.9) ``` ```py r_scatter(0.25) ``` ```py r_scatter(0) ``` ```py r_scatter(-0.55) ``` ### 计算`r` 目前为止,`r`的公式还不清楚。 它拥有超出本课程范围的数学基础。 然而,你将会看到,这个计算很简单,可以帮助我们理解`r`的几个属性。 `r`的公式: `r`是两个变量的乘积的均值,这两个变量都以标准单位来衡量。 以下是计算中的步骤。 我们将把这些步骤应用于`x`和`y`值的简单表格。 ```py x = np.arange(1, 7, 1) y = make_array(2, 3, 1, 5, 2, 7) t = Table().with_columns( 'x', x, 'y', y ) t ``` | x | y | | --- | --- | | 1 | 2 | | 2 | 3 | | 3 | 1 | | 4 | 5 | | 5 | 2 | | 6 | 7 | 根据散点图,我们预计`r`将是正值,但不等于 1。 ```py t.scatter(0, 1, s=30, color='red') ``` 第一步:将每个变量转换为标准单位。 ```py t_su = t.with_columns( 'x (standard units)', standard_units(x), 'y (standard units)', standard_units(y) ) t_su ``` | x | y | x (standard units) | y (standard units) | | --- | --- | --- | --- | | 1 | 2 | -1.46385 | -0.648886 | | 2 | 3 | -0.87831 | -0.162221 | | 3 | 1 | -0.29277 | -1.13555 | | 4 | 5 | 0.29277 | 0.811107 | | 5 | 2 | 0.87831 | -0.648886 | | 6 | 7 | 1.46385 | 1.78444 | 第二步:将每一对标准单位相乘 ```py t_product = t_su.with_column('product of standard units', t_su.column(2) * t_su.column(3)) t_product ``` | x | y | x (standard units) | y (standard units) | product of standard units | | --- | --- | --- | --- | | 1 | 2 | -1.46385 | -0.648886 | 0.949871 | | 2 | 3 | -0.87831 | -0.162221 | 0.142481 | | 3 | 1 | -0.29277 | -1.13555 | 0.332455 | | 4 | 5 | 0.29277 | 0.811107 | 0.237468 | | 5 | 2 | 0.87831 | -0.648886 | -0.569923 | | 6 | 7 | 1.46385 | 1.78444 | 2.61215 | 第三步:`r`是第二步计算的乘积的均值。 ```py # r is the average of the products of standard units r = np.mean(t_product.column(4)) r 0.61741639718977093 ``` 正如我们的预期,`r`是个不等于的正值。 ### `r`的性质 计算结果表明: `r`是一个纯数字。 它没有单位。 这是因为`r`基于标准单位。 `r`不受任何轴上单位的影响。 这也是因为`r`基于标准单位。 `r`不受轴的交换的影响。 在代数上,这是因为标准单位的乘积不依赖于哪个变量被称为`x `和`y`。 在几何上,轴的切换关于`y = x`直线翻转了散点图,但不会改变群聚度和关联的符号。 ```py t.scatter('y', 'x', s=30, color='red') ``` ### `correlation `函数 我们将要重复计算相关性,所以定义一个函数会有帮助,这个函数通过执行上述所有步骤来计算它。 让我们定义一个函数`correlation `,它接受一个表格,和两列的标签。该函数返回`r`,它是标准单位下这些列的值的乘积的平均值。 ```py def correlation(t, x, y): return np.mean(standard_units(t.column(x))*standard_units(t.column(y))) ``` 让我们在`t`的`x`和`y`列上调用函数。 该函数返回`x`和`y`之间的相关性的相同答案,就像直接应用`r`的公式一样。 ```py correlation(t, 'x', 'y') 0.61741639718977093 ``` 我们注意到,变量被指定的顺序并不重要。 ```py correlation(t, 'y', 'x') 0.61741639718977093 ``` 在`suv`表的列上调用`correlation`,可以使我们看到价格和效率之间的相关性,以及价格和加速度之间的相关性。 ```py correlation(suv, 'mpg', 'msrp') -0.6667143635709919 correlation(suv, 'acceleration', 'msrp') 0.48699799279959155 ``` 这些数值证实了我们的观察: 价格和效率之间存在负相关关系,而价格和加速度之间存在正相关关系。 价格和加速度之间的线性关系(相关性约为 0.5),比价格和效率之间的线性关系稍弱(相关性约为 -0.67)。 相关性是一个简单而强大的概念,但有时会被误用。 在使用`r`之前,重要的是要知道相关性能做和不能做什么。 ### 相关不是因果 相关只衡量关联,并不意味着因果。 尽管学区内的孩子的体重与数学能力之间的相关性可能是正的,但这并不意味着做数学会使孩子更重,或者说增加体重会提高孩子的数学能力。 年龄是一个使人混淆的变量:平均来说,较大的孩子比较小的孩子更重,数学能力更好。 ### 相关性度量线性关联 相关性只测量一种关联 - 线性关联。 具有较强非线性关联的变量可能具有非常低的相关性。 这里有一个变量的例子,它具有完美的二次关联`y = x ^ 2`,但是相关性等于 0。 ```py new_x = np.arange(-4, 4.1, 0.5) nonlinear = Table().with_columns( 'x', new_x, 'y', new_x**2 ) nonlinear.scatter('x', 'y', s=30, color='r') ``` ```py correlation(nonlinear, 'x', 'y') 0.0 ``` ### 相关性受到离群点影响 离群点可能对相关性有很大的影响。 下面是一个例子,其中通过增加一个离群点,`r`等于 1 的散点图变成`r`等于 0 的图。 ```py line = Table().with_columns( 'x', make_array(1, 2, 3, 4), 'y', make_array(1, 2, 3, 4) ) line.scatter('x', 'y', s=30, color='r') ``` ```py correlation(line, 'x', 'y') 1.0 outlier = Table().with_columns( 'x', make_array(1, 2, 3, 4, 5), 'y', make_array(1, 2, 3, 4, 0) ) outlier.scatter('x', 'y', s=30, color='r') ``` ```py correlation(outlier, 'x', 'y') 0.0 ``` ### 生态相关性应谨慎解读 基于汇总数据的相关性可能会产生误导。 作为一个例子,这里是 2014 年 SAT 批判性阅读和数学成绩的数据。50 个州和华盛顿特区各有一个点。`Participation Rate`列包含参加考试的高中学生的百分比。 接下来的三列显示了每个州的测试每个部分的平均得分,最后一列是测试总得分的平均值。 ```py sat2014 = Table.read_table('sat2014.csv').sort('State') sat2014 ``` | State | Participation Rate | Critical Reading | Math | Writing | Combined | | --- | --- | --- | --- | --- | --- | | Alabama | 6.7 | 547 | 538 | 532 | 1617 | | Alaska | 54.2 | 507 | 503 | 475 | 1485 | | Arizona | 36.4 | 522 | 525 | 500 | 1547 | | Arkansas | 4.2 | 573 | 571 | 554 | 1698 | | California | 60.3 | 498 | 510 | 496 | 1504 | | Colorado | 14.3 | 582 | 586 | 567 | 1735 | | Connecticut | 88.4 | 507 | 510 | 508 | 1525 | | Delaware | 100 | 456 | 459 | 444 | 1359 | | District of Columbia | 100 | 440 | 438 | 431 | 1309 | | Florida | 72.2 | 491 | 485 | 472 | 1448 | (省略了 41 行) 数学得分与批判性阅读得分的散点图紧密聚集在一条直线上; 相关性接近 0.985。 ```py sat2014.scatter('Critical Reading', 'Math') ``` ```py correlation(sat2014, 'Critical Reading', 'Math') 0.98475584110674341 ``` 这是个非常高的相关性。但重要的是要注意,这并不能反映学生的数学和批判性阅读得分之间的关系强度。 数据由每个州的平均分数组成。但是各州不参加考试 - 而是学生。表中的数据通过将每个州的所有学生聚集为(这个州里面的两个变量的均值处的)单个点而创建。但并不是所有州的学生都会在这个位置,因为学生的表现各不相同。如果你为每个学生绘制一个点,而不是每个州一个点,那么在上图中的每个点周围都会有一圈云状的点。整体画面会更模糊。学生的数学和批判性阅读得分之间的相关性,将低于基于州均值计算的数值。 基于聚合和均值的相关性被称为生态相关性,并且经常用于报告。正如我们刚刚所看到的,他们必须谨慎解读。 ### 严重还是开玩笑? 2012 年,在著名的《新英格兰医学杂志》(New England Journal of Medicine)上发表的一篇论文,研究了一组国家巧克力消费与的诺贝尔奖之间的关系。《科学美国人》(Scientific American)严肃地做出回应,而其他人更加轻松。 欢迎您自行决定!下面的图表应该让你有兴趣去看看。 ## 回归直线 相关系数`r`并不只是测量散点图中的点聚集在一条直线上的程度。 它也有助于确定点聚集的直线。 在这一节中,我们将追溯高尔顿和皮尔逊发现这条直线的路线。 高尔顿的父母及其成年子女身高的数据显示出线性关系。 当我们基于双亲身高的子女身高的预测大致沿着直线时,就证实了线性。 ```py galton = Table.read_table('galton.csv') heights = Table().with_columns( 'MidParent', galton.column('midparentHeight'), 'Child', galton.column('childHeight') ) def predict_child(mpht): """Return a prediction of the height of a child whose parents have a midparent height of mpht. The prediction is the average height of the children whose midparent height is in the range mpht plus or minus 0.5 inches. """ close_points = heights.where('MidParent', are.between(mpht-0.5, mpht + 0.5)) return close_points.column('Child').mean() heights_with_predictions = heights.with_column( 'Prediction', heights.apply(predict_child, 'MidParent') ) heights_with_predictions.scatter('MidParent') ``` ### 标准单位下的度量 让我们看看,我们是否能找到一个方法来确定这条线。 首先,注意到线性关联不依赖于度量单位 - 我们也可以用标准单位来衡量这两个变量。 ```py def standard_units(xyz): "Convert any array of numbers to standard units." return (xyz - np.mean(xyz))/np.std(xyz) heights_SU = Table().with_columns( 'MidParent SU', standard_units(heights.column('MidParent')), 'Child SU', standard_units(heights.column('Child')) ) heights_SU ``` | MidParent SU | Child SU | | --- | --- | | 3.45465 | 1.80416 | | 3.45465 | 0.686005 | | 3.45465 | 0.630097 | | 3.45465 | 0.630097 | | 2.47209 | 1.88802 | | 2.47209 | 1.60848 | | 2.47209 | -0.348285 | | 2.47209 | -0.348285 | | 1.58389 | 1.18917 | | 1.58389 | 0.350559 | (省略了 924 行) 在这个刻度上,我们可以像以前一样精确地计算我们的预测。 但是首先我们必须弄清楚,如何将“接近”的点的旧定义转换为新的刻度上的一个值。 我们曾经说过,如果双亲高度在 0.5 英寸之内,它们就是“接近”的。 由于标准单位以标准差为单位测量距离,所以我们必须计算出,0.5 英寸是多少个双亲身高的标准差。 双亲身高的标准差约为 1.8 英寸。 所以 0.5 英寸约为 0.28 个标准差。 ```py sd_midparent = np.std(heights.column(0)) sd_midparent 1.8014050969207571 0.5/sd_midparent 0.27756111096536701 ``` 现在我们准备修改我们的预测函数,来预测标准单位。 所有改变的是,我们正在使用标准单位的值的表格,并定义如上所述的“接近”。 ```py def predict_child_su(mpht_su): """Return a prediction of the height (in standard units) of a child whose parents have a midparent height of mpht_su in standard units. """ close = 0.5/sd_midparent close_points = heights_SU.where('MidParent SU', are.between(mpht_su-close, mpht_su + close)) return close_points.column('Child SU').mean() heights_with_su_predictions = heights_SU.with_column( 'Prediction SU', heights_SU.apply(predict_child_su, 'MidParent SU') ) heights_with_su_predictions.scatter('MidParent SU') ``` 这个绘图看起来就像在原始刻度上绘图。 只改变了轴上的数字。 这证实了我们可以通过在标准单位下工作,来理解预测过程。 ### 确定标准单位下的直线 高尔顿的散点图形状是个橄榄球 - 就是说,像橄榄球一样大致椭圆形。不是所有的散点图都是橄榄形的,甚至那些线性关联的也不都是。但在这一节中,我们假装我们是高尔顿,只能处理橄榄形的散点图。在下一节中,我们将把我们的分析推广到其他形状的绘图。 这里是一个橄榄形散点图,两个变量以标准单位测量。 45 度线显示为红色。 但是 45 度线不是经过垂直条形的中心的线。您可以看到在下图中,1.5 个标准单位的垂直线显示为黑色。蓝线附近的散点图上的点的高度都大致在 -2 到 3 的范围内。红线太高,无法命中中心。 所以 45 度线不是“均值图”。该线是下面显示的绿线。 两条线都经过原点`(0,0)`。绿线穿过垂直条形的中心(至少大概),比红色的 45 度线平坦。 45 度线的斜率为 1。所以绿色的“均值图”直线的斜率是正值但小于 1。 这可能是什么值呢?你猜对了 - 这是`r`。 ### 标准单位下的回归直线 绿色的“均值图”线被称为回归直线,我们将很快解释原因。 但首先,让我们模拟一些`r`值不同的橄榄形散点图,看看直线是如何变化的。 在每种情况中,绘制红色 45 度线作比较。 执行模拟的函数为`regression_line`,并以`r`为参数。 ```py regression_line(0.95) ``` ```py regression_line(0.6) ``` 当`r`接近于 1 时,散点图,45 度线和回归线都非常接近。 但是对于`r`较低值来说,回归线显然更平坦。 ### 回归效应 就预测而言,这意味着,对于双亲身高为 1.5 个标准单位的家长来说,我们对女子身高的预测要稍低于 1.5 个标准单位。如果双亲高度是 2 个标准单位,我们对子女身高的预测,会比 2 个标准单位少一些。 换句话说,我们预测,子女会比父母更接近均值。 弗朗西斯·高尔顿爵士就不高兴了。他一直希望,特别高的父母会有特别高的子女。然而,数据是清楚的,高尔顿意识到,高个子父母通常拥有并不是特别高的子女。高尔顿沮丧地将这种现象称为“回归平庸”。 高尔顿还注意到,特别矮的父母通常拥有相对于他们这一代高一些的子女。一般来说,一个变量的平均值远远低于另一个变量的平均值。这被称为回归效应。 ### 回归直线的方程 在回归中,我们使用一个变量(我们称`x`)的值来预测另一个变量的值(我们称之为`y`)。 当变量`x`和`y`以标准单位测量时,基于`x`预测`y`的回归线斜率为`r`并通过原点。 因此,回归线的方程可写为: ![](http://latex.codecogs.com/gif.latex?%5Cmbox%7Bestimate%20of%20%7Dy%20%7E%3D%7E%20r%20%5Ccdot%20x%20%7E%7E%7E%20%5Cmbox%7Bwhen%20both%20variables%20are%20measured%20in%20standard%20units%7D) 在数据的原始单位下,就变成了: ![](http://latex.codecogs.com/gif.latex?%5Cfrac%7B%5Cmbox%7Bestimate%20of%7D%7Ey%20%7E-%7E%5Cmbox%7Baverage%20of%7D%7Ey%7D%7B%5Cmbox%7BSD%20of%7D%7Ey%7D%20%7E%3D%7E%20r%20%5Ctimes%20%5Cfrac%7B%5Cmbox%7Bthe%20given%7D%7Ex%20%7E-%7E%5Cmbox%7Baverage%20of%7D%7Ex%7D%7B%5Cmbox%7BSD%20of%7D%7Ex%7D) 原始单位的回归线的斜率和截距可以从上图中导出。 ![](http://latex.codecogs.com/gif.latex?%5Cmathbf%7B%5Cmbox%7Bslope%20of%20the%20regression%20line%7D%7D%20%7E%3D%7E%20r%20%5Ccdot%20%5Cfrac%7B%5Cmbox%7BSD%20of%20%7Dy%7D%7B%5Cmbox%7BSD%20of%20%7Dx%7D) ![](http://latex.codecogs.com/gif.latex?%5Cmathbf%7B%5Cmbox%7Bintercept%20of%20the%20regression%20line%7D%7D%20%7E%3D%7E%20%5Cmbox%7Baverage%20of%20%7Dy%20%7E-%7E%20%5Cmbox%7Bslope%7D%20%5Ccdot%20%5Cmbox%7Baverage%20of%20%7Dx) 下面的三个函数计算相关性,斜率和截距。 它们都有三个参数:表的名称,包含`x`的列的标签以及包含`y`的列的标签。 ```py def correlation(t, label_x, label_y): return np.mean(standard_units(t.column(label_x))*standard_units(t.column(label_y))) def slope(t, label_x, label_y): r = correlation(t, label_x, label_y) return r*np.std(t.column(label_y))/np.std(t.column(label_x)) def intercept(t, label_x, label_y): return np.mean(t.column(label_y)) - slope(t, label_x, label_y)*np.mean(t.column(label_x)) ``` ### 回归直线和高尔顿的数据 双亲身高和子女身高之间的相关性是 0.32: ```py galton_r = correlation(heights, 'MidParent', 'Child') galton_r 0.32094989606395924 ``` 我们也可以找到回归直线的方程,来基于双亲身高预测子女身高: ```py galton_slope = slope(heights, 'MidParent', 'Child') galton_intercept = intercept(heights, 'MidParent', 'Child') galton_slope, galton_intercept (0.63736089696947895, 22.636240549589751) ``` 回归直线的方程是: ![](http://latex.codecogs.com/gif.latex?%5Cmbox%7Bestimate%20of%20child%27s%20height%7D%20%7E%3D%7E%200.64%20%5Ccdot%20%5Cmbox%7Bmidparent%20height%7D%20%7E+%7E%2022.64) 这也成为回归方程。回归方程的主要用途是根据`x`预测`y`。 例如,对于 70.48 英寸的双亲身高,回归直线预测,子女身高为 67.56 英寸。 ```py galton_slope*70.48 + galton_intercept 67.557436567998622 ``` 我们最初的预测,通过计算双亲身高接近 70.48 的所有子女的平均身高来完成,这个预测非常接近:67.63 英寸,而回归线的预测是 67.55 英寸。 ```py heights_with_predictions.where('MidParent', are.equal_to(70.48)).show(3) ``` | MidParent | Child | Prediction | | --- | --- | --- | | 70.48 | 74 | 67.6342 | | 70.48 | 70 | 67.6342 | | 70.48 | 68 | 67.6342 | (省略了 5 行) 这里是高尔顿的表格的所有行,我们的原始预测,以及子女身高的回归预测。 ```py heights_with_predictions = heights_with_predictions.with_column( 'Regression Prediction', galton_slope*heights.column('MidParent') + galton_intercept ) heights_with_predictions ``` | MidParent | Child | Prediction | Regression Prediction | | --- | --- | --- | --- | | 75.43 | 73.2 | 70.1 | 70.7124 | | 75.43 | 69.2 | 70.1 | 70.7124 | | 75.43 | 69 | 70.1 | 70.7124 | | 75.43 | 69 | 70.1 | 70.7124 | | 73.66 | 73.5 | 70.4158 | 69.5842 | | 73.66 | 72.5 | 70.4158 | 69.5842 | | 73.66 | 65.5 | 70.4158 | 69.5842 | | 73.66 | 65.5 | 70.4158 | 69.5842 | | 72.06 | 71 | 68.5025 | 68.5645 | | 72.06 | 68 | 68.5025 | 68.5645 | (省略了 924 行) ```py heights_with_predictions.scatter('MidParent') ``` 灰色圆点显示回归预测,全部在回归线上。 注意这条线与均值的金色图非常接近。 对于这些数据,回归线很好地逼近垂直条形的中心。