在R中寻找非线性相关性

8

我在data[2-90]中存储了大约90个变量。我怀疑其中有4个变量与data[1]呈现抛物线相关性。我想要确定哪些变量具有这种相关性。是否有一种简单快捷的方法来实现这一点?

我已经尝试构建了这样一个模型(我可以针对每个变量i = 2:90循环执行):

y <- data$AvgRating
x <- data$Hamming.distance
x2 <- x^2

quadratic.model = lm(y ~ x + x2)

然后查看R^2 / 系数,以了解相关性的想法。有没有更好的方法?

也许R可以使用90个变量构建回归模型,并选择自身显著的变量?这样有可能吗?我可以在JMP中进行线性回归,但我不确定我是否可以使用R进行所有变量的非线性回归。因此,我手动尝试着看看哪些变量事先是相关的。如果有一个函数可用于此,那将会很有帮助。


1
如果 data 是一个 data.frame,那么 data[1] 将给出一个只有一列的 data.frame,而 lm 函数期望一个向量。使用 data[[1]] 可以获取向量。 - snaut
问题在于它们将具有非单调关系(类似于抛物线)。我想知道是否可以以某种方式捕捉这种相关性。最终的目标是找到约4个重要变量来构建非线性lm模型。 - dorien
谢谢 snaut,这真的有助于制作循环 :) - dorien
有没有可能使用非线性公式进行逐步回归呢? - dorien
1
我不知道你为什么想要建立这个模型,但如果关系不是线性的话,广义加性模型可能更可取。包mgcv中的实现可以去除变量。 - Roland
显示剩余9条评论
3个回答

9
你可以在R中使用nlcor包。该软件包可以找到两个数据向量之间的非线性相关性。
有不同的方法来估计非线性相关,例如infotheo。然而,两个变量之间的非线性相关可以采取任何形式。 nlcor对大多数非线性形状都很强健。在不同的场景中它表现良好。
在高层次上,nlcor通过自适应地将数据分成线性相关段来工作。这些段的相关性被聚合以产生非线性相关性。输出是一个介于0到1之间的数字。接近1表示高相关性。与pearson相关不同的是,不会返回负值,因为它在非线性关系中没有意义。
有关此软件包的更多详细信息,请单击此处 要安装nlcor,请按照以下步骤操作:
install.packages("devtools") 
library(devtools)
install_github("ProcessMiner/nlcor")
library(nlcor)

安装完成后,

# Implementation 
x <- seq(0,3*pi,length.out=100)
y <- sin(x)
plot(x,y,type="l")

sin(x) plot

# linear correlation is small
cor(x,y)
# [1] 6.488616e-17
# nonlinear correlation is more representative
nlcor(x,y, plt = T)
# $cor.estimate
# [1] 0.9774
# $adjusted.p.value
# [1] 1.586302e-09
# $cor.plot

使用 nlcor 来计算 sin(x)

如图所示,线性相关系数接近于零,但是变量之间存在明显的关系,这可以通过nlcor进行检测。

注意:在nlcor中x和y的顺序很重要。nlcor(x,y)nlcor(y,x)是不同的。这里的x和y分别表示“自变量”和“因变量”。


2
拟合广义加性模型,有助于识别解释变量之间的曲率关系。在第22页阅读示例这里

谢谢。我尝试使用gam函数来实现这个。但是当变量太多时,会出现自由度不足的错误。因此,我认为应该先针对每个变量进行操作,以确定哪些变量最适合。或者我是否错过了gam可以识别变量的功能? - dorien

1
另一种选择是计算每对变量之间的互信息分数。例如,使用 infotheo package 中的 mutinformation 函数,您可以执行以下操作:
set.seed(1)

library(infotheo)

# corrleated vars (x & y correlated, z noise)
x <- seq(-10,10, by=0.5)
y <- x^2
z <- rnorm(length(x))

# list of vectors
raw_dat <- list(x, y, z)


# convert to a dataframe and discretize for mutual information
dat <- matrix(unlist(raw_dat), ncol=length(raw_dat))
dat <- discretize(dat)

mutinformation(dat)

Result:

|   |        V1|        V2|        V3|                                                                                            
|:--|---------:|---------:|---------:|                                                                                            
|V1 | 1.0980124| 0.4809822| 0.0553146|                                                                                            
|V2 | 0.4809822| 1.0943907| 0.0413265|                                                                                            
|V3 | 0.0553146| 0.0413265| 1.0980124| 

默认情况下,mutinformation() 计算两个或多个变量之间的离散经验互信息分数。如果您使用连续数据,请使用 discretize() 函数将数据转换为离散值。这可能至少对于寻找变量之间的非线性关系(如上述所述)作为第一次尝试是有帮助的。

我可以将此用于任意数据集,而不一定是固定的数据集吗?谢谢。 - python novice
嗨@pythonnovice,我以前没有处理过这种类型的数据,所以我不能确定。可能最简单的方法是模拟一些简单的非平稳数据并尝试一下。 - Keith Hughitt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接