在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
本节书摘来自华章计算机《数据科学R语言实践:面向计算推理与问题求解的案例研究法》一书中的第2章,第2.4节,作者:[美] 德博拉·诺兰(Deborah Nolan) 邓肯·坦普·朗(Duncan Temple Lang) 更多章节内容可以访问云栖社区“华章计算机”公众号查看。 2.4 探索所有男选手的跑步时间现在我们已经完成了对公布在Cherry Blossom网站上表格数据的提取,可以开始研究年龄和跑步时间之间的关系了。典型地,我们首先以图形化的方式考查构建在散点图上的数据,其中散点图以跑步时间为y轴,年龄为x轴。下面我们调用plot()函数对男运动员构造这样的一张散点图。 这里我们使用一个轴范围参数ylim,以筛选掉诸如跑步时间为1.5分钟这类的参赛者。 图2-6 男选手的跑步时间对年龄的默认散点图。该图显示70 000名男选手的跑步时间对于年龄的一个简单散点图,图中导致了如此严重的重叠绘制,以致于数据的形状无法辨识 以上是该包中可用的4个函数名,通过阅读display.brewer.all()中的帮助信息可知,这是一个好的开始,因为这里列出了该包中所有可用的调色板。调用如下: 然后在Set3调色板中选择蓝色: 该颜色以十六进制格式存储,其中红色red为54,蓝色blue为27,绿色green为8F,它并没有包括α透明度,这意味着该颜色是不透明的。但是我们可以通过在Purples8的后面粘贴一个透明度值来生成该颜色的一个透明度版本: 我们将这个颜色作为散点图的绘制符号。 图2-7 修正后男选手的散点图。把图2-6中的绘制符号由圆圈变成了圆点,使用透明色,减少绘制符号的大小,并对年龄添加了少量的随机噪声。现在我们可以从图像中看到高密度区域包含大多数的参赛选手,并且跑步时间随着年龄的增长有轻微上升的趋势 图2-8中显示的结果和图2-7中的绘图在形状上非常相似,只是图2-8中多了一些小黑点,表明一些单独的离群点远离了主体点云。 图2-8 男选手的跑步时间对年龄的平滑散点图。该图提供了不同于图2-7的另一种散点图绘制方法,图2-7中使用了抖动和透明色来解决过度重叠的问题。这里不需要对年龄进行抖动,因为平滑操作本身通过将单个参赛者的(age, runtime)分散到邻近的小区域而潜在地实现了抖动操作。图中的高密度区域和之前的散点图有着非常相似的形状 这个新变量ageCat,是一个因子,它把年龄以10年为一间隔进行分组,另外75岁以上的选手组成一组。 可以看到,在图2-9中plot()函数创建了一系列的箱线图而不是散点图。该函数调用与之前生成图2-6的函数调用之间的区别在于所提供的公式不同。由于ageCat是一个因子,对于公式time~ageCat,默认生成的是一系列并排的箱线图,而每个关于跑步时间的箱线图都由年龄因子中的一个分组决定。图中我们观察到上四分位数比中值和下四分位数随着年龄增长的速度更快。在下一节中,我们设法更正式地总结年龄和跑步时间之间的这种关系。 图2-9 并排的男选手跑步时间相对年龄的箱线图。将男选手按年龄以10年为一间隔进行分组,箱线图按顺序显示了每组的四分位时间。所有的四分位值都随年龄的增长而增长,但是箱体随年龄的增长变得不对称,表示上四分位值比中四分位和下四分位值随年龄增长得更快 我们已经指定从lm()向lmAge的返回值,该返回对象包含有关run time对age的线性最小二乘法拟合的系数、预测值、残差以及其他相关信息。我们可以调用summary(),得到关于拟合的一个简单概要: 注意summary()函数不会产生标准的分位数、极端值,等等。这是因为我们已经向它传递了一个lm对象,即 类lm的summary方法提供了一组不同的概要统计工具集,它更适合拟合线性模型。 为了有助于进一步识别残差中的模式,我们用一条来自拟合残差的局部平均值的光滑曲线来增强该残差图形,也就是说,对某一特定的年龄,比如37岁,我们把那些年龄在37岁附近一个小邻域内选手的残差进行加权平均。这样的局部拟合曲线可以让我们更好地观察残差模式的偏离趋势。用loess()函数拟合该曲线如下: 注意loess()函数也接受一个公式对象来描述数据的拟合关系,这里我们想要的是resids关于age的拟合。由参数data提供的数据框中包含这两个变量;此外它还可以包含其他的变量,但是我们已经专门创建了这个数据框,使它只含有来自于ImAge的残差和cbMenSub中运动员的年龄。和Im()类似,loess()的返回值也是一个特殊对象,它包含被拟合的值和其他与数据拟合曲线有关的信息。 现在如果在数据向量中对以上的每一个年龄调用被预测的平均残差,即调用resid.lo.pr,我们就可以把曲线添加到平滑散列中: 可以从predict.loess()函数中得到这些预测值,该函数从一个拟合和一个数据框中提取loess对象,例如,拟合为resid.lo,数据框由loess拟合曲线中需要匹配的变量组成,在本例中就是age。也就是说,我们通过如下方法创建resid.lo.pr: 注意,我们调用的是predict(),而不是predict.loess()。predict()函数是一个包装器,它允许我们不依赖于拟合的形式去编写代码。该函数接受一个从拟合函数中返回的对象,比如从lm()或loess()函数中返回对象,具体调用哪个拟合函数取决于对象所属的类。也就是,predict()自身会调用相关的函数,即对于Im对象调用predict.lm(),对于loess对象调用predict.loess()。 图2-10 选手成绩关于年龄的简单线性拟合模型的残差图。这里显示的是一个平滑的残差散点图,表示的是15~80岁的男选手的跑步时间关于年龄的简单线性拟合模型的残差分布。在散点图上叠加了两条曲线,实线是y=0处的水平线,虚线是残差的局部平滑曲线 并对20~80岁之间的所有年龄做预测: 曲线显示如图2-11所示。 图2-11 跑步时间关于年龄的分段线性拟合和Loess曲线。这里我们以30、40、50、60岁为拐点分别绘制分段线性拟合曲线和来自loess()的拟合曲线,这些曲线彼此接近。然而对于50岁以上的参赛选手来说,图中的loess拟合曲线比分段线性拟合曲线显示的曲率更大 然后我们拟合这个参数模型: 现在对于50岁以下的选手,直线的斜率比我们最初简单的线性模型更平缓,而对于年龄超过50岁的选手,该模型表明其平均用时比整体平均用时慢了0.67分钟,而整体平均用时又比50岁以下选手的平均用时多0.56分钟。 现在我们已经有了这些变量,下面便可以创建模型 这个模型与仅带有参数age和over50的模型有类似的解释。也就是,系数over40是年龄在(30,40]和(40,50]之间斜率上的变化。采用以下方法,得到最小二乘法拟合模型: 这里我们在公式中使用“.”表示这个模型应该包含数据框中作为协变量的变量(除了runTime之外)。 注意,over60系数基本上为0,表明那些超过60岁的选手并不比他们50多岁的时候跑得慢多少。即年龄超过50岁的选手每增加一岁,跑步时间大概会增加0.404分钟,而10英里赛的所有选手每增加一岁,跑步时间大约平均增加0.66分钟。 然后调用predict()函数进行预测,向predict()函数传递lm对象,即带有拟合细节信息的lmPiecewise;以及用于产生预测的协变量,即overAgeDF。也就是,我们调用predict()如下: 我们绘制拟合的分段线性函数如下: 然后添加loess曲线: 两个拟合曲线显示于图2-11。我们看到它们彼此非常接近。最主要的差别是在超过70岁的年龄组别。我们没有在70岁处添加拐点,以至于我们的模型无法捕捉到数据在年龄超过70岁后的剧烈增长。我们也许需要考虑在模型中增加额外的拐点以观察是否可以改善拟合的性能。看起来我们似乎已经在建模平均成绩上取得了很大的进步,但是我们必须小心解释这些结果。例如,假设,很可能那些跑得慢的年轻选手会随着年龄的增长退出比赛,这样那些参赛年龄较大的选手就将成为跑得更快的选手,而这会让我们在跑步速度如何随年龄变化的估计上产生偏差。此外,这些数据是由参赛选手的14个横截面快照组成的,我们可以问问自己,参赛选手的组成是否会随着参赛时间阶段的不同而发生变化呢?这些问题将是随后两节的主题。 图2-12 逐年男选手参赛人数的曲线。该图表明1999~2012年,樱花10英里赛中男选手的参赛数量增加了一倍多 那么有没有可能2012年参赛者的年龄更大,因此比1999年同年龄段的选手跑得更慢呢?我们可以比较这两届比赛的年龄分布。 然后我们对这两个年龄集绘制叠加的密度曲线,操作如下: 注意第一次调用plot()绘图时,我们使用的是该函数缺省的水平和垂直坐标范围。当在第一个密度图中加入第二条密度曲线时,我们发现垂直轴没有大到能够包含第二条曲线的峰值。所以我们重绘了图形,指定ylim=c(0,0.05),以容纳2012年密度曲线中较高的峰值。我们也可以使用lattice包[5]中的densityplot()函数,该函数可以根据所绘制的密度曲线恰当地自动缩放轴的大小。尽管如此,可视化处理通常是一个迭代的过程。我们在绘图时对大多数参数使用缺省设置,一旦发现有趣的结构,就重新绘制图形,以调整图形的比例并添加其他的信息,例如,轴的标签、标题、图例、颜色、线的类型和粗细等。 图2-13 1999年和2012年男选手的年龄密度曲线。这两条密度曲线的形状相差很大。1999年的男选手的年龄分布模式宽阔且近乎平坦,在28~45岁之间大致呈均匀分布。相比之下,2012年的参赛选手更年轻,在30岁处有一个尖峰,呈右偏斜分布 从图2-14中我们看到两条曲线的形状相似,但是2012年的曲线高于1999年的曲线,表明在两组参赛选手之间存在着一致性差异。图2-15显示了这两条曲线在预计跑步时间上的这种差异。在50多岁时两者的差距最小到2分钟,从60多岁、70多岁到80多岁,差距逐渐从2.5分钟增加到8.5分钟。这里我们把比较所有14年数据中跑步时间和年龄之间关系的任务留作练习。 图2-14 1999年和2012年男选手成绩的loess曲线拟合。2012年男选手的“成绩-年龄”loess拟合曲线位于1999年曲线的上方。在多数年龄上这两条曲线之间相差大约5分钟,而在40多岁的后期到60多岁的前期两条曲线彼此相差2~3分钟。这两条曲线的形状相似 图2-15 Loess曲线差异。这条线显示了被预测的2012年和1999年男选手的跑步时间之间的差异 |
请发表评论