建立模型的目的是提供一个简单的、低维度的数据集摘要。
建模过程可以分为两个阶段:
1.定义一个模型族来表示一种精确但一般性的模式。例如,模式可以是一条直线或一条二次曲线。可以用方程来表示模型族,通过改变模型中的参数来捕获不同的模式。
2.生成一个拟合模型,即从模型族中找出最接近数据的一个模型。这个阶段使得一般性的模型族具体化为特定模型。
准备工作:
library(tidyverse)
library(modelr)
options(na.action=na.warn)
一、一个简单的模型
下面研究模拟数据集sim1:
ggplot(sim1,aes(x,y))+geom_point()
可以发现数据有一个非常强的模式。下面我们要捕获这种模式。
1.首先确定模型的基本形式:
2.随机生成一些模型,将其覆盖到数据上。
这个例子我们可以使用geom_abline函数:
> models<-tibble(a1=runif(250,-20,40),a2=runif(250,-5,5))
> ggplot(sim1,aes(x,y))+geom_abline(aes(intercept=a1,slope=a2),data=models,alpha=1/4)+geom_point()
为了评价模型的好坏,最简单的方法是计算数据点与模型之间的垂直距离。下面我们编写一个函数用来计算这个距离:
第一步:编写一个函数将模型的参数和数据作为输入,模型的预测值作为输出:
> model1<-function(a,data){a[1]+data$x*a[2]}
> model1(c(7,1.5),sim1)
[1] 8.5 8.5 8.5 10.0 10.0 10.0 11.5 11.5 11.5 13.0
[11] 13.0 13.0 14.5 14.5 14.5 16.0 16.0 16.0 17.5 17.5
[21] 17.5 19.0 19.0 19.0 20.5 20.5 20.5 22.0 22.0 22.0
第二步:计算均方误差根
> model_distance<-function(mod,data){
+ diff<-data$y-model1(mod,data)
+ sqrt(mean(diff^2))
+ }
> model_distance(c(7,1.5),sim1)
[1] 2.665212
第三步:使用purrr计算所有模型的均方误差
purrr包中提供了映射函数:map2_dbl用于输出双精度型向量。
> sim1_distance<-function(a1,a2){
+ model_distance(c(a1,a2),sim1)
+ }
> models<-models%>%mutate(distance=purrr::map2_dbl(a1,a2,sim1_distance))
> models
# A tibble: 250 x 3
a1 a2 distance
<dbl> <dbl> <dbl>
1 1.21 2.32 2.74
2 39.8 -1.44 19.3
3 -3.82 -1.02 26.5
4 -18.9 -1.44 43.5
5 25.6 -0.840 10.2
6 -0.861 2.40 3.94
7 -17.1 3.97 12.3
8 15.7 -3.04 22.2
9 22.1 -1.66 11.2
10 6.35 -3.30 31.4
# ... with 240 more rows
第四步:将最好的十个模型映射到图形上
> ggplot(sim1,aes(x,y))+geom_point(size=2,color="grey30")+geom_abline(data=filter(models,rank(distance)<=10),aes(intercept=a1,slope=a2,color=-distance))
还可以将不同的模型看为观测,使用a1,a2作为横纵坐标画出其散点图。高亮最好的10个模型。
> ggplot(models,aes(a1,a2))+geom_point(aes(color=-distance))+geom_point(data=filter(models,rank(distance)<=10),size=2,color='red')
第五步:使用网络搜索法找出模型参数
1.生成一张分布均匀的数据点网格,然后将这个网格与前面的10个最佳模型点绘制在一起,最后找出模型的粗略值。
> grid<-expand.grid(a1=seq(-5,20,length=25),a2=seq(1,3,length