R: Kriging interpolation and cross validation 克里金插值及交叉验证浅析

克里金插值的基本介绍可以参考ARCGIS的帮助文档[1]. 其本质就是根据已知点的数值,确定其周围点(预测点)的数值。最直观的方法就是找到已知点和预测点数值之间的关系,从而预测出预测点的数值。比如IDW插值方法,就是假设已知点和预测点的值跟它们相对距离成反比。克里金插值的精妙之处在于它不仅考虑了已知点和预测点的距离关系,还考虑了这些已知点之间的自相关关系。

如何衡量已知点之间的自相关关系呢?通常使用的就是半变异函数,其公式如下[1]:

Semivariogram(distance h) = 0.5 * average((value i – value j)2)

这就是克里金插值不同于其他插值方法的核心所在,通过计算每个距离范围内所有配对点的离差平方和,就可以绘制出不同距离范围下的变差值图,如下示意图[1]。我们知道,离差平方和是衡量一组数据变化程度的量,而这里通过计算所有已知点与其不同距离范围内邻居点集的距离离差平方和,就可以大致衡量出已知点与不同距离范围邻居点的变化程度关系,通常的做法是进行曲线拟合,常用的包括指数拟合、球面拟合、高斯拟合等。而这个拟合的结果就是我们插值所需要的块金值、基台值等。

 

注意,目前为止这里只涉及到克里金插值是如何分析已知点信息,以及如何构造这些已知点之间的关系,整个插值(预测)过程就是假设这种已知点之间的关系:距离关系和自相关关系,对于预测点同样适用!

然而,在没有更多信息的前提下,我们如何知道这种插值是否可信?目前较为合理的方法就是交叉验证Cross validation。其本质是拿出一些已知点作为预测点,这些被拿出的点不参与上述已知点关系的探索过程,而是作为验证数据来衡量我们预测是否合理。比如,我们每次拿出一个已知点作为验证数据,来验证这个点的预测值,我们就可以得到所有已知点与其预测值之间的偏差,这个所有点的偏差从某种程度上讲就为我们提供了整个预测方法是否合理的依据。

一个基于R gstat空间插值包的示例:

如下图,假设我们已知的数据点的栅格图,需要插值出其它预测点的值(白色透明区域):

首先,我们需要将这个栅格数据读入到R中(需要安装raster包)

install.packages("raster")

library(raster)

data.observed <- raster("C:/Users/workspace/allmax.img")

因为gstat都是以data  frame的格式进行数据处理,首先我们编写一个函数,将这个栅格数据转化为data frame:

raster_to_dataframe<- function(inRaster, name) #
{
  rp<- rasterToPoints(inRaster)
  df = data.frame(rp)
  colnames(df) = c("X", "Y", "VALUE")
  df$NAME<- name
  return(df)
}
name参数可以是随意的字符串,方便与其他data frame合并的时候辨别数据,这时候我们调用此函数,如下:data.observed <- raster_to_dataframe (data.observed, "Observed") 查看转换为data frame的结果,可以使用:head(data.observed)
          X       Y VALUE    NAME
1 -318466.5 3794841    12 Observed
2 -304466.5 3794841    10 Observed
3 -303466.5 3794841     9 Observed
4 -302466.5 3794841    11 Observed
5 -301466.5 3794841     7 Observed
6 -297466.5 3794841    14 Observed

好了,接下来就是要分析这写已知点,gstat提供了半变异图绘制函数variogram:

v<- variogram(object = VALUE~1,data = df.wg,locations =~X+Y, width= 200)
plot(v)

通过观察,已知点的自相关关系semivariance随着距离distance的增加,呈现出指数形式的减弱(还记得吗?离差平方和?值越小,代表关系越强),所以通过观察半变异方差的分布,确定使用指数模型来拟合:

v.fit = fit.variogram(v, vgm(model = "Exp", psill= 45, range = 20000, kappa = 10),fit.sills = 50)
plot(v, model=v.fit)v.fit

如何确定pstill, range等初始值呢,同样通过观察大致给出即可,fit.variogram()函数会自动计算出正确的结果,这个初始值存在的作用只是辅助计算,不用十分正确,其结果如下图:

  

model psill range
1 Exp 61.39472 5326.663

可以看出,R计算出了新的psill和range值。

接下来,我们就可以利用上述分析的信息,进行克里金插值。这里使用的是krige函数:

kingnewdata<- raster_to_dataframe2(max.allgf, "Interpolate location")
aa<- krige(formula = VALUE~1,locations =~X+Y , model = vgm(61.39472, "Exp", 5326.663 , 10) , data = data.observed, newdata= kingnewdata, nmax=12, nmin=10)

参数formula指出已知点和其他信息的关系(假如本例已知点代表土壤含水量,我们也知道这些点对应的降雨信息,那么这里的公式就是土壤含水量和降雨的简单线性关系),这里我们没有其他信息,就是普通克里金插值。参数location是已知点的坐标,这里X代表经度,Y值代表纬度。参数model就是我们上边分析的指数模型,使用拟合后的参数即可。data表示要使用的已知点的数据框。newdata表示要插值的点的位置,注意要包含和data参数所使用的dataframe一样的变量名称(本例中位置是大写X, Y),nmax和nmin是最多和最少搜索的点数,其他参数大家可以参考帮助文档,插值的结果如下:

好了,我们已经完成了克里金插值所有任务并且得到了我们所需要插值图,但是怎么才能知道我们的插值结果可信与否呢?当然,如果我们有预测点的实际数据,我们可以评价插值结果的精度,但是很多情况下,我们没有这些数据,cross validaion应运而生。对于克里金插值,gstat提供的cross validation函数是krige.cv(),对于本文,只需要如下代码即可完成cross validation:

kriging<- krige.cv(formula = VALUE~1, locations = ~X+Y, model = vgm(61.39472, "Exp", 5326.663 , 10), data = data.observed ,nfold= nrow(data.observed))head(kriging)

注意,krige.cv()函数本质上是进行很多次克里金插值,然后我们就可以分析被拿出的已知点的值和预测值,估计克里金插值的可信性。这里我们每次拿出一个点,所以nfold的值设置为和data.observed的行数一样,可以看到结果:

  var1.pred var1.var observed  residual     zscore fold         X       Y
1 19.020820 31.29921       12 -7.020820 -1.2549348    1 -318466.5 3794841
2 11.220626 27.62193       10 -1.220626 -0.2322499    2 -304466.5 3794841
3 10.758057 24.82611        9 -1.758057 -0.3528407    3 -303466.5 3794841
4  9.200462 24.85426       11  1.799538  0.3609613    4 -302466.5 3794841
5 10.840395 27.07824        7 -3.840395 -0.7380158    5 -301466.5 3794841
6 12.446044 29.40208       14  1.553956  0.2865826    6 -297466.5 3794841

结果包含了预测值,预测值的方差,已知值,残差,z统计量值等,我们可以绘制出z统计量图:

ggplot(data = kriging, aes(x=X,y=Y))+
  geom_raster( aes(fill= zscore)) +
  scale_fill_gradient2( name="zscore",low = "green",
                        mid = "grey", high = "red", midpoint = 0,
                        space = "rgb", na.value = "grey50")

结果如下:

或者其直方图来评价插值方案:

par(mar=c(2,2,2,2))
hist(kriging$zscore)

  

比如我们可以得出类似结论:由于大部分数值都在1个标准差范围内,说明插值方案可行,我们就可以做出插值方案在预测区也基本可行的假设。

最后,欢迎大家留言讨论,转载请注明出处

参考文献:

[1] http://desktop.arcgis.com/en/arcmap/10.3/tools/3d-analyst-toolbox/how-kriging-works.htm

关于R基本栅格数据处理我推荐一篇博文:http://rstudio-pubs-static.s3.amazonaws.com/1057_1f7e9ac569644689b7e4de78c1fece90.html

时间: 2024-11-07 05:51:07

R: Kriging interpolation and cross validation 克里金插值及交叉验证浅析的相关文章

openlayers4 入门开发系列之前端动态渲染克里金插值 kriging 篇(附源码下载)

前言 openlayers4 官网的 api 文档介绍地址 openlayers4 api,里面详细的介绍 openlayers4 各个类的介绍,还有就是在线例子:openlayers4 官网在线例子,这个也是学习 openlayers4 的好素材. openlayers4 入门开发系列的地图服务基于 Geoserver 发布的,关于 Geoserver 方面操作的博客,可以参考以下几篇文章: geoserver 安装部署步骤 geoserver 发布地图服务 WMS geoserver 发布地

克里金插值及栅格渲染

1.首先写一个栅格渲染的方法: 步骤:1计算立方图 2创建色带 3渲染 //渲染        private void Renders(IRasterLayer layer)        {            IRasterClassifyColorRampRenderer classRender = new RasterClassifyColorRampRendererClass(); IRasterRenderer rasterRender = classRender as IRas

克里金插值程序

克里金插值的原理的阅读笔记,在下面下载DOWN LINK.此原理让你很快明天克里金插值的原理,论文写的十分的好.推荐你下载并阅读,如果没有CSDN积分,可以去知网或者百度学术中下载.只是上面没有我的笔记而已. 下面说说程序的事情. 这个程序有两个版本,第一个是Matlab版本的,在CSDN中可以下载,地址为 Download_LINK. 这个matlab版本的缺点是运行慢,太大的数据会慢的受不了.所以,我在网上找了一段时间,花费一天时间.终于找到一个c++版本的,这个版本的大家想必也知道.只是不

ArcGIS教程:不同的克里金模型

克里金方法依赖于数学模型和统计模型.通过添加包含概率的统计模型,可将克里金方法从空间插值的确定性方法中描述的确定性方法中分离出来.对于克里金法,您会将某种概率与预测值相关联;也就是说,这些值不能完全基于统计模型进行预测.以在某一地区测得的氮值这一样本为例.显然,即使样本很大,您也无法预测某个未测量位置处的准确氮值.因此,您不但要尝试预测该值,而且还要评估预测的误差. 克里金方法依赖于自相关概念.相关性通常被视为两种变量相关的趋势.例如,股票市场在利率降低时倾向于上涨,所以称其为负相关.但是,股票

交叉验证的缺陷及改进(Cross Validation done wrong)

本文主要是对我们使用交叉验证可能出现的一个问题进行讨论,并提出修正方案. 本文地址:http://blog.csdn.net/shanglianlm/article/details/47207173 交叉验证(Cross validation)在统计学习中是用来估计你设计的算法精确度的一个极其重要的工具.本文主要展示我们在使用交叉验证时可能出现的一个问题,并提出修正的方法. 下面主要使用 Python scikit-learn 框架做演示. 先验理论(Theory first) 交叉验证将数据集

Cross Validation done wrong

Cross Validation done wrong Cross validation is an essential tool in statistical learning 1 to estimate the accuracy of your algorithm. Despite its great power it also exposes some fundamental risk when done wrong which may terribly bias your accurac

关于K-fold cross validation 下不同的K的选择的疑惑?

在K-fold cross validation 下 比较不同的K的选择对于参数选择(模型参数,CV意义下的估计的泛化误差)以及实际泛化误差的影响.更一般的问题,在实际模型选择问题中,选择几重交叉验证比较合适? 交叉验证的背景知识: CV是用来验证模型假设(hypothesis)性能的一种统计分析方法,基本思想是在某种意义下将原始数据进行分组,一部分作为训练集,一部分作为验证集,使用训练集对每个hypothesis进行训练,再用验证集对每个hypothesis的性能进行评估,然后选取性能最好的h

交叉验证(Cross Validation)原理小结

交叉验证是在机器学习建立模型和验证模型参数时常用的办法.交叉验证,顾名思义,就是重复的使用数据,把得到的样本数据进行切分,组合为不同的训练集和测试集,用训练集来训练模型,用测试集来评估模型预测的好坏.在此基础上可以得到多组不同的训练集和测试集,某次训练集中的某样本在下次可能成为测试集中的样本,即所谓"交叉". 那么什么时候才需要交叉验证呢?交叉验证用在数据不是很充足的时候.比如在我日常项目里面,对于普通适中问题,如果数据样本量小于一万条,我们就会采用交叉验证来训练优化选择模型.如果样本

cross validation交叉验证

交叉验证是一种检测model是否overfit的方法.最常用的cross validation是k-fold cross validation. 具体的方法是: 1.将数据平均分成k份,0,1,2,,,k-1 2.使用1~k-1份数据训练模型,然后使用第0份数据进行验证. 3.然后将第1份数据作为验证数据.进行k个循环.就完成了k-fold cross validation 这个交叉验证的方法的特点是:所有的数据都参与了验证,也都参与了训练,没有浪费数据.