使用说明 1. 每一节标题就是演示文稿里的页标题,括号里是建议时长;总计约 120 分钟。 2. 稿子按口语写,直接念即可。【停】表示停顿一下让同学消化,【互动】表示请同学先回答再往下讲,【板书】表示建议写在黑板上。 3. 稿子里的数字(相关系数、R 方、VIF 等)来自讲者自己的分析结果,课前请用 classdata-1.RData 重新跑一遍核对。 4. 想放慢节奏时,多给【互动】留时间;想压缩时,可以略去“补充说明”段落。

板块 页 时长
开场与背景 开场、1–2 13 分钟
题目、数据、脉络 3–5 16 分钟
响应变量与探索 6–10 28 分钟
多变量可视化 11–13 17 分钟
建模与选模 14–17 23 分钟
诊断与结论 18–21 20 分钟
收尾答疑 结束 3 分钟

开场(2 分钟)

同学们好。今天我们用两个小时,把 Assignment 4 完整地走一遍。我知道有些同学看到题目,第一反应是:这是个什么背景?数据里这些变量是什么意思?图要画哪些?回归又怎么和图连起来?所以我今天不会只讲“怎么做”,而是从头讲:这个作业为什么会存在,它在问什么,每一步为什么要这样做,做完之后怎么把结论写出来。

先提醒两件事。第一,我会用我自己做的一套分析来示范,目的是让你们理解方法和思路。你们的作业里,响应变量怎么定,要不要变换,选哪个模型,结论怎么写,都需要你们自己做判断,并且写出理由。不要照搬我的选择,也不要和同学共用结构、文字。第二,今天讲得慢,听不懂的地方随时打断我,我们宁可少讲一页,也要让每一页都讲明白。

1. 背景:什么是“红线划定”(6 分钟)

我们先不看数据,先讲背景。作业里有个词叫 redlining,中文常翻译成“红线划定”。这是什么意思呢?

想象一家银行或者保险公司,拿出一张城市地图,把一些社区用红笔圈起来,标注“这些地方我们不做生意”,或者“在这里做生意要有特别高的门槛”。被圈起来的社区,常常是少数族裔居民比例高、收入比较低的地方。这就是红线划定。这个名字就是从那个“红笔圈地图”的动作来的。

【停】

为什么这件事重要?因为保险是一个基础设施。你想买房,银行要求你买房屋保险;你买不到保险,就贷不到款;贷不到款,房子就卖不出去、修不起来;房子越来越破,社区就越来越衰败,到最后真的变成“高风险区域”。所以红线划定有一个恶性循环:先因为种族被拒绝,结果社区真的变差了,之后保险公司又说“你看,这里确实风险高”。

保险公司当然不会承认自己因为种族而拒保。他们的说法是:我们只是按风险办事,火灾多的地方、盗窃多的地方、老房子多的地方,理赔风险高,所以保费高、承保严,这是正常的商业判断,和种族无关。

那么问题就来了:谁对谁错?这不能靠争论,要靠数据。美国民权委员会就是这么想的:他们收集数据,然后问一个统计问题——当我们把火灾、盗窃、房龄这些“合理的风险因素”都考虑进去之后,少数族裔比例还会不会对保险可得性有额外的影响?如果会,那就说明保险公司的“只看风险”这个说法站不住;如果不会,那保险公司的辩护就有道理。

这个“把别的因素考虑进去之后”,统计上就叫“控制(control for)”。后面你们会看到,整份作业几乎每一步都围绕着“控制”这件事展开。请大家记住这个核心:不是问“少数族裔多的地方保险是不是更难买”,这个问题的答案几乎肯定是是;而是问“在风险相同的社区里,是不是仍然更难买”。

【板书】写下:红线划定 = 与风险无关、与种族有关的区别对待。统计问题 = 控制风险因素后,race 还有没有效应。

2. 背景:两个保险市场与这份数据的来历(5 分钟)

接下来讲数据是怎么来的,因为后面所有变量的定义都依赖这一页。

美国的保险市场可以粗略地分成两块。第一块叫自愿市场,就是普通的保险公司,他们自己决定要不要给你保险,要不要给你续保。第二块叫非自愿市场,在这个作业里指的是 FAIR 计划。FAIR 计划是一种兜底安排:当你被普通保险公司拒绝之后,你可以去 FAIR 计划买保险,所以它又叫“最后的选择”。一个社区里 FAIR 计划的保单特别多,通常意味着这里的居民在自愿市场被大量拒绝了。

所以这里有两个互补的信号:自愿市场里“新签加续保减去取消和不续保”是多少,这是一个信号;FAIR 计划里有多少保单,是另一个信号。这两个都在反映“保险好不好买”,只是方向相反。

数据由美国民权委员会收集,覆盖 1977 年 12 月到 1978 年 2 月,共 47 个邮编社区。除了保险活动数据之外,芝加哥警察局提供了盗窃数据,消防局提供了火灾数据。这里有个细节很有意思:风险数据来自 1975 年,而保险数据来自 1977 到 1978 年,中间差了大约三年。为什么?因为保险公司自己声称,他们在定价时用的是滞后三年的犯罪数据。所以委员会为了公平,也用三年前的风险数据来“控制”,这样才算在用保险公司自己承认的标准去比较。最后,人口普查局提供种族构成、收入和房龄。

好,背景讲完了,大家现在应该清楚:我们拿到的是 47 个社区的横截面数据,要回答一个“控制之后”的问题。下面进入题目本身。

3. 题目在问什么(5 分钟)

我们回到作业要求。先说规则,因为每年都有同学栽在规则上。

这份作业占总成绩百分之四十,满分五十分。截止时间是 2026 年 11 月 8 日午夜,澳大利亚东部时间。不接受迟交,没有商量。必须附上签名的 RSFAS 封面,没有封面会有麻烦。篇幅是六页单面,或者三页双面,加封面。

我要特别强调篇幅。这是图形数据分析的作业,图要占版面,文字也要占版面。六页纸要放进去:背景、探索、模型、诊断、结论。你们一定会遇到“图太多放不下”的情况。我的建议是:每放一张图之前,先问自己这张图要说明什么;如果说不出来,就不放。后面我还会专门讲怎么做取舍。

再看研究问题。题目的目标是:在控制 fire 和 theft 这类因素之后,研究种族构成对承保行为的影响。注意,这里写的是“承保行为”,也就是说我们要把保险可得性当作要解释的结果,race 是主要的解释变量,fire、theft 这些是控制变量。

评分细则我这里没有,请大家以课程网站发布的为准。我只能从题目判断:作业会看你有没有从图形出发、有没有把控制变量的思想用起来、模型选择有没有理由、诊断有没有做、结论有没有和证据对应。

4. 数据与变量(8 分钟)

我们来逐个看变量,请对着表来听。

第一列 zip,邮政编码。这 47 个观测,每个观测就是一个邮编区域。它只是个标签,不是一个可以直接放进回归的“分类变量”,后面我会解释为什么。

fire 是火灾数,单位是每 1000 户住房中的火灾数,1975 年。theft 是盗窃数,同样是每 1000 户,1975 年。这两个是“风险因素”。

age 是房龄,不过它不是年龄,而是“1939 年或更早建成的住房占的百分比”。数值越大,这个社区的房子越老。

income 是家庭收入中位数,单位大约是千美元。race 是少数族裔所占百分比,数值从很低到超过百分之八十。

最后是两个保险指标。volun 是自愿市场活动:新保单加续保,减去取消和不续保,再除以住房数,表示每 100 户的净活动量。注意它是“净”的,所以理论上可以为负,意味着取消的比新增的还多。invol 是 FAIR 计划保单加续保,每 100 户。它不会为负,但是有很多零。

【互动】我想请大家想一想:volun 和 invol 都在衡量保险好不好买,但方向相反——volun 大是好事,invol 大是坏事。如果我只用其中一个当作要解释的变量,会漏掉什么信息?请大家讨论一分钟。

【停】

好,我听到一些回答。一个常见的看法是:只用 invol,那些 invol 等于零的社区,我们不知道是因为自愿市场很好,还是因为连 FAIR 都没有人申请。只用 volun,两个 volun 一样的社区,FAIR 依赖可能差很多。这正是下面要讲的“响应变量怎么构造”的出发点。

下面看一眼最后一行 zip。我们做 dim(insure) 确认是 47 行 8 列,summary 看一下每个变量的范围。这是任何分析的第一步:先看数据长什么样,有没有明显的异常值、缺失值。

5. 整体分析脉络(3 分钟)

在进入细节之前,我给大家一张地图,因为很多同学做作业时会迷失在各种图和模型里,不知道自己走到哪了。

我把整个分析分成七步。第一步,明确目的,决定要解释的变量是什么。第二步,探索:单变量看分布,两两看关系,判断要不要变换。第三步,空间视角:这些邮编在地图上是什么分布。第四步,多变量可视化:symbol plot 和 coplot,在建模之前先用图看“控制之后”的样子。第五步,建模:全子集回归挑变量,检查共线性,比较候选模型,选一个最终模型。第六步,诊断:检查模型假设,尝试补救,用增变量图和偏残差图检查 race 这一项。第七步,写结论,并且诚实地写局限。

这个顺序的逻辑是:先看图,再建模,再回到图验证。图形分析课的精神就是“让图说话”,数字要有图的支撑。请大家做作业时都按这个顺序去走。

6. 响应变量的构造(9 分钟)

现在进入第一个真正需要你们自己决定的地方:响应变量。

课上老师强调过:做分析之前先问 purpose,也就是目的是什么,要解释的变量是谁。这份作业里有两个候选:volun 和 invol。我先讲我的思考过程,请大家记住这是“一种选择”,你们完全可以有不同的选择,只要有理由。

我先想用 invol。它直接反映有多少人被迫去 FAIR,看起来很对口。但是它有两个问题:第一,它有很多零,零表示这个社区没有 FAIR 保单,但我们不知道是因为大家都买得到保险,还是因为大家买不到保险也没去申请。第二,它只讲了故事的一半,没有说自愿市场有多活跃。

我再想用 volun。它也只讲一半:两个社区 volun 相同,一个 FAIR 依赖很高,一个几乎没有,这两个社区的保险处境完全不同,但 volun 看不出来。

所以我想把两个信息合起来:构造一个“自愿市场占比”,用 volun 除以 volun 加 invol。公式写在代码里,叫 rate。它的好处有两个:第一,好解释,接近 1 说明几乎所有保险都来自主流市场,容易买到;接近 0 说明几乎全靠 FAIR,很难买到。第二,它直接对应委员会关心的“主流市场和兜底市场的平衡”。

【板书】rate = volun / (volun + invol),越接近 1 越容易买到保险。

接下来看代码。第一行就是构造 rate。然后 summary 看一下范围。再看两张图:直方图和箱线图。大家看直方图,这个分布左偏很厉害,大部分社区集中在 1 附近,有一条一直拖到 0.3 左右的尾巴。这条尾巴里的社区,就是我们最担心被红线划定的地方。

这里要提醒两个风险。第一,volun 按定义可以为负,分母也可能为零或负,所以构造之前要检查。我们这份数据里,volun 最小是 0.5,分母恒为正,rate 最低约 0.31,其中有 15 个社区正好等于 1,它们的 invol 都是 0。第二,rate 被卡在 1 的上面,很多社区正好等于 1,这会带来“天花板效应”,后面模型诊断里会看到它的影响。

【互动】请大家想一想,如果你不用比例,还有哪些办法?比如只用 invol 但做某种处理,或者两个变量分别分析。每一种办法都要回答一个问题:它能不能反映“保险好不好买”的全貌?你们不需要和我选一样的,但需要把理由写进报告。

7. 单变量探索(4 分钟)

选好响应变量之后,第一件事是一个一个地看变量,也就是单变量探索。这一步经常被同学跳过,但它很有用,因为后面很多现象都能在这里找到“预兆”。

我们对 fire、age、income、race、rate 各画一个直方图。看什么?看三件事:分布是对称还是偏的,有没有离群点,取值集中在哪个范围。

fire 是右偏的,大部分社区的火灾数比较低,集中在二十以下,有少数社区高得多,接近四十。race 也是右偏:多数社区少数族裔比例不高,只有少数几个超过百分之八十。age 集中在较高的一端,中位数大约百分之六十三,说明芝加哥的房子整体偏老。income 大部分在八千到一万四千美元之间,有一个明显的高收入点,超过一万六千。rate 前面说了,左偏,大量集中在 0.85 以上。

【停】为什么要在这里花时间?因为偏斜意味着少数几个点可能对后面的回归影响很大;而 rate 的天花板,意味着后面残差图可能出现特殊形状。把它们先记在笔记里。写报告时,这一段可以非常简短,用两三句话概括,不用每个变量都展开。

8. 两两关系与共线性(7 分钟)

这一页是整份作业最重要的探索图之一:散点图矩阵,也叫 pairs plot。

先讲怎么读。矩阵里每一格,是行变量对列变量的散点图。我在下三角画了散点加一条红色的 lowess 曲线,在上三角直接写相关系数。

什么是 lowess?它是局部加权回归,你可以想象在每个 x 值附近,只拿离它近的一些点,拟合一条小直线,然后把这些小直线连起来,得到一条平滑曲线。好处是它不假设整体是直线,所以如果关系是弯的,曲线就是弯的;如果关系是直的,曲线就是直的。用它来判断“线性够不够”非常方便。

接下来看重点格子。第一,rate 对 race:明显向下的趋势,相关系数大约负 0.75。这在没有控制任何东西的时候就看到了,说明少数族裔比例高的社区,自愿市场占比低。第二,rate 对 income,正相关,大约 0.7,收入高的社区更容易买到保险。第三,race 对 income,负相关,大约负 0.7。这一格非常关键。大家想一想它意味着什么?

【互动】race 和 income 强相关,会给我们的分析带来什么麻烦?

【停】对,麻烦在于:如果两个解释变量本身高度相关,回归就很难分清是谁在起作用。income 可能在“替”race 说话,或者反过来。这叫共线性。后面我们会用 VIF 和主成分分析去量化它。

第四个观察:rate 对 fire,大约负 0.69,火灾多的社区,自愿市场占比低,这符合“按风险承保”的逻辑。但是注意,它不等于没有红线划定,因为我们还没有把 race 控制住。最后,theft 对 rate 几乎没有相关,大约负 0.08。这一点后面会再出现,因为在回归里 theft 会出现一个“奇怪”的符号。

9. 变换探索(5 分钟)

看完分布和关系,我们要回答一个问题:要不要做变换?

变换的目的是让关系更接近线性、让分布更对称、让方差更稳定。常见做法是:右偏的变量取对数或者开平方;比例类的变量可以考虑 logit。

我们怎么判断变换有没有用?看图,而不是凭感觉。代码里我对 fire、theft、race 分别画了两种图:原始尺度下对 rate 的散点加 lowess,以及取对数之后对 rate 的散点加 lowess。注意我取的是对数加 1,是为了避免零值取对数出问题。然后我们比较两种图:曲线是不是更直了,点的分布是不是更均匀了,相关系数是不是变大了。

我的结果是:没有明显改善。对响应变量取对数,和五个预测变量分别比较,也没有稳定的改进。所以我的决定是:保持原尺度。

这里想强调:变换探索的结论是“有没有用”都要写进报告,不要只写“我做了变换”。没有改善而保留原样,是一个合理的、也是有证据的结论。至于你们自己的数据结果,请自己判断,也许你们的构造方式下会有不同的发现。

10. 空间视角:邮编与地图(3 分钟)

这一页讲邮编怎么用。作业里附了一张芝加哥邮编地图。

代码里,我按 rate 从低到高排序,看最低的几个社区;然后数一数 rate 等于 1 的有几个。把这几个邮编对着地图看:rate 最低的社区,比如 60612、60653、60624、60621,集中在市区中部,race 超过百分之八十五,fire 偏高。rate 等于 1 的十五个社区,分布在北部和南部,race 低于百分之十一,收入高于一万二千美元。

这说明,种族和保险可得性的关系不是随机散落的,而是沿着清晰的地理边界分布。这是一条很好的补充证据,也让读报告的人更有直观感受。

但是我最后没有把 zip 放进回归。理由有两个:第一,它有 47 个水平,每个水平只有一个观测,要放就得 46 个哑变量,没有意义;第二,邮编所承载的空间信息,已经被 race、fire、income 体现了。注意,这是一个“理由”,你们写报告时也要给出你们不使用或者使用 zip 的理由。

11. Symbol plot:一图五变量(6 分钟)

探索结束,我们进入多变量可视化。第一个工具是 symbol plot,中文可以叫符号图。

它的想法很简单:一张二维散点图,只有两个坐标轴,但是我们可以让点的大小、颜色、形状也携带信息。这里横轴是 race,纵轴是 rate,点的大小对应 fire,颜色表示收入高于还是低于中位数,形状表示房龄高于还是低于中位数。这样一张图同时看了五个变量。

看代码:pch 控制形状,col 控制颜色,cex 控制大小。我还加了一条 lowess 曲线和一条中位数虚线。

现在看图。第一,整体趋势向下,rate 随 race 增大而下降。第二,红色点,也就是低收入社区,集中在右下角,也就是高 race、低 rate 的区域,而且点比较大,说明 fire 也高。这就是 race、income、fire 三者纠缠在一起的样子。第三,也是最重要的:即使只看小点,也就是火灾风险中等的社区,负斜率仍然存在。这意味着 race 的效应不是单纯由火灾造成的。第四,三角和圆没有明显分开,说明房龄在这张图上没有形成清楚的模式。

【停】这张图有一个局限:它是“看起来”如此,没有数字。所以它的作用是引出下一步:用 coplot 把“控制”这件事做得更严格。

12. Coplot:控制 fire(6 分钟)

coplot 是这份作业最能体现“控制”的图,大家务必看懂。

先讲怎么构造。coplot 的全称是 conditioning plot,条件图。我们选一个条件变量,这里是 fire,把它的取值范围切成四段,而且相邻的段有重叠,就像滑动窗口一样。每一段对应一个面板,面板里只画属于这一段的社区,也就是说,在每个面板里,fire 近似是常数。然后在每个面板里画 rate 对 race。这样,面板内部看到的关系,就是“在 fire 大致相同的社区里,race 和 rate 的关系”。这正是控制 fire 的图形版本。

看代码:coplot(rate ~ race | fire, number = 4, overlap = 0.3)。竖线后面是条件变量。每个面板里我加了 lowess 曲线和一条总体中位数的虚线,方便比较。

读图的顺序:看面板排列,左下到右上,fire 越来越高。下面两个面板,是低 fire 的社区,曲线几乎是平的,而且位于中位数线之上。这说明在低风险社区里,rate 普遍很高,race 的影响很弱。这符合保险公司的说法:低风险地方,大家都买得到保险。

重点在右上角那一格,也就是 fire 最高的那一段。这里曲线明显向下:随着 race 增大,rate 急剧下降。大家想一想,这些社区的火灾风险都差不多高,按保险公司的说法,它们应该被同等对待。但是图里显示,其中少数族裔比例高的社区,自愿市场占比低得多。这个现象不能只用 fire 解释,它和红线划定的假设一致。

13. Coplot:控制 income(5 分钟)

同样的做法,换成按 income 条件化。

最低收入的面板里,race 从低到高,rate 从大约 0.9 一直降到大约 0.35,趋势非常清晰。中间收入的面板,曲线不是单调的,数据也比较散,没有干净的方向。收入越高的面板,rate 整体越高,race 的影响越来越弱。到最高收入的面板,几乎所有点都在 0.85 以上,曲线基本是平的。但是要注意,这个面板里包含高收入离群点 60611,它可能拉动曲线,写报告时应当提一句。

把两张 coplot 放在一起,我们得到一个有意思的结论:race 的影响在低收入社区和高风险社区最明显,而在高收入、低风险的社区里不明显。也就是说,race 和 income、fire 是联合起作用的,而不是各自独立。这给后面建模提了一个醒:简单的加法模型可能只抓到了一部分。

14. 全子集回归(6 分钟)

图看够了,开始建模。第一个问题:五个候选变量 fire、theft、age、income、race,到底要放哪几个?

最直接的办法是全子集回归。五个变量一共有 31 个非空子集,我们把所有子集都拟合一遍,按模型大小分组,每个大小只保留最好的两个。代码里用 leaps 包的 regsubsets。nbest = 2 就是每个大小保留两个最好的。

看结果表。每一行是一个模型,前面五列是 0 或 1,表示变量有没有被选进去,后面是 R 方和调整后 R 方。

大小为 1:race 最好,R 方约 0.56;income 次之,约 0.49。这告诉我们:单个变量里 race 解释力最强,但是 income 也不差,这正是前面说的 race 和 income 共线。

大小为 2:fire 加 race 最好,R 方约 0.65,改善明显。大小为 3:fire、theft、race,R 方约 0.75。大小为 4:fire、theft、age、race,调整后 R 方约 0.76,是所有模型里最高的。大小为 5:五个变量全放,R 方没有再提高,调整后 R 方反而下降到约 0.75。

【互动】为什么五个变量的 R 方没有比四个变量更高,调整后 R 方还下降了?

【停】R 方永远不会因为加变量而下降,所以这里的现象其实是:加入 income 带来的提高几乎为零,而调整后 R 方对多加的变量有惩罚,所以反而降了。总结一句:看调整后 R 方,而不是只看 R 方。

15. 共线性:PCA 与 VIF(5 分钟)

前面我们多次提到 race 和 income 相关,现在把它量化。我用两个工具。

第一个是主成分分析,也就是 PCA。做法是把五个预测变量标准化,然后找出方差最大的方向。如果五个变量彼此独立,每个主成分各解释五分之一的方差;如果它们高度相关,前几个主成分就会解释绝大部分方差。我们的结果是:前两个主成分解释约百分之七十五,前三个约百分之九十。说明五个变量不是独立的,但也远没有挤成一条线,属于中等程度的共线性。

第二个是 VIF,方差膨胀因子。它的算法是:把某一个变量对其他所有预测变量做回归,得到 R 方,然后算一除以一减 R 方。如果这个变量几乎能被其他变量完全预测,R 方接近 1,VIF 就会非常大。经验上,大于 5 或者 10 才算严重。我们的结果是:income 约 3.1,fire 约 2.5,race 约 2.3,theft 约 1.7,age 约 1.6,都小于 4。

结论:race 和 income 确实有重叠,income 的 VIF 在五个里最高,但是还没到需要处理的程度。这个结论要和前面的全子集结果对上:当 race 已经在模型里,income 几乎没有额外贡献,正是共线性的体现。

16. 候选模型比较(5 分钟)

从全子集的结果里,我挑了三个候选。模型 A:fire、theft、age、race,调整后 R 方最高,约 0.759。模型 B:fire、theft、race,调整后 R 方约 0.737。模型 C:五个变量全放进去,调整后 R 方约 0.753。

代码里用 lm 分别拟合,然后用 summary 把 R 方和调整后 R 方并排看,再看模型 B 的系数表。

判断一个变量“显著”,课上教的标准是 t 值的绝对值大于临界值,大约 2,对应 p 小于 0.05。我们看三个模型:fire、theft、race 在三个模型里 t 值都远大于 2,符号稳定。这叫稳健,也就是说无论你放不放别的变量,它们都站得住。

age 的情况不一样。在模型 A 里它刚好显著,t 值约负 2.2,p 约 0.03;但在模型 C 里加了 income 之后,t 值变成约负 1.9,p 约 0.065,不显著了。这说明 age 的显著性不稳定,很可能是在帮 income 分担一部分信息。income 本身在模型 C 里 t 值接近 0,完全没有贡献。

【互动】如果你是我,在 A 和 B 之间,你选哪一个?先想理由,一分钟后回答。

【停】

两种答案都可以。关键是理由要写清楚。我自己的理由在下一页讲。

17. 最终模型与解释(6 分钟)

我选的是模型 B。理由有两条。

第一,显著性:B 里面三个变量都很显著,没有多余的、不稳定的项。第二,简约:从 A 去掉 age,调整后 R 方只下降大约 0.022,这个损失很小,而样本只有 47 个,我们没有太多“预算”可以花在一个只是勉强显著、又不稳定的变量上。

最终的模型写成:rate 约等于一个常数,减去 0.013 乘 fire,加上 0.003 乘 theft,减去 0.003 乘 race。

下面是最重要的:怎么解释系数。解释系数要说完整的话,包括单位和“保持其他变量不变”。

fire 的系数是负 0.013:在 theft 和 race 保持不变时,每 1000 户多一起火灾,自愿市场占比平均下降约 0.013。这符合直觉。

race 的系数是负 0.003:在 fire 和 theft 保持不变时,少数族裔比例每多一个百分点,自愿市场占比平均下降约 0.003。这个数看起来小,但是 race 的范围是 0 到 100 左右,所以从最低到最高会累计下降相当大。更重要的是,这个负效应是在控制 fire 和 theft 之后仍然存在的,保险公司的“按风险办事”解释不了它。这就是支持红线划定的统计证据。

theft 的系数是正的 0.003,这需要特别小心。它的边际相关几乎是零,在回归里却变成了显著的正系数。这不能解释为“盗窃越多越容易买到保险”,更合理的解释是抑制效应:theft 和 fire 相关,大约 0.56,当 fire 已经在模型里,theft 里与 fire 重叠的部分被扣掉,剩下的部分和 rate 的关系就变了符号。在报告里写一句这个解释,会让读者知道你没有被这个符号骗到。

18. 模型诊断(6 分钟)

选好模型之后,必须回头检验它的假设,不能只看系数表。线性回归有几条核心假设:线性、方差齐性、正态、没有过度影响的点。我们用四张图来检查。

第一张,残差对拟合值,检查线性和方差齐性。理想情况是点随机散布在零线周围,lowess 曲线是平的。我们的曲线先上升后下降,有弯曲,说明线性有轻微问题。原因我猜是 rate 被卡在 1,高拟合值的社区上面没有“空间”,所以残差只能向下。

第二张,残差绝对值对拟合值,专门检查方差是不是随拟合值变化。理想情况曲线是平的,我们的曲线随拟合值上升而下降,也就是说,拟合值低的社区,也就是高风险社区,残差波动更大。这叫异方差。

第三张,QQ 图,检查残差是否近似正态。中间部分贴着参考线,但是两端有偏离,说明尾部比正态分布更厚一点,是轻度的非正态。

第四张,杠杆值。杠杆值衡量一个点的 x 值有多极端,它的平均数是参数个数除以样本量,常用的警戒线是平均数的两倍,在我们的模型里大约 0.17。看图,60607 的杠杆约 0.62,远远超出。注意要找对是哪个社区:杠杆最高的是 60607(fire 接近 40,theft 高达 147)。60612 是 rate 最低的社区,杠杆是第二高,约 0.2,刚过警戒线。这两个社区各方面都很极端,它会对拟合有较大影响。

写报告时,每张诊断图都要有一句“发现了什么问题”,而不是把图放在那里。同时要诚实:我们的模型有一些假设问题,下一页看看能不能补救。

19. 尝试变换:logit(rate)(3 分钟)

针对诊断里的问题,我尝试了一个补救:对响应变量做 logit 变换,对 fire 和 race 取对数。logit 的好处是把 0 到 1 之间的比例拉到整条实数轴上,可以缓解天花板效应。

不过 rate 有些值正好等于 1,logit 会变成无穷大,所以必须先做截断处理,把靠近 0 和 1 的值拉进来一点。代码里我取了 0.01,这只是一个示范,你们要自己决定怎么处理,并且在报告里说明。

结果:变换之后,残差对拟合值的曲线变得更平,QQ 图的尾部也更贴近参考线,诊断确实改善了。

但是,我最终没有采用它,而是保留了原模型。理由有两条。第一,样本只有 47,很难判断这种改善是真实的,还是过拟合带来的。第二,变换后的模型,系数是“对 logit(rate) 的影响”,而且预测变量还取了对数,很难向做政策的人解释。这是一个取舍:精确度和可解释性之间,我选了可解释性。这个取舍的理由,就是报告里体现思考的地方。

20. 增变量图与偏残差图(6 分钟)

最后两张图,专门针对我们最关心的那个变量:race。

先讲增变量图,英文 added variable plot。它想回答:“race 在模型里已经有 fire 和 theft 的情况下,还有没有额外的贡献?”做法是三步。第一步,用 fire 和 theft 去回归 rate,取残差,这是 rate 中不能被 fire 和 theft 解释的部分。第二步,用 fire 和 theft 去回归 race,取残差,这是 race 中不能被 fire 和 theft 解释的部分。第三步,把两个残差画成散点图。

这张图的妙处在于:它把 fire 和 theft 的影响从两边都“扣掉”了,剩下的就是 race 的净贡献。图里的斜率恰好等于回归里 race 的系数。我们的图里有清晰的负线性趋势,说明 race 在控制 fire 和 theft 之后仍然有显著的解释力。

再讲偏残差图。它回答另一个问题:race 的效应是不是线性的。偏残差等于模型残差加上 race 的系数乘 race,我们把它对 race 作图,再叠一条回归直线和一条 lowess 曲线。如果两条线贴合,线性假设就合理;如果 lowess 明显弯离直线,说明需要非线性项。

我们的结果:整体是负线性趋势,但是在 race 超过百分之六十之后,lowess 比直线更陡。这说明线性模型可能低估了高少数族裔比例社区里的效应。这一点不推翻结论,但要写进局限。

21. 结论与局限(5 分钟)

最后是总结,我们回到最开始的问题:控制了风险因素之后,race 还有没有影响?

我们的证据链是这样的:第一,探索阶段,pairs plot 里 race 和 rate 是最强的负相关。第二,symbol plot 和 coplot 里,在 fire 相同或者 income 相近的社区内,race 的负趋势依然存在,尤其在高 fire 和低收入的社区里很清楚。第三,回归里,控制 fire 和 theft 之后,race 的系数是负的,而且显著。第四,增变量图展示了这个净效应的形状。所以我们的结论是:图形和统计证据一致,支持存在红线划定。

但是结论里必须有局限,这是区分好报告和一般报告的地方。第一,这是观察性数据,我们只能说“与红线划定一致”,不能说“证明了因果”。第二,这是邮编层面的汇总数据,不能推断到个人,这是所谓的生态谬误。第三,样本只有 47 个,还有 60607 这样的高杠杆点,结果对个别点比较敏感。第四,模型的残差有异方差和天花板效应,race 的线性设定在高比例处也不够好。

写作上我再提醒三点。第一,每张图配一句“这张图说明了什么”。第二,在六页的限制下,把图当成预算来分配,删掉任何一张图如果结论不受影响,那就删。第三,不要贴代码,报告读者要的是结论和证据。

收尾与答疑(3 分钟)

我们回顾一下今天的路线:先弄清背景,红线划定在问什么;再明确响应变量;接着探索分布和关系,判断变换;然后用 symbol plot 和 coplot 做控制;再用全子集和共线性分析选模型;用诊断图检查假设;最后用增变量图和偏残差图聚焦 race,写出结论和局限。每一步都有一个你自己的决定,请你们自己动手,自己论证。

接下来是答疑时间。带着你们自己的图来问,比问“应该选什么”更有效。谢谢大家。