美文网首页生物信息学与算法数据科学与R语言statistic
StatQuest学习笔记|在R中进行Ridge Regress

StatQuest学习笔记|在R中进行Ridge Regress

作者: 亚里亚的塔 | 来源:发表于2020-02-22 20:49 被阅读0次

    原理

    Ridge Regression,Lasso Regression和Elastic-Net Regression都是通过增加一个惩罚项让模型less sensitive。


    Ridge Regression

    以该图为例,红色的点为training data, 绿色的点为test data。虽然通过两个红色的点能得到一条完全拟合的线,但是这条红线对绿色的点预测较差差。
    加入惩罚项之后,得到蓝色的线,与红色点拟合度降低的同时,对绿色的点预测更准确。
    Ridge Regression,Lasso Regression和Elastic-Net Regression原理如下:


    Ridge Regression and Lasso Regression
    Elastic-Net Regression
    三种原理相似,区别在于Ridge Regression适用于变量对模型都有贡献,分析过程中不排除变量;Lasso Regression适用于存在大量干扰变量,分析过程中可以排除无关变量使其贡献为0;Elastic-Net Regression适用于存在大量变量但是不知道哪些有用哪些没用。
    Regularization

    建立数据集

    在没有数据的情况下建立一个数据集来模拟分析吧
    先建立一个1000个容量,有5000个参数,但是实际上只有15个有用参数的数据集

    set.seed(42)
    #1000个样本
    n <- 1000
    #5000个参数
    p <- 5000
    #15个有用的参数
    real_p <- 15
    x <- matrix(rnorm(n*p), nrow=n, ncol=p)
    ##y的结果是x前15列的和,加上一些干扰项
    y <- apply(x[,1:real_p], 1, sum) + rnorm(n))
    

    做好了数据集,我们来尝试用x预测y,可以看出这个数据集存在大量没用参数,理论上来讲Lasso Regression使最合适的

    分析

    调用包

    在R中,Ridge Regression,Lasso Regression和Elastic-Net Regression都可以用同一个包glmnet

    glmnet原理,当α=0是球的是Ridge Regression,当α=1求得是Lasso Regression,当α介于0到1之间是求得是Elastic-Net Regression
    library(glmnet)
    

    区分好训练集和测试集

    #将数据分为training和testing
    #设定某些行为训练集
    #在1:n之间随意选一个属,选中所有0.66*n的数,三分之二的数为train dataset, 行名保存在train_rows里面
    train_rows <- sample(1:n, .66*n)
    #根据train_rows作为索引,创建新的matrix,只含training data
    x.train <- x[train_rows,]
    #test data就是排除train data的
    x.test <- x[-train_rows,]
    
    #同样,将y也中的数据也分为训练和测试
    y.train <- y[train_rows]
    y.test <- y[-train_rows]
    

    Ridge regression

    #先用训练集建立模型, cv(corss validation),默认为10-Fold Cross Validation #
    #前两个参数确定训练集,在本例中,我们想用x.train去预测y.train
    #liner regression中type.measure="mse" mean squared error = suquared ressiduals/ sample size(如果要用logistic Regression,参数为deciance)
    #ridge regression,所以alpha为0
    #liner regression中family="gaussian" ; (logistic regression set "binomial")
    #整个函数的意思是用cv.glmnet(),10-Fold Cross Validation, 拟合一个带有ridge regression惩罚项的linear regression,从而得到最优λ
    alpha0.fit <- cv.glmnet(x.train,y.train, type.measure="mse", 
    alpha=0, family="gaussian")
    #现在将预测函数在testing中得到验证,预测数据保存
    #第一个参数是预测模型,第二个参数是λ的值,能得到最简模型,虽然ridgere gression中可用lambda.min替代(不需要排除参数),为了比较三个模型,在这里统一设置lambda.1se
    #news=x.test,
    alpha0.predicted <- 
    predict(alpha0.fit, s=alpha0.fit$lambda.1se, newx=x.test)
    #比较真实值和预测值
    mean((y.test - alpha0.predicted)^2)
    

    lasso regression

    alpha1.fit <- cv.glmnet(x.train,y.train, type.measure="mse", 
    alpha=1, family="gaussian")
    alpha1.predicted <- 
    predict(alpha1.fit, s=alpha1.fit$lambda.1se, newx=x.test)
    mean((y.test - alpha1.predicted)^2)
    

    Elastic-Net Regression

    先随便指定一下

    α=0.5时

    alpha0.5.fit <- cv.glmnet(x.train,y.train, type.measure="mse", 
    alpha=0.5, family="gaussian")
    alpha0.5.predicted <- 
    predict(alpha0.5.fit, s=alpha0.5.fit$lambda.1se, newx=x.test)
    mean((y.test - alpha0.5.predicted)^2)
    

    用循环实现α=0.1, 0.2, ..., 1

    来看三种方法到底哪个算的mean更小

    list.of.fits <- list()
    #用for来尝试不同的alpha
    for(i in 0:10:{
    fit.name <- paste0("alpha", i/10)
    list.of.fits[[fit.name]] <- 
     cv.glmnet(x.train,y.train, type.measure="mse", 
    alpha=i/10, family="gaussian")
    }
    #alpha 取值0.1, 0.2, ..., 1
    
    results <- data.frame()
    for(i in 0:10){
    fit.name <- paste0("alpha", i/10)
    predicted <-
    predict(list.of.fits[[fit.name]],
    s=list.of.fits[[fit.name]],
    s=list.of.fits[[fit.name]]$lambda.1se, newx=x.test)
    
    mse <- mean((y.test - predicted)^2)
    
    temp <- data.frame(alpha=i/10, mse=mse, fit.name=fit.name)
    results <- rbind(results, temp)
    }
    
    results
    

    结果

    statquest范例结果

    可以看出当alpha=1 mse最小,这时实际上是Lasso Regression。
    也证实了在有大量无用参数时,Lasson Regression比较合适。

    相关文章

      网友评论

        本文标题:StatQuest学习笔记|在R中进行Ridge Regress

        本文链接:https://www.haomeiwen.com/subject/mgxrqhtx.html