使用glmnet进行描述性统计时,lambda的值是多少

使用glmnet进行描述性统计时,lambda的值是多少,lambda,logistic-regression,glmnet,Lambda,Logistic Regression,Glmnet,我正在进行一项描述性而非预测性分析,借此我希望比较逻辑回归类型问题中系数的大小——包括截距。由于每个变量都需要描述,我尝试了标准的glm logit回归,知道许多变量至少部分相关,我也尝试了岭回归,看看它有什么不同 我遇到的问题是,我看到的所有指南都建议识别lambda.min或lambda.1se处的系数,但是对我来说,lambda的这个值处的系数都是零。我可以任意选择lambda来返回值,但我不知道这是否正确 require(glmnet) CT.base <- readRDS('C

我正在进行一项描述性而非预测性分析,借此我希望比较逻辑回归类型问题中系数的大小——包括截距。由于每个变量都需要描述,我尝试了标准的glm logit回归,知道许多变量至少部分相关,我也尝试了岭回归,看看它有什么不同

我遇到的问题是,我看到的所有指南都建议识别lambda.min或lambda.1se处的系数,但是对我来说,lambda的这个值处的系数都是零。我可以任意选择lambda来返回值,但我不知道这是否正确

require(glmnet)

CT.base <- readRDS('CTBaseObj.rds') #readRDS data objects


regular <- glm(Flag ~ . - Occurrences , family = binomial(link="logit"), 
               data = CT.base, weights = Occurrences, maxit = 50)

#Ridge
x <- model.matrix(Flag ~ . - Occurrences, CT.base)
x <- x[, !colnames(x) %in% '(Intercept)']
y <- CT.base$Flag
w <- CT.base$Occurrences

CT.cv <- cv.glmnet(x, y , family = "binomial", 
                   weights = w, alpha = 0.0, parallel = T, type.measure = "class")
plot(CT.cv)
我已经链接了这背后的数据集的再现性,但这可能不是必要的!欣然接受任何建议


谢谢。

您的模型存在的问题是,您对观测值施加的权重非常不平衡,其中一个权重为20000000,而许多权重为1,没有一个权重超过10000

par(mfrow = c(1,2))
boxplot(w)
boxplot(log(w))
在这种情况下,模型只能做很多事情,但总是用巨大的权重预测观测值,并将所有系数收缩到零。您可以通过以下方式看到这一点:

CT <- glmnet(x, y , family = "binomial", 
                   weights = w, alpha = 0)

all(predict(CT, x, CT.cv$lambda.min, type= "class") == 0)
#TRUE

y[which.max(w)]
#0
事实上,当模型只预测更丰富的类别时,它最大限度地减少了分类失误。这可以通过增加与类别1成员关联的权重来解释。或者通过选择另一个度量,如平衡精度、平衡错误率或精度召回曲线下的面积进行模型拟合。不幸的是,glment软件包不提供此选项。但你可以看看包装插入符号或mlr

如果您使用auc:

CT.cv <- cv.glmnet(x, y , family = "binomial", 
                   alpha = 0, type.measure = "auc")
plot(CT.cv)
成为一名学习者:

lrn <- makeLearner("classif.glmnet", predict.type = 'prob', alpha = 0)
创建列车数据集:

mlr_train <- data.frame(x,
                        y = as.factor(y))
我们将只调整0-10范围内的lambda:

ps <- makeParamSet(
  makeNumericParam("lambda", lower = 0, upper = 10))

cv10 denotes 10 fold CV
bac is balanced accuracy it wil be used as selection metric

z <- tuneParams(lrn, task, cv10, par.set = ps, control = ctrl, 
          show.info = TRUE, measures = list(bac, setAggregation(bac, test.sd)))

> z
Tune result:
Op. pars: lambda=0.0503
Threshold: 0.07
bac.test.mean=0.5615910,bac.test.sd=0.0394965

因此,为了最大限度地提高平衡精度,需要选择lambda=0.0503和阈值0.07。考虑到这个阈值,我将放弃这种方法中的一种,然后重新调整正类的权重

我认为你强加给受试者的荒谬权重导致了这种行为。拥有一个2000万的重量和许多其他1显然与模型混乱。只有权重最高的观测才有机会被预测,因此所有coef都可以缩小到零。感谢您的广泛回答-感谢您花费的时间。荒谬的权重实际上是现实生活中的发现,我们很早就把它们引入了logit模型,系数估计值没有大的变化——这是一个人口权重。我理解ridge在处理这个问题的方式上可能有所不同,我可能不得不回到标准logit,因为我需要的是描述性系数,而不是预测能力。@Jon也许你只对概率以及系数如何影响它们感兴趣。在我看来,考虑到在非常低的概率阈值下非常适度的平衡精度,ridge在这种情况下似乎不能提供有用的见解,但我可能是错的,因为我从未以这种方式实际探索过它。
CT <- glmnet(x, y , family = "binomial", 
                    alpha = 0, lambda = CT.cv$lambda.min)

all(predict(CT, x, CT.cv$lambda.min, type= "class") == 0)
library(mlr)
lrn <- makeLearner("classif.glmnet", predict.type = 'prob', alpha = 0)
getParamSet(lrn)
mlr_train <- data.frame(x,
                        y = as.factor(y))
task <- makeClassifTask(data = mlr_train, target = "y",  positive = "1")
ctrl = makeTuneControlGrid(resolution = 200, tune.threshold = TRUE)
ps <- makeParamSet(
  makeNumericParam("lambda", lower = 0, upper = 10))

cv10 denotes 10 fold CV
bac is balanced accuracy it wil be used as selection metric

z <- tuneParams(lrn, task, cv10, par.set = ps, control = ctrl, 
          show.info = TRUE, measures = list(bac, setAggregation(bac, test.sd)))

> z
Tune result:
Op. pars: lambda=0.0503
Threshold: 0.07
bac.test.mean=0.5615910,bac.test.sd=0.0394965