R语言机器学习入门——14

309 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情

项目实操——线性回归(二)

线性拟合常用函数:

使用predict()函数可以用拟合模型对新的数据集进行预测

直接使用plot()函数可以对拟合结果进行绘图:

plot(fit)

会生成四幅图:残差拟合图、正态分布qq图、大小位置图以及残差影响图

Abline()函数可以绘制出拟合曲线,但这个命令属于低级绘图命令,必须在高级绘图的基础上完成,我们先绘制身高与体重的散点图:

plot(women$height,women$weight)
> abline(fit)

最小二乘法的原理就是找到一条直线(拟合直线),使残差平方和最小

一般拟合曲线很少是直线,大部分都是曲线,也就是多项式的回归

还是women这个数据集,我们用多项式回归试一下:

先定义一个fit2变量

将体重作为因变量,身高与身高的平方作为自变量

fit2 <- lm(weight ~ height+I(height^2),data = women)

可以对比两次回归的曲线差异

plot(women$height,women$weight)
abline(fit)

这次使用lines()函数,这个函数能把点连成线,横坐标是身高数据,纵坐标是根据拟合模型的得出的预测值,为了增加比较的差异性,我们给第二个曲线增加颜色:

lines(women$height,fitted(fit2),col="red")

对比很明显,带有二次项的回归模型能够更好的拟合数据,使得更多的点落在曲线上

那么,三次项的回归模型效果是不是更好呢?我们再来拟合一下

fit3 <- lm(weight ~ height+I(height^2)+I(height^3),data=women)
plot(women$height,women$weight)
abline(fit)
> lines(women$height,fitted(fit2),col="red")
> lines(women$height,fitted(fit3),col="blue")

拟合结果如图:

结果表明,继续增加多项式可以提高拟合度,但是其实没有必要,因为用于拟合的数据集,只是用于建模的数据集,不一定适合真实的数据,过多的拟合也是纸上谈兵。

项目实操——多元线性回归

当预测变量不止一个时,简单现象回归就变成了多元线性回归,相当于求解多元方程,而且和方程式求解不同的是,这些变量的权重还不一样,有些大 ,有些小,有些或者是没有多大影响,下面我们来看一个案例:

以state.x77这个数据集为例,求解出一个拟合模型,然后可以根据某些指标预测出犯罪率:

首先我们将state.x77这个矩阵数据转化成数据框,因为lm()函数输入数据必须是数据框的格式

这里为了简化问题,我们只取四个指标进行回归分析:population、illiteracy、income、frost

states <- as.data.frame(state.x77[,c("Murder",'Population','Illiteracy','Income',"Frost")])

还是使用一个lm()函数,定义一个fit变量,用于存储模型结果

fit <- lm(Murder ~ Population+Illiteracy+Income+Frost,data = states)

使用summary()函数查看模型的详细过程结果

> summary(fit)

我们可以使用coef()函数单独查看各项的系数,根据系数项和截距值就能写出拟合方程

coef(fit)

options(digits = 4)

可以通过options()的digits参数设置显示的位数

下面我们来列举一个更复杂的例子,在很多研究中,变量会有交互项,也就是变量相互之间并不是独立的,例如mtcars数据集,汽车的重量与马力之间存在着交互,质量大会影响到马力。交互项就是解释变量之间存在相关性

我们来拟合一下mtcars数据集中,每加仑汽油行驶里程数(mpg)变量与马力(hp)以及车重(wt)之间的关系

fit <- lm(mpg ~ hp+wt+hp:wt,data = mtcars)
summary(fit)

从结果中可以看见,车重与马力的交互项是非常显著的,这就说明响应变量mpg与其中一个预测变量的关系依赖于另一个预测变量的水平,其实就是说,每加仑汽油行驶里程数域与汽车马力的关系需要依赖汽车的不同而不同。

对于多元线性回归存在的一个问题就是,如果存在多个变量,就需要考虑变量之间的相互影响和回归时的组合关系,也就是如何从众多可能的模型中选择最佳的模型呢?

比如是不是需要包括所有的变量,还是需要去掉一些对模型贡献不显著的变量,是否需要添加多项式或者是交互项来提高拟合度呢?

那么对于以上的问题,我们可以使用AIC()函数来比较模型。

AIC()函数是An Information Criterion的简称,称为赤池信息准则,这个准则考虑了模型统计拟合度以及用来拟合的参数数目

计算得到的AIC值越小越好,越小说明模型用较少的参数就可以获得足够的拟合度

例如上面拟合犯罪度的案例

Ctrl+UP调出历史代码列表

对比一下两个fit的拟合度

fit1 <- lm(Murder ~ Population+Illiteracy+Income+Frost,data = states)
fit2 <- lm(Murder ~ Population+Illiteracy,data = states)
AIC(fit1,fit2)

结果显示,fit2的拟合度更好,但是如果变量数过多,那么组合起来的拟合模型数将是巨大的,再用AIC()两两比较就不太可行了

这个时候,对于变量的选择可以使用逐步回归法和全子集回归法。

逐步回归法中,模型会依次添加或者删除一个变量直到达到某个节点为止,这个节点就是继续添加或者删除变量,模型不再继续变化。如果每次是增加变量,那么就是向前逐步回归,如果每次是删除变量,那么就是向后逐步回归。

全子集回归法是取所有可能的模型,然后从中计算出最佳的模型,很显然全子集回归法要比逐步回归法要好,因为会检测到所有的模型,把可能的模型都纳入考虑之中,但是缺点就是如果变量数太多,会涉及到大量的计算,运算会比较慢。

这两种方法都需要通过R的扩展包来实现,MASS包中的stepAIC()函数可以进行逐步回归法的计算

> library(MASS)
> states <- as.data.frame(state.x77[,c("Murder",'Population','Illiteracy','Income',"Frost")])
> fit <- lm(Murder ~ Population+Illiteracy+Income+Frost,data = states)
> stepAIC(fit,direction = "backward")

Leaps包中的regsubsets()函数可以进行全子集回归的计算

但是拟合效果最佳但没有实际意义的模型是没有用的,所以我们始终要对数据有所了解。