簡體   English   中英

在R中實現二維核密度估計的不同核

[英]Implementing a different Kernel for 2D Kernel Density Estimation in R

我正在尋找一些幫助,了解如何實現二維核密度方法,具有各向同性方差和雙變量正常內核,但不是使用典型距離,因為數據是在表面上地球,我需要使用一個很大的圓距離。

我想在R中復制這個,但我無法弄清楚如何使用除了簡單的歐幾里德距離之外的任何內置估計器的距離度量,並且因為它使用帶卷積的復雜方法來添加內核。 有沒有人有辦法編程任意內核?

我最終修改了MASS庫中的kde2d函數。 需要進行一些重大修訂,如下所示。 也就是說,代碼非常靈活,允許使用任意的2-d內核。 (rdist.earth()用於大圓距離,h是所選帶寬,在這種情況下,以km為單位,n是每個方向上要使用的網格點數.rdist.earth需要“字段”圖書館)

可以修改該函數以在超過2d的時間內執行計算,但是網格在更高維度上變得非常快。 (現在不是很小。)

歡迎對優雅或表現的意見和建議!

kde2d_mod <- function (data, h, n = 200, lims = c(range(data$lat), range(data$lon))) {
#Data is a matrix: lon,lat for each source. (lon,lat to match rdist.earth format.)
print(Sys.time()) #for timing

nx <- dim(data)[1]
if (dim(data)[2] != 2) 
stop("data vectors have only lat-long data")
if (any(!is.finite(data))) 
stop("missing or infinite values in the data are not allowed")
if (any(!is.finite(lims))) 
stop("only finite values are allowed in 'lims'")
#Grid:
g<-grid(n,lims) #Function to create grid.

#The distance matrix gets large... Can we work around it? YES WE CAN!
sets<-ceiling(dim(g)[1]/10000)
#Allocate our output:
z<-rep(as.double(0),dim(g)[1])

for (i in (1:sets)-1) {
   g_subset=g[(i*10000+1):(min((i+1)*10000,dim(g)[1])),]
   a_matrix<-rdist.earth(g_subset,data,miles=FALSE)

   z[(i*10000+1):(min((i+1)*10000,dim(g)[1]))]<- apply( #Here is my kernel...
    a_matrix,1,FUN=function(X)
    {sum(exp(-X^2/(2*(h^2))))/(2*pi*nx)}
   )
rm(a_matrix)
}

print(Sys.time())
#Un-transpose the final data.
z<-t(matrix(z,n,n))
dim(z)<-c(n^2,1)
z<-as.vector(z)
return(z)
}

這里的關鍵點是任何內核都可以在內部循環中使用; 不利的一面是,這是在網格點進行評估,因此需要一個高分辨率的網格來運行它; FFT會很棒,但我沒有嘗試過。

網格功能:

grid<- function(n,lims) {
num <- rep(n, length.out = 2L)
gx <- seq.int(lims[1L], lims[2L], length.out = num[1L])
gy <- seq.int(lims[3L], lims[4L], length.out = num[2L])

v1=rep(gy,length(gx))
v2=rep(gx,length(gy))
v1<-matrix(v1, nrow=length(gy), ncol=length(gx))
v2<-t(matrix(v2, nrow=length(gx), ncol=length(gy)))
grid_out<-c(unlist(v1),unlist(v2))

grid_out<-aperm(array(grid_out,dim=c(n,n,2)),c(3,2,1) ) #reshape
grid_out<-unlist(as.list(grid_out))
dim(grid_out)<-c(2,n^2)
grid_out<-t(grid_out)
return(grid_out)
}

您可以使用image.plot繪制值,使用x,y點的v1和v2矩陣:

kde2d_mod_plot<-function(kde2d_mod_output,n,lims) ){
 num <- rep(n, length.out = 2L)
 gx <- seq.int(lims[1L], lims[2L], length.out = num[1L])
 gy <- seq.int(lims[3L], lims[4L], length.out = num[2L])

 v1=rep(gy,length(gx))
 v2=rep(gx,length(gy))
 v1<-matrix(v1, nrow=length(gy), ncol=length(gx))
 v2<-t(matrix(v2, nrow=length(gx), ncol=length(gy)))

 image.plot(v1,v2,matrix(kde2d_mod_output,n,n))
 map('world', fill = FALSE,add=TRUE)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM