R语言与其它回归方法

文章目录

      • 1. 岭回归
      • 2. LASSO
      • 3. 主成分回归 - PCR
      • 4. 偏最小二乘回归 - PLS

压缩方法 & 降维方法

1. 岭回归

法①:lm.ridge函数

## lm.ridge函数进行岭回归
# 对样本数据进行标准化处理
data <- data.frame(scale(data0[,2:]))
# 对标准化处理后的数据(不含截距项)进行岭回归
library(MASS)
ridge <- lm.ridge(y~.-1, data= ,lambda=seq(0,3,0.1))
beta <- coef(ridge) ; beta
# 绘制岭迹图(部分格式调整不必要)
k <- ridge$lambda
plot(k,k,type="n",xlab="岭参数k",ylab="岭回归系数",ylim=c(-2.5,2.5))
linetype <- c(1:)   char <- c(18:)  #绘图格式调整
for(i in 1:)
	lines(k,beta[,i],type="o",lty=linetype[i],pch=char[i],cex=0.75)
legend(locator(1),inset=0.5,legend=c("x1","x2",...),cex=0.8,pch=char,lty=linetype)

## LinearRidge函数进行岭回归
library(ridge)
ridge <- linearRidge(y~ ,data= ,lambda="automatic",scaling=c("corrForm","scale","none"),...)
summary(ridge)  #多了参数检验的功能

案例:

#### 对数据进行标准化处理
scaledata <- scale(data)
X <- scaledata[,2:3]; Y <- scaledata[,1]; 
mean<-attr(scaledata,'scaled:center'); sd<-attr(scaledata,'scaled:scale')

#-----------------------------------------------------
#### 1. 复共线性判别
##* 使用方差膨胀因子
library(carData);library(car)
lm1 <- lm(Y~X1+X2,data=data.frame(scaledata))
vif(lm1) 
##* 使用条件数 k(lambda(1)/lambda(p-1)) 
# 用kappa函数直接计算
kappa(t(X)%*%X,exact=TRUE)
# 另法:手动计算矩阵的特征值并使用条件数k判别
Lambda <- eigen(t(X)%*%X)
Lambda$values[1]/Lambda$values[2]

#-----------------------------------------------------
#### 岭回归
# 对标准化后的数据采用不同的岭参数k建模
library(MASS)
ridge <- lm.ridge(Y~.-1, data=data.frame(scaledata),lambda=seq(0,0.3,0.01))
beta <- coef(ridge) ; beta
# 绘制岭迹图
k <- ridge$lambda
p <- plot(k,beta[,1],type="n",xlab="岭参数k",ylab="岭回归系数",xlim=c(0,0.3),ylim=c(-2,5))
linetype <- c(1:2) #绘图格式调整
for(i in 1:2)
  lines(k,beta[,i],type="l",lty=linetype[i],cex=0.75)
legend(0.25,5,legend=c("x1","x2"),cex=1,lty=linetype)
# 取岭参数k,使X1和X2的岭回归系数比较稳定,并计算此时的回归系数。

# 首先是标准化中心化后数据的回归模型
ridge <- lm.ridge(Y~X1+X2-1, data=data.frame(scaledata),lambda=0.08)
beta <- coef(ridge) ; beta
# 转化为原始数据后,回归系数为
Beta <- beta/sd[2:3]*sd[1]
Beta0 <- mean[1]-sum(beta*mean[2:3]/sd[2:3]*sd[1])
c(Beta0,Beta)

# 或者也可以直接用原始数据建模,得到同样的结果:
ridge <- lm.ridge(Y~X1+X2, data=X6_11,lambda=0.08)
beta <- coef(ridge) ; beta
# 参数Beta构成得到岭回归方程

法②:glmnet函数

library(glmnet)
grid=10^seq(10,-2,length=100)
ridge.mod=glmnet(x,y,alpha=0,lambda=grid)#此函数默认进行了标准化
#alpha=0拟合岭回归模型,alpha=1表示lasso模型
dim(coef(ridge.mod))   #20 100: 100个lambda的取值,分别对应20维的系数向量
ridge.mod$lambda[50] # 手动选取lambda为第50个取值
coef(ridge.mod)[,50]
sqrt(sum(coef(ridge.mod)[-1,50]^2))
predict(ridge.mod,s=50,type="coefficients")[1:20,]#预测系数

set.seed(1)
train=sample(1:nrow(x), nrow(x)/2)
test=(-train)
y.test=y[test]
ridge.mod=glmnet(x[train,],y[train],alpha=0,lambda=grid, thresh=1e-12)
ridge.pred=predict(ridge.mod,s=4,newx=x[test,]) #newx=x[test,]获得测试集的预测值(取lambda=4)
#求拟合模型的MSE
mean((ridge.pred-y.test)^2) 
#求只含截距项的模型的MSE
mean((mean(y[train])-y.test)^2) 
ridge.pred=predict(ridge.mod,s=1e10,newx=x[test,]) 
mean((ridge.pred-y.test)^2) 
#求最小二乘回归模型的MSE
ridge.pred=predict(ridge.mod,s=0,newx=x[test,],exact=T)
mean((ridge.pred-y.test)^2)
lm(y~x, subset=train)
predict(ridge.mod,s=0,type="coefficients")[1:20,]

#用交叉验证法选择λ
set.seed(1)
cv.out=cv.glmnet(x[train,],y[train],alpha=0)#内置交叉验证函数cv.glmnet使用十折交叉验证选择λ
plot(cv.out)
bestlam=cv.out$lambda.min
bestlam#211.7416
ridge.pred=predict(ridge.mod,s=bestlam,newx=x[test,])
mean((ridge.pred-y.test)^2)
out=glmnet(x,y,alpha=0)
predict(out,type="coefficients",s=bestlam)[1:20,]

2. LASSO

优点:系数估计是稀疏的(自动选择变量)

lasso.mod=glmnet(x[train,],y[train],alpha=1,lambda=grid)
plot(lasso.mod)

set.seed(1)
cv.out=cv.glmnet(x[train,],y[train],alpha=1)
plot(cv.out)
bestlam=cv.out$lambda.min
lasso.pred=predict(lasso.mod,s=bestlam,newx=x[test,])
mean((lasso.pred-y.test)^2)
out=glmnet(x,y,alpha=1,lambda=grid)
lasso.coef=predict(out,type="coefficients",s=bestlam)[1:20,]
lasso.coef
lasso.coef[lasso.coef!=0]

3. 主成分回归 - PCR

使用PCR方法前要先删除数据集中的缺失值
结果比较难解释
使预测变量可解释的方差最大化

法①:princomp函数

## princomp函数做主成分估计(主成分是标准化后自变量的线性组合)
# 对样本数据进行标准化处理
data <- data.frame(scale(data0[,2:]))
# 主成分估计及展示结果
pr <- princomp(~x1+x2+...,data= ,cor=T)
summary(pr,loadings=TRUE) #输出主成分分析的主要结果 ①
pre <- pr$scores[,1:2]; pre #输出前两个主成分的得分
# 应用主成分分析结果建立回归模型
data$z1 <- pre[,1]
data$z2 <- pre[,2]
pcr <- lm(y~z1+z2-1,data= )
summary(pcr)  #主成分的回归模型 ②
# 最终的回归方程只要把①中主成分的回归模型代入②式即可

案例:

#### 对数据进行标准化处理
scaledata <- scale(data)
X <- scaledata[,1:4]; Y <- scaledata[,5]; 
mean<-attr(scaledata,'scaled:center'); sd<-attr(scaledata,'scaled:scale')

#------------------------------------------------------------
#### 1. 复共线性判别
XX<-t(X)%*%X
kappa(XX,exact=TRUE)

#---------------------------------------------------------------
#### 2. 主成分分析
Lambda <- eigen(XX)$values;Lambda
plot(Lambda,type='o',xlab='i',ylab='lambda',xaxp=c(1,4,3))
# 前三个特征根lambda的贡献率(取值之和占总和的百分比)达到99.9%,所以保留前三个主成分进行分析
Vectors <- eigen(XX)$vectors[,1:3];Vectors
# 三个主成分分别由上面的Vectors向量给出

# 对主成分进行回归分析,有:
Z <- X%*%Vectors[,1:3]
YZ <- data.frame(cbind(Z,Y));names(YZ)[1:4]<-c('Z1','Z2','Z3','Y')
pca <- lm(Y~Z1+Z2+Z3-1,data=YZ);pca$coefficients#
# 可以写出主成分的回归方程

# 计算原始数据的主成分回归方程系数
beta<-Vectors[,1:3]%*%pca$coefficients;beta
Beta <- beta/sd[1:4]*sd[5]
Beta0 <- mean[5]-sum(beta*mean[1:4]/sd[1:4]*sd[5])
c(Beta0,Beta)

法②:pcr函数

library(pls)
set.seed(2)
pcr.fit=pcr(y~., data=,scale=TRUE,validation="CV")#validation="CV"使用十折交叉验证主成分个数
summary(pcr.fit)
validationplot(pcr.fit,val.type="MSEP")
set.seed(1)
pcr.fit=pcr(y~., data=,subset=train,scale=TRUE, validation="CV")
validationplot(pcr.fit,val.type="MSEP")#做出交叉验证mse图像
pcr.pred=predict(pcr.fit,x[test,],ncomp=7)
mean((pcr.pred-y.test)^2)
pcr.fit=pcr(y~x,scale=TRUE,ncomp=7)
summary(pcr.fit)

4. 偏最小二乘回归 - PLS

使预测变量和响应变量可解释的方差最大化

set.seed(1)
pls.fit=plsr(y~., data=,subset=train,scale=TRUE, validation="CV")
summary(pls.fit)
validationplot(pls.fit,val.type="MSEP")
pls.pred=predict(pls.fit,x[test,],ncomp=2)
mean((pls.pred-y.test)^2)
pls.fit=plsr(y~., data=,scale=TRUE,ncomp=2)
summary(pls.fit)

你可能感兴趣的:(R,ML)