R语言与线性回归分析

2023-10-31


基本假设:正态性、独立性、线性、同方差性
常用R包:car(carData)、MASS、leap…

1. 原始数据的分析

plot(x,y); abline(lm(y~x))
library(carData);library(car)
scatterplot(x,y)  #生成拟合的二元关系图(散点+箱线)
scatterplotMatrix()  #生成散点图矩阵

cor()  #计算相关系数

2. 回归模型的拟合(参数估计和检验)

# 数据准备
n <- ; p <- 
Y <- as.matrix(dataset[,1])
X1 <- as.matrix(dataset[,2:p])
X <- cbind(1,X1)
XX <- t(X)%*%X

# 参数估计
Beta <- solve(XX)%*%t(X)%*%Y
e <- Y-X%*%Beta #<or> resid <- resid(lm) #残差的计算
SSe <- t(e)%*%e
sigma2 <- SSe/(n-p) || sigma2 <- sd(e)^2*(n-1)/(n-p)  #σ标准差的估计
covBeta <- sigma2*solve(XX)  #Beta的协方差阵
r <- matrix(nrow=p,ncol=p)
for (i in 1:p)  {
	for (j in 1:p)
		r[i,j] <- covBeta[i,j]/(sqrt(covBeta[i,i])*sqrt(covBeta[j,j]))
		}   #Beta的相关系数阵

# 模型检验
Beta1 <- beta[-1]
Xc <- (X-matrix(1,nrow=18)%*%colMeans(X))[,-1]
RSS_I <- t(Beta1)%*%t(Xc)%*%Y
RSS_H <- n*mean(Y)^2
SS_He <- t(Y)%*%Y-RSS_H
RSS <- t(Beta)%*%t(X)%*%Y  ||  RSS <- RSS_H + RSS_I
SSe <- t(Y)%*%Y-RSS
F <- (RSS-RSS_H)/(p-1)/(SSe/(n-p))
pf(F,p-1,n-p,lower.tail = T)

# 系数检验
t <- matrix(1,ncol=p)
for(j in 1:4) t[j]<-beta[j]/sqrt(sigma2*solve(t(X)%*%X)[j,j])
p-value <- 2*pt(abs(t),n-p,lower.tail = FALSE)

# 复相关系数
TSS<-t(Y-mean(Y))%*%(Y-mean(Y))
R2 <- RSS_I  / TSS
Adjusted_R2 <- 1-(1-R2)*(n-1)/(n-p)
myfit <- lm(y~x1+x2+x3,dataframe)

summary() 展示拟合模型的详细结果
coefficients()  列出拟合模型的模型参数(截距项和斜率)
confint()  列出模型参数的置信区间(95%fitted()  列出拟合模型的预测值
anova()  生成拟合模型的方差分析表
vcov()  列出模型参数的协方差矩阵
AIC()  输出赤池信息统计量
plot()  生成评价拟合模型的诊断图
predict()  用拟合模型对新的数据集预测响应变量值

3. 变量选择

变量选择准则

## 平均残差平方和准则 (RMSq)
RMSq <- SSeq/(n-q)
## Cp准则
Cp <- SSeq/sigma2-(n-2*q)
## 赤池信息准则 (AIC/BIC)
AIC <- (-2)*lnL+2*q
BIC <- (-2)*lnL+q*log(n)

# (下面代码假设有3个自变量)
e <- list()
SSeq<-matrix(1,nrow=7); RMS<-matrix(1,nrow=7); Cp<-matrix(1,nrow=7); 
lnL<-matrix(1,nrow=7); AIC<-matrix(1,nrow=7); BIC<-matrix(1,nrow=7);
q<-matrix(c(2,2,2,3,3,3,4),nrow=1)
e[[7]] <- resid(lmlist[[7]])
for(i in 1:7)
{
  e[[i]] <- resid(lmlist[[i]])
  SSeq[i]<- t(e[[i]])%*%e[[i]]
  RMS[i]<-SSeq[i]/(n-q[i])
  Cp[i] <-SSeq[i]/(sd(e[[7]])^2*(n-1)/(n-p))-n+2*q[i]
  lnL[i]<-(-n/2)*(log(SSeq[i])+log(2*pi/n)+1)
  AIC[i]<-(-2)*lnL[i]+2*q[i]   ||  AIC(lmlist[[i]])   # 两者的结果有一点差异
  BIC[i]<-(-2)*lnL[i]+q[i]*log(n)  ||  BIC(lmlist[[i]])   # 两者的结果有一点差异
} 
COM<-data.frame(row.names=c('x1','x2','x3','x1 x2','x1 x3','x2 x3','x1 x2 x3'),RMS,Cp,AIC)
COM

逐步回归

library(MASS)
exps <- stepAIC(lm,scope= ,direction=<"both"/"forward"/"backward">...)
summary(exps)

全子集回归

library(leaps)
leaps <- regsubsets(y~.,data= ,nbest=<n>)   # nbest表示展示n个最佳的子集回归模型
plot(leaps,scale="adjr2") #绘图展示子模型和调整R平方的结果
coef(leaps,6)

sleaps <- summary(leaps)
names(sleaps)  # "which"  "rsq"    "rss"    "adjr2"  "cp"     "bic"    "outmat" "obj" 
plot(reg.summary$adjr2,xlab="Number of Variables",ylab="Adjusted RSq",type="l")
i <- which.max(reg.summary$adjr2)
points(i,reg.summary$adjr2[i], col="red",cex=2,pch=20)

res <- data.frame(sleaps$outmat,调整R平方=sleaps$adjr2)
res   #表格展示子模型和调整R平方的结果

library(car)
subsets(leaps,statistic="cp",main="Cp Plot for All subsets Regression")   #基于Cp统计量的不同子模型的比较
abline(1,1,lty=2,col="red")

向前/向后回归

regfit.fwd=regsubsets(y~.,data=,nvmax=,method="forward")#向前逐步选择
summary(regfit.fwd)
regfit.bwd=regsubsets(y~.,data=,nvmax=,method="backward") #向后逐步选择
summary(regfit.bwd)
coef(regfit.fwd,7)
coef(regfit.bwd,7)

模型选择

set.seed(1)
train=sample(c(TRUE,FALSE), nrow(dataset),rep=TRUE) #rep是replace
test=(!train)
regfit.best=regsubsets(y~.,data=dataset[train,],nvmax=19)
test.mat=model.matrix(y~.,data=dataset[test,])#此函数用于生成回归设计矩阵
val.errors=rep(NA,19)
for(i in 1:19){
  coefi=coef(regfit.best,id=i)
  pred=test.mat[,names(coefi)]%*%coefi
  val.errors[i]=mean((Hitters$Salary[test]-pred)^2)
}
val.errors
which.min(val.errors)
coef(regfit.best,10)

#以上程序有点冗余,可以编写预测函数
predict.regsubsets=function(object,newdata,id,...){
  form=as.formula(object$call[[2]])
  mat=model.matrix(form,newdata)
  coefi=coef(object,id=id)
  xvars=names(coefi)
  mat[,xvars]%*%coefi
}
regfit.best=regsubsets(y~.,data=dataset,nvmax=19)
coef(regfit.best,10)

# k折交叉验证
k=10
set.seed(1)
folds=sample(1:k,nrow(dataset),replace=TRUE)
cv.errors=matrix(NA,k,19, dimnames=list(NULL, paste(1:19)))
for(j in 1:k){
 best.fit=regsubsets(y~.,data=dataset[folds!=j,],nvmax=19)
  for(i in 1:19){
    pred=predict.regsubsets(best.fit,dataset[folds==j,],id=i)#这里可以简化为predict
    cv.errors[j,i]=mean( (dataset$y[folds==j]-pred)^2)
  }
}
mean.cv.errors=apply(cv.errors,2,mean)
mean.cv.errors
par(mfrow=c(1,1))
plot(mean.cv.errors,type='b')
reg.best=regsubsets(y~.,data=dataset, nvmax=19)
coef(reg.best,11)

4. 回归诊断

综合诊断

# 残差图、QQ图、位置尺度图、cook统计量图
plot(fit)
par(mfrow=c(2,2)); plot(fit)  # 生成在一张图中

# 模型假设通过与否的综合检验
library(gvlma)
gvmodel <- gvlma(fit)
summary(gvmodel)

对误差项假设的诊断

## 残差的计算
resid() or residuals()   # 拟合模型的残差值(SSe)
resid()/sd(resid())  #标准化残差
rstudent()  # 学生化残差(ri)

## 正态性诊断
# ①正态QQ图
library(car)
qqPlot()
# ②学生化残差柱状图
residplot <- function(fit,nbreaks=10)
{
  z<-rstudent(fit)
  hist(z,breaks=nbreaks,freq=FALSE,xlab="Studentized Residual",main="Distribution of Errors")
  rug(jitter(z),col="brown")
  curve(dnorm(x,mean=mean(z),sd=sd(z)),add=TRUE,col="blue",lwd=2)
  lines(density(z)$x,density(z)$y,col="red",lwd=2,lty=2)
  legend("topright",legend=c("Normal Curve","Kernel Density Curve"),lty=1:2,col=c("blue","red"),cex=.7)
 }
residplot(lm)

## 误差独立性诊断
# Durbin-Watson检验 (p-value>0.05 → 无自相关性,误差项之间独立)
durbinWatsonTest(lm)

## 线性诊断
# 成分残差图(偏残差图)
library(car)
crPlots(lm)

## 同方差性诊断
ncvTest(lm) #生成计分检验,零假设为误差方差不变
spreadLevelPlot(lm) #生成最佳拟合曲线的散点图

异常观测值的影响分析

## 异常值点(离群点——模型预测效果不佳的观测点,有很大的残差值)
# ①QQ图——落在置信区间以外的点
# ②标准化残差值大于2或小于-2的点
# ③根据单个最大残差值的显著性判断模型是否存在离群点
outlierTest()  # p-value<0.05, 判定为离群点

## 强影响点(对模型参数估计值影响比例失衡的点)
# ①Cook距离(D统计量 > 4/(n-p-1))
cutoff <- 4/(nrow(data)-length(fit$coefficients)-2)
plot(fit,which=4,cook.levels=cutoff)
abline(h=cutoff,lty=2,col="red")
# ②变量添加图(提供关于强影响点如何影响模型的信息)
library(car)
avPlots(fit,ask=FALSE)

## 高杠杆值点(与其他预测变量有关的离群点,由许多异常的预测变量值组合起来,与响应变量没有关系)
# 帽子统计量(hatvalue > 2or3*p/n)
hat.plot <- function(fit){
	p <- length(coefficients(fit))
	n <- length(fitted(fit))
	plot(hatvalues(fit),main="Index Plot of Hat Values")
	abline(h=c(2,3)*p/n,col="red",lty=2)
	idenfify(1:n,hatvalues(fit),names(hatvalues(fit)))
	}  #identify选项可以在图中交互式标注离群点
hat.plot(fit)

## 综合
library(car)
influencePlot(fit,main="Influence Plot",sub="Circle size is proportional to Cook's distance")
# 纵坐标超过2或-2的可能是离群点,横坐标超过0.2或0.3的可能是高杠杆值点,圆圈较大的可能是强影响点

多重共线性诊断

## 方差膨胀因子 vif=1/(1-R^2), vif越大,变量之间的线性相关程度越大
#(一般vif>10表明存在严重多重共线性,剔除该变量;或计vif的均值>1)
#当样本量不算小,而R2接近1时,可以认为存在严重的多重共线性
library(car)
vif(lm) 

## 条件数 k(lambda(1)/lambda(p-1)) 
# (<=100:共线性的程度较小 100~1000:存在较强的多重共线性   >1000:存在严重的多重共线性)
X <- scale(as.matrix(data[2:]));X
kappa(t(X)%*%X,exact=TRUE)

## 另:计算矩阵的特征值
lambda <- eigen(t(X)%*%X)
lambda$values[1]/lambda$values[p-1]

5. 改进措施

1.删除观测点
2.增删变量(删除有多重共线性的变量)
3.Box-Cox变换(变换Y)

bc<-boxcox(y~ ,lambda=seq(-2,2,0.01))

lambda<-bc$x[which.max(bc$y)] 
lambda

y_bc<-(y^lambda-1)/lambda 
lm_bc<-lm(y_bc~I(x1^2)+x2)
summary(lm_bc)

par(mfrow=c(2,2))
plot(lm_bc)

4.Box-Cox变换、Box-Tidwell变换(变换X)

# Box-Cox变换(适用于模型违反正态假设的情况)
library(car)
summary(powerTranform(x))
# Box-Tidwell变换(适用于模型违反线性假设的情况)
library(car)
boxTidwell(y~x1+x2)

5.尝试其他方法(岭回归、稳健回归、非参数回归、非线性回归、时间序列、多层次回归、广义线性回归)

6. 岭回归

8. 其他

有交互项的线性回归

lm<-lm(y~x1+x2+x1:x2)
library(effects)
plot(effect("x1:x2",lm,,list(x1=c()),multiline=TRUE)

深层次分析——交叉验证(刀切法)

shrinkage <- function(fit,k=10){
	  require(bootstrap)
	  x <- fit$model[,2:ncol(fit$model)]
	  y <- fit$model[,1]
	  theta.fit <- function(x,y){lsfit(x,y)}
	  theta.predict <- function(fit,x){as.matrix(cbind(1,x),nrow=18)%*%(as.matrix(fit$coef))}
	  results <- crossval(t(as.matrix(x,nrow=18)),y,theta.fit,theta.predict,ngroup=k)
	  r2 <- cor(y,fit$fitted.values)^2
	  r2cv <- cor(y,results$cv.fit)^2
	  cat("Original R-square = ",r2,"\n")
	  cat(k,"Fold Cross-Validated R-square = ",r2cv,"\n")
	  cat("Change = ",r2-r2cv,"\n")
}
shrinkage(lm)
# 代码有点问题

深层次分析——变量的相对重要性

# 标准化(先将数据标准化后再做回归分析)
zdata <- scale(data) 

# 相对权重(对所有可能子模型添加一个预测变量引起的R平方平均增加量的近似值,结果显示各变量对R平方的解释比例)
relweights <- function(fit,...){
	  R <- cor(fit$model)
	  nvar <- ncol(R)
	  rxx <- R[2:nvar,2:nvar]
	  rxy <- R[2:nvar,1]
	  svd <- eigen(rxx)
	  evec <- svd$vectors
	  ev <- svd$values
	  delta <- diag(sqrt(ev))
	  lambda <- evec %*% delta %*% t(evec)
	  lambdasq <- lambda^2
	  beta <- solve(lambda) %*% rxy
	  rsquare <- colSums(beta^2)
	  rawwgt <- lambdasq %*% beta^2
	  import <- (rawwgt / rsquare)*100
	  import <- as.data.frame(import)
	  row.names(import) <- names(fit$model[2:nvar])
	  names(import) <- "Weights"
	  import <- import[order(import),1,drop=FALSE]
	  dotchart(import$Weights,labels=row.names(import),xlab="% of R-Square",pch=19,
	           main="Relative Importance of Predictor Variables",
	           sub=paste("Total R-Square= ", round(rsquare,digits=3)),...)
	  return(import)
}
relweights(fit)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

R语言与线性回归分析 的相关文章

  • LaTex 中与 knit 和 xtable 交叉引用的问题

    我目前正在与 R Studio 合作 使用 LaTex 中的 R knitr 生成 PDF 文档 在这些文档中 我想在文本中引用的表格中展示我的部分结果 我使用 R 中的 xtable 包生成这些表 它运行良好并为我提供了正确的表 到目前为
  • R 根据事件更新值

    我最近发布了这个问题 该问题已经与我在笔记本电脑上本地使用的 Mysql 数据库相关 由于我在 Mysql 中没有找到问题的解决方案 其他人似乎也没有找到解决方案 所以我想再次发布它 但现在与 R 相关 我使用带有 RMysql 包的数据库
  • 基于另一个数据集获取数据集的子集

    假设我有一个数据集 即 dat1 ID block plot SPID TotHeight 1 1 1 4 44 5 2 1 1 4 51 3 1 1 4 28 7 4 1 1 4 24 5 5 1 1 4 27 3 6 1 1 4 20
  • 计算例如具有多列 data.frames 的列表中的平均值

    我有几个 data frames 的列表 每个 data frame 有几列 通过使用mean mylist first dataframe a我可以得到这个 data frame 中 a 的平均值 但是我不知道如何计算列表中存储的所有 d
  • 如何在 ggplot 中保持配色方案,同时删除每个图中未使用的级别?

    我想比较一个图中的数据的一些子组和另一图中的一些其他子组 如果我绘制一个图 其中绘制了所有子组 那么这个数字将是巨大的 并且每个单独的比较都会变得困难 我认为如果给定的子组在所有图中都具有相同的颜色 这对读者来说会更有意义 这是我尝试过的两
  • 如何在for循环中引用变量?

    我正在循环访问不同的 data tables 和 data table 中的变量 但我在引用内部变量时遇到问题for loop dt1 lt data table a1 c 1 2 3 a2 c 4 5 2 dt2 lt data tabl
  • 删除ggplot2中的负图区域[重复]

    这个问题在这里已经有答案了 如何删除 ggplot2 中 x 轴和 y 轴下方的绘图区域 请参见下面的示例 我尝试了几个主题元素 panel border panel margin plot margin 但没有任何运气 p lt ggpl
  • 重复测量引导统计数据,按多个因素分组

    我有一个看起来像这样的数据框 但显然还有更多行等 df lt data frame id c 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 cond c A A B B A A B B A A B B A A B B co
  • 使用 purrr 迭代替换数据帧列中的字符串

    我想用purrr使用以下命令在数据框列上迭代运行多个字符串替换gsub 功能 这是示例数据框 df lt data frame Year 2019 Text c rep a aa 5 rep a bb 3 rep a cc 2 gt df
  • 如何计算R中移动窗口内的平均斜率

    我的数据集包含2个变量y 和 t 05s y 每 05 秒测量一次 我正在尝试计算移动中的平均坡度20秒窗口 即计算第一个 20 秒斜率值后 窗口向前移动一个时间单位 05 秒 并计算下一个 20 秒窗口 在以下位置生成连续 20 秒斜率值
  • 多功能测试仪替代 system.time

    我已经看到 我认为是这样 使用了类似于 system time 的函数 它可以同时评估多个函数的时间并输出一个输出 我不记得它是什么 并且用我正在使用的术语进行互联网搜索并没有得到我想要的响应 有人知道我正在谈论的功能的名称 位置吗 你想要
  • Dendextend:关于如何根据定义的组为树状图的标签着色

    我正在尝试使用一个名为 dendextend 的很棒的 R 包来绘制树状图并根据一组先前定义的组为其分支和标签着色 我已阅读您在 Stack Overflow 中的答案以及 dendextend vignette 的常见问题解答 但我仍然不
  • R独特的列或行与NA无可比拟

    有谁知道如果incomparables的论证unique or duplicated 曾经被实施过incomparables FALSE 也许我不明白它应该如何工作 无论如何 我正在寻找一个巧妙的解决方案 以仅保留与另一列相同的唯一列 或行
  • 为什么 dplyr filter() 不能在函数内工作(即使用变量作为列名)?

    使用 dplyr 函数对数据进行过滤 分组和变异的函数 基本管道序列在函数之外工作得很好 这就是我使用真实列名称的地方 将其放入一个函数中 其中列名称是一个变量 并且某些函数可以工作 但有些函数则不能 尤其是 dplyr filter 例如
  • 在 R 格子包中微调点图

    我正在尝试为不同的数据集和不同的算法绘制一堆 ROC 区域 我有三个变量 方案 指定所使用的算法 数据集 是正在测试算法的数据集 以及 Area under ROC 我正在 R 中使用lattice库 命令如下 点图 方案 Area und
  • 使用 R 选择第一个非 NA 值

    df lt data frame ID c 1 1 1 2 3 3 3 test c NA 5 5 6 4 NA 7 3 NA 10 9 我想创建一个名为 value 的变量 它是每个单独 ID 测试的第一个非 NA 值 对于只有NA的个体
  • R 中的列乘以子字符串

    假设我有一个数据框 其中包含多个组件及其在多个列中列出的属性 并且我想对这些列运行多个函数 我的方法是尝试将其基于每个列标题中的子字符串 但我无法弄清楚如何做到这一点 下面是数据框的示例 Basket F Type 1 F Qty 1 F
  • 将每列的值乘以 R 中另一个 data.frame 中的权重

    我有两个data frames df and weights 代码如下 df看起来像这样 id a b d EE f 1 this 0 23421153 0 02324956 0 5457353 0 73068586 0 5642554 2
  • 将数据框中重叠的范围合并到唯一的组中

    我有一个 n 行 3 的数据框 df lt data frame start c 178 400 983 1932 33653 end c 5025 5025 5535 6918 38197 group c 1 1 2 2 3 df sta
  • 将阴影区域添加到五分位数之间的直方图中

    All 我有一个包含 2 个直方图的图表 其中我还绘制了代表第 20 40 60 和 80 个百分位数的线条 下面的代码使用虚拟数据重现了类似的图表 data lt rbind data frame x rnorm 1000 0 1 g o

随机推荐