glmnet

作者: nnlrl | 来源:发表于2020-04-13 21:07 被阅读0次
    • Glmnet主要用于拟合广义线性模型。筛选可以使loss达到最小的正则化参数lambda。该算法非常快,并且可以使用稀疏矩阵作为输入。主要有线性模型用于回归,logistic回归进行分类以及cox模型进行生存分析。可以从拟合模型中做出各种预测。它也可以拟合多响应线性回归。


      公式

    其中l(y,η)是观测i的负对数似然,样本不同的分布具有不同的形式,对于高斯分布可以写为 1/2(y−η)^2,后一项是elastic-net正则化项,beta是需要学习的参数,alpha指定使用Lasso回归(alpha = 1)还是岭回归(alpha = 0)。当我们具有较多的特征时,我们希望进行特征的筛选,Lasso回归会使特征稀疏化,保留部分特征用于构建模型,如果我们不希望舍去任何一个特征,那么便可以使用岭回归。

    对于每种模型Glmnet都提供了glmnet用于拟合模型, cv.glmnet使用k折交叉验证拟合模型, predict对数据进行预测(分类/回归),coef用于提取指定lambda时特征的系数。

    线性模型

    线性回归Glmnet主要包含两类模型。包括gaussian (the Gaussian family)和mgaussian (the multiresponse Gaussian family)。

    Gaussian Family

    适用于因变量y只有一维的时候

    library(glmnet)
    data(QuickStartExample)
    
    #首先使用glmnet拟合线性模型,使用alpha = 0.2和20个lambda进行搜索,并给予
    #后50个样本更高的权重
    fit = glmnet(x, y, alpha = 0.2, weights = c(rep(1,50),rep(2,50)), nlambda = 20)
    
    print(fit)
    
    ## 
    ## Call:  glmnet(x = x, y = y, weights = c(rep(1, 50), rep(2, 50)), alpha = 0.2,      nlambda = 20) 
    ## 
    ##    Df   %Dev Lambda
    ## 1   0 0.0000 7.9390
    ## 2   4 0.1789 4.8890
    ## 3   7 0.4445 3.0110
    ## 4   7 0.6567 1.8540
    ## 5   8 0.7850 1.1420
    ## 6   9 0.8539 0.7033
    ## 7  10 0.8867 0.4331
    ## 8  11 0.9025 0.2667
    ## 9  14 0.9101 0.1643
    ## 10 17 0.9138 0.1012
    ## 11 17 0.9154 0.0623
    ## 12 17 0.9160 0.0384
    ## 13 19 0.9163 0.0236
    ## 14 20 0.9164 0.0146
    ## 15 20 0.9164 0.0090
    ## 16 20 0.9165 0.0055
    ## 17 20 0.9165 0.0034
    

    其中%Dev表示模型的可解释偏差,值越大表明该模型包括了越多样本的信息,Lambda则表示20个Lambda对应的值。

    #我们也可以绘图展示根据lambda变化情况每一个特征的系数变化
    plot(fit, xvar = "lambda", label = TRUE)
    
    #也可以对%dev绘图
    plot(fit, xvar = "dev", label = TRUE)
    

    如果我们在构建模型的过程中想要使用交叉验证,则可以使用cv.glmnet函数,type.measure表示模型的损失函数,默认为均方误差,nfolds指定k的大小,默认是20折交叉验证

    cvfit = cv.glmnet(x, y, type.measure = "mse", nfolds = 20)
    
    #这时对模型绘图展示的是不同的结果
    plot(cvfit)
    
    • x轴代表经过log以后的lambda值,y轴代表模型的误差,cv.glmnet会自动选择使误差最小的lambda(左侧的虚线),最小的lambda值保存在cvfit$lambda.min

    • 同时我们也可以使用coef提取每一个特征在指定lambda下的系数,一旦模型训练完成,我们也可以使用predict对新数据进行预测

    #提取lambda = 0.5时20个输入特征的系数,· 代表经过L1正则化后这些特征已经被消掉了。
    coef.apprx = coef(fit, s = 0.5)
    
    #输出新数据的预测值,type参数允许选择预测的类型并提供预测值
    predict(fit, newx = x[1:5,], type = "response", s = 0.05)
    

    Multiresponse Gaussian Family

    当我们需要预测多个值时,简单的高斯模型已经不能满足了,这时候我们需要使用family = "mgaussian"拟合模型,即所谓的“多任务学习”问题。

    #导入示例数据,包括100例样本,20个特征以及4个输出值
    data(MultiGaussianExample)
    
    #参数几乎与普通高斯模型相同,例如alpha、weights、nlambda、standard
    mfit = glmnet(x, y, family = "mgaussian")
    

    同样我们可以plot模型的系数

    #这里的设置type.coef=“2norm”。在此设置下,每个变量绘制一条曲线,等同于L2
    #正则化。默认设置为type.coef=“coef”,为每一个因变量绘制一张系数图
    plot(mfit, xvar = "lambda", label = TRUE, type.coef = "2norm")
    

    其余操作与上边没有差别,使用cv.glmnet进行交叉验证,使用predict进行预测以及coef提取系数,不要忘了family = "mgaussian"

    Logistic Regression

    对于连续变量我们可以拟合GLM并对新样本进行预测,但当输出值为离散变量表示样本的分类情况时,我们就需要使用一种激活函数将输出值限定在0-1之间,用以代表模型输出该样本属于某一类别的概率

    Binomial Models

    当y仅包含两种分类时可以使用二分类模型,

    data(BinomialExample)
    
    #使用family = "binomial"拟合二分类模型
    fit = glmnet(x, y, family = "binomial")
    

    对于logistic回归,cv.glmnet具有与高斯模型相似的参数和用法。nfold、weights、lambda、parallel都可以使用。在type.measure中有一些差异:“deviance”代表实际偏差, “mae”代表平均绝对误差,“class”代表错配误差,“auc”(仅适用于二分类逻辑回归)并给出ROC曲线下的面积。

    #交叉验证
    cvfit = cv.glmnet(x, y, family = "binomial", type.measure = "class")
    
    #指定lambda在0.05和0.01时预测新样本的类别,type = "class"指定输出值为类别
    predict(fit, newx = x[1:5,], type = "class", s = c(0.05, 0.01))
    
    plot(cvfit)
    

    Multinomial Models

    对于多分类问题,其用法类似于二分类logistic回归。

    导入数据,包括1,2,3三个类别
    data(MultinomialExample)
    
    #拟合模型,其中多项式回归的一个特殊选项是type.multinomal,如果
    #type.multinomal=“grouped”,则允许使用分组套索回归。这将确保变量的多项式
    #系数都在一起,就像多变量高斯模型一样。
    fit = glmnet(x, y, family = "multinomial", type.multinomial = "grouped")
    
    #交叉验证
    cvfit=cv.glmnet(x, y, family="multinomial", type.multinomial = "grouped", parallel = TRUE)
    
    #绘图展示
    plot(fit, xvar = "lambda", label = TRUE, type.coef = "2norm")
    plot(cvfit)
    
    #预测模型
    predict(cvfit, newx = x[1:10,], s = "lambda.min", type = "class")
    

    请注意,虽然type.multinomal不是cv.glmnet中的参数,但实际上,可以传递给glmnet的任何参数在cv.glmnet的参数列表中都是有效的。我们还使用并行计算来加速计算。在预测过程中,我们只需要在predict中指定type = "class"

    Cox回归

    在Glmnet中还可以使用Cox风险比例模型,常用于研究预测变量与生存时间的关系。在通常的生存分析框架中,我们有生存时间以及生存状态(0=alive,1=dead)。

    #导入数据
    data(CoxExample)
    
    #拟合模型,指定family = "cox"
    fit = glmnet(x, y, family = "cox")
    
    plot(fit)
    
    #交叉验证构建模型
    cvfit = cv.glmnet(x, y, family = "cox")
    
    plot(cvfit)
    

    总结一下:

    • 当我们构建回归模型时,y为连续变量,指定family = "gaussian/mgaussian"构建广义线性模型,在使用交叉验证cv.glmnet时损失函数选用type.measure = "mse"使用均方误差,使用predict预测新样本时指定type = "response"输出预测值。

    • 当我们构建分类模型时,y为离散变量代表分类数据,指定family = "binomial/multinomial"以及type.multinomial = "grouped"构建逻辑回归模型,在使用交叉验证cv.glmnet时损失函数选用type.measure = "class/auc"使用错配误差或auc(二分类),使用predict预测新样本时指定type = "class"输出预测的类。

    • 当我们构建Cox回归模型时,y为离散变量代表分类数据,指定family = "cox"构建Cox回归模型

    相关文章

      网友评论

        本文标题:glmnet

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