Hi,大家好,我是晨曦
今天这期推文我们依旧聚焦在机器学习,而我们这期的主角就来谈谈大家平时最常见、也是最能用到的模型——线性回归模型
那么,我们就开始吧
晨曦碎碎念系列传送门
首先,根据我们前面所掌握的知识,线性回归属于有监督学习中回归的范畴,主要用来解决的是因变量为连续型变量的情况,这个时候我们常常会存在一个疑问:自变量究竟是连续型变量、还是离散型变量、还是数值型变量、还是字符型变量?
这个是很多小伙伴一开始就会出现的疑问,因为很多网络上的教程也把上述的概念给弄混淆了,所以这里我们做一个简单的区分
我们的数据类型包括:字符型、数值型和逻辑型三种,而我们的模型,或者扩展到我们的机器学习算法中,本质上来说其实就是一个个数学公式,所以我们要求的数据类型一定是数值型变量,那么这时候问题来了:为什么有的时候我们把字符型变量作为我们的自变量也是可以进行机器学习的呢?
这是因为我们在输入字符型的时候,我们R语言中的函数对字符型变量进行了重编码,也就是会生成一个虚拟编码,通俗的来讲举个例子就是性别是字符型变量,分为男和女,那么重编码后就变成了1和2
所以,我们这里解决了第一个问题即机器学习中的大多数模型都是通过重编码把字符型变量转化为数值型变量然后进行模型的构建
那么,还有一个问题:线性回归模型中的自变量要求是连续型还是离散型?
这个答案则是都可以,自变量即可以是离散型变量也可以是连续型变量,对于自变量来说,线性回归并没有太多的要求,而主要的要求是在于因变量上
所以我们可以做出总结:
1.针对线性回归(简单线性回归)来说,自变量为数值型变量(离散型&连续型),而因变量则是要求为连续型变量且建议正态分布
这里针对教科书上来说确实是直接要求因变量是符合正态分布的,但是我们往往对我们的因变量直接进行正态性检验发现严重偏离,这个时候其实我们是对于正态性的理解不够,这里晨曦直接说结论,针对因变量直接进行正态性检验是没有意义的,我们应该针对残差来进行正态性检,也就是说你没有必要提前对y做正态检验。而是先回归,然后针对残差做残差诊断,其中就是有一条要去判断残差是否满足正态性,如果残差不满足正态性,则可以说明模型不是最优(所以可以得出结论,针对线性回归来说,大样本(大于30)的前提下因变量、自变量和残差都不是必须符合正态性)
参考教程:数据分析中的第一误区 - 张霜的博文
2.通过构建虚拟变量,机器学习模型可以纳入字符型变量,但是我们要知道,最本质的数学公式接纳的是数值型变量而不是字符型变量,也就是说表面上来看是字符型变量,实际上其内在已经转换成了数值型变量
了解完上述的背景知识,我们就可以进入下面的代码实战部分
#准备输入数据
#数据中共有六个维度:age(年龄),sex(性别),bmi(肥胖指数),children(孩子数量),smoker(是否吸烟),region(居住地),charges则是当前数据人上年度在医院的花销
library(data.table)
df
这回可以很清楚的看到,我们的结局变量为连续型变量,这是一个美国病人的医疗费用的数据(医保)
#探索数据
str(df)
#Classes ‘data.table’ and 'data.frame': 1338 obs. of 7 variables:
# $ age : int 19 18 28 33 32 31 46 37 37 60 ...
# $ sex : chr "female" "male" "male" "male" ...
# $ bmi : num 27.9 33.8 33 22.7 28.9 ...
# $ children: int 0 1 3 0 0 0 1 3 2 0 ...
# $ smoker : chr "yes" "no" "no" "no" ...
# $ region : chr "southwest" "southeast" "southeast" "northwest" ...
# $ charges : num 16885 1726 4449 21984 3867 ...
# - attr(*, ".internal.selfref")=
#观察结局变量的分布
hist(df$charges)#可以很清楚的看到我们的因变量并不符合正态分布,但是我们仍然可以进行线性回归(大样本)
在我们的数据中,绝大多数的个人每年的费用都在0~15000美元,尽管分布的尾部经过直方图的峰部后延伸得很远。即将面临的另一个问题就是回归模型需要每一个特征都是数值型的,而在我们的数据框中,我们有3个字符型的特征。很快,我们会看到R中的线性回归函数如何处理我们的变量。#建立模型
ins_model
#观察模型
ins_model
#Call:
#lm(formula = charges ~ age + children + bmi + sex + smoker +
# region, data = df)
#Coefficients:
# (Intercept) age children bmi sexmale
# -11938.5 256.9 475.5 339.2 -131.3
# smokeryes regionnorthwest regionsoutheast regionsouthwest
# 23848.5 -353.0 -1035.0 -960.1
Intercept代表着一个截距数值,具体就是当所有自变量为0的时候,因变量是多少,这是一个常数项,这里我们解释一下截距项,其实这个数值没有太多的意义这个数值往往我们是不看的,因为很难解释,比如说,你无法说年龄为0,这明显是不符合我们客观认知的~至于其它的变量的回归系数,则表明,当其它变量不变的情况下,这个变量的增加会给因变量带来多大的改变但是其实如果你试图解析这个数值背后的实际含义会发现比较困难,如果我们的因变量是连续型变量,比如说是房地产价格或者股票价格,那么我们这个回归系数可以解释为当其它自变量不变的情况下,因变量变化的大小,但是这里我们的因变量是一个离散型变量,这个就无法简单的用数值的增加或者降低来解释了,所以我们大体只可以得到一个趋势,但是如果必须要讨论实际的意义可能并不是一个简单的事情这里我们又要纠正一个问题:单纯的线性回归适用于因变量为连续型变量的情况下,而如果我们的因变量是离散型变量,这个时候我们需要使用的广义线性模型中的Logistic回归模型但是,如果因变量是连续型正整数,而且发生的频率不是很高,这个时候我们可以使用广义线性模型中的泊松回归(适用条件为因变量是连续型正整数且发生的频率不是很高)同时,各位小伙伴可能注意到,在我们的模型公式中,我们仅指定了6个变量,但是输出时,除了截距项外,却输出了8个系数之所以发生这种情况,是因为lm()函数自动将一种称为虚拟编码(dummy coding)的技术应用于模型所包含的每一个因子类型的变量中。当添加一个虚拟编码的变量到回归模型中时,一个类别总是被排除在外作为参照类别然后,估计的系数就是相对于参照类别解释的。在我们的模型中,R自动保留sex female、smoker no和region northeast变量,使东北地区的女性非吸烟者作为参照组。因此,相对于女性来说,男性每年的医疗费用要少$131.30;吸烟者平均多花费$23848.50,远超过非吸烟者。此外,模型中另外3个地区的系数是负的,这意味着东北地区倾向于具有最高的平均医疗费用。#评估模型性能
#通过在R命令行输入ins_model,可以获得参数的估计值,它们告诉我们关于自变量是如何与因变量相关联的。但是它们根本没有告诉我们用该模型来拟合数据有多好。为了评估模型的性能,可以使用summary()命令来分析所存储的回归模型:
summary(ins_model)
#Call:
#lm(formula = charges ~ age + children + bmi + sex + smoker +
# region, data = df)
#Residuals:
# Min 1Q Median 3Q Max
#-11304.9 -2848.1 -982.1 1393.9 29992.8
#Coefficients:
# Estimate Std. Error t value Pr(>|t|)
#(Intercept) -11938.5 987.8 -12.086 < 2e-16 ***
#age 256.9 11.9 21.587 < 2e-16 ***
#children 475.5 137.8 3.451 0.000577 ***
#bmi 339.2 28.6 11.860 < 2e-16 ***
#sexmale -131.3 332.9 -0.394 0.693348
#smokeryes 23848.5 413.1 57.723 < 2e-16 ***
#regionnorthwest -353.0 476.3 -0.741 0.458769
#regionsoutheast -1035.0 478.7 -2.162 0.030782 *
#regionsouthwest -960.0 477.9 -2.009 0.044765 *
#---
#Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Residual standard error: 6062 on 1329 degrees of freedom
#Multiple R-squared: 0.7509, Adjusted R-squared: 0.7494
#F-statistic: 500.8 on 8 and 1329 DF, p-value: < 2.2e-16
标志①:残差部分:提供了我们预测中的错误的汇总统计数据,其中一些显然是相当可观的。由于残差等于真值减去预测值,最大误差29992.8表明,该模型至少有一次观测的预测费用低了近30,000美元。另一方面,50%的误差在1Q和3Q值(第一和第三个四分之一)内,因此大部分预测在真实价值的2850美元和真实价值的1400美元之间。标志②:星形(例如“***”)表示模型中每个特征的预测能力。显著性水平(如符号所列出的)提供了一个关于给定估计值的真实系数为零的可能性的度量。三颗星的存在表明其显著性水平为0, 这意味着该特征极不太可能与因变量无关。一种常见的做法是使用0.05的显著性水平来表示一个具有统计学意义的变量
标志③:多重R平方值(也称为决定系数)提供了一个度量,以衡量我们的模型作为一个整体如何解释因变量的值。与相关系数相似,值越接近1.0,模型越好地解释数据。由于调整后r平方值为0.7494,我们知道因变量的近75%的变化可以用我们的模型来解释鉴于前三个性能指标,我们的模型表现得相当好。真实世界数据的回归模型具有相当低的r平方值并不罕见;0.75的值实际上是相当好的回归建模和其他机器学习方法之间的一个关键区别是,回归通常会将特征选择和模型的权利留给个人。因此,如果我们有关于一个特性如何与结果相关的主题知识,我们就可以使用这些信息来告知模型应该纳入何种变量,并潜在地提高模型的性能
第一种方法:Model specification – adding non-linear relationships在线性回归中,假设自变量与因变量之间的关系是线性的,但这可能并不一定是正确的。例如,年龄对医疗支出的影响可能并非在所有年龄值中都保持不变;对于最年长的人群来说,治疗可能会变得不成比例地昂贵为了解释一个非线性关系,我们可以在回归模型中添加一个高阶项,将该模型视为一个多项式。实际上,我们将建模一个这样的关系这两种模型之间的区别在于,将估计一个单独的beta,其目的是捕获x平方项的影响。这使得年龄的影响可以作为年龄平方的函数来衡量要将非线性年龄添加到模型中,我们只需要创建一个新的变量然后,当我们生成改进的模型时,我们将把年龄和年龄的平方添加到lm()公式中,例如:charges ~ age + age2
我们在研究中发现,只有BMI大于30才会对患者造成伤害,或者说只有达到某一个阈值才会对我们的因变量造成影响然后我们可以使用下面的代码对我们的自变量进行编码,我们编码的目的在于明确了BMI阈值上下对结局变量的影响然后,我们可以将bmi30变量纳入我们改进的模型中,要么替换原始的bmi变量,要么再添加,这取决于我们是否认为肥胖的影响是除了单独的BMI效应之外发生的。如果没有充分的理由不这样做,我们将在最终的模型中包括这两者。如果您在决定是否包含一个变量时遇到困难,一种常见的做法是包含该变量并检查其显著性水平。然后,如果这个变量没有统计学意义,你就有证据支持在未来排除它到目前为止,我们只考虑了每个特性对结果的贡献。如果某些特征对因变量有综合影响呢?例如,吸烟和肥胖可能分别产生有害影响,但我们有理由假设,它们的综合影响可能比两者单独的总和更糟糕当两个特性具有组合效果时,这就被称为交互作用。如果我们怀疑两个变量有交互作用,我们可以通过在模型中添加它们的交互作用来验证这个假设。交互效果可以使用R公式语法来指定:charges ~ bmi30*smoker上面的代码展开就是:charges ~ bmi30 + smokeryes + bmi30:smokeryes然后让我们整体回顾一下,我们得到线性模型后,我们可以做哪些改动ins_model2
bmi30*smoker + region, data = df)
summary(ins_model2)
#如果我们确定一个变量是有意义的,那么纳入的变量越多,模型一定是越准确的
相对于我们的第一个模型,r-平方值已经从0.75提高到约0.87。我们的模型现在解释了87%的医疗费用的变化此外,我们关于模型函数形式的理论似乎得到了验证。高阶年龄项具有统计学意义,肥胖指标bmi30如此肥胖和吸烟之间的相互作用表明了巨大的影响;除了单独吸烟的费用增加超过13,404美元之外,肥胖吸烟者每年花费19,810美元。这可能表明,吸烟会加剧与肥胖相关的疾病到这里难道就结束了?不,显然我们依旧还有一些没有弄明白的问题,我们接下来继续进行探索我们仔细看下面这三个模型,这里我们常会有一个疑问:有了年龄的平方后我们是否还需要纳入单纯的年龄变量以及我们已经重编码了BMI,我们是否还需要纳入没有重编码的BMI变量#模型一
ins_model2
bmi30*smoker + region, data = df)
#Multiple R-squared: 0.8664
#模型二
ins_model2
bmi30*smoker + region, data = df)
#Multiple R-squared: 0.8664
#模型三
ins_model2
bmi30*smoker + region, data = df)
#Multiple R-squared: 0.8652
这里我们依旧是通过实践来解答上述的问题,我们可以很清楚的看到去掉单纯的age变量和加入age变量,并没有对模型的决定系数产生影响,但是,我们根据最原始的数学公式,则是要求我们加入age平方前的变量,所以这里我们给的建议则是,添加上平方前的变量,即age和age的平方都纳入我们的自变量,而针对BMI重编码我们也可以得出结论,即添加上BMI会对模型的决定系数起到的一定性的提高至此,我们线性回归模型相关的内容就给大家介绍到了这里,相信大家通过本期推文的学习,应该可以掌握线性回归模型,至于后续的一些细节,大家可以持续关注挑圈联靠公众号后续内容,会给大家带来更多机器学习相关的内容参考书籍:Machine Learning with R
晨曦单细胞笔记系列传送门
1. 首次揭秘!不做实验也能发10+SCI,CNS级别空间转录组套路全解析(附超详细代码!)
2. 过关神助!99%审稿人必问,多数据集联合分析,你注意到这点了吗?
3. 太猛了!万字长文单细胞分析全流程讲解,看完就能发文章!建议收藏!(附代码)
4. 秀儿!10+生信分析最大的难点在这里!30多种方法怎么选?今天帮你解决!
5. 图好看易上手!没有比它更适合小白入手的单细胞分析了!老实讲,这操作很sao!
6. 毕业救星!这个R包在高分文章常见,实用!好学!
7. 我就不信了,生信分析你能绕开这个问题!今天一次性帮你解决!
晨曦单细胞数据库系列传送门
1. 宝儿,5min掌握一个单细胞数据库,今年国自然就靠它了!(附视频)
2. 审稿人返修让我补单细胞数据咋办?这个神器帮大忙了!
3. 想白嫖、想高大上、想有高大上的SCI?这个单细胞数据库,你肯定用得上!(配视频)
4. What? 扎克伯格投资了这个数据库?炒概念?跨界生信?
5. 不同物种也能合并做生信?给你支个妙招,让数据起死回生!
6. 零成本装逼指南!单细胞时代,教你用单细胞数据库巧筛基因,做科研!
7. 大佬研发的单细胞数据库有多强? 别眼馋 CNS美图了!零基础的小白也能10分钟学会!
8. 纯生信发14分NC的单细胞测序文章,这个北大的发文套路,你可以试下!实在不行,拿来挖挖数据也行!
9. 如何最短时间极简白嫖单细胞分析?不只是肿瘤方向!十分钟教你学会!
10. 生信数据挖掘新风口!这个单细胞免疫数据库帮你一网打尽了!SCI的发文源头!
欢迎大家关注解螺旋生信频道-挑圈联靠公号~