逻辑回归模型(Logistic Regression Model)
建模
逻辑回归模型是一种 基于线性回归模型 的分类模型,将回归(regression)模型数值化(numeric)的优势用在了分类(classification)上。借助glmnet
包,以iris的前100位的两种花 setosa 和 versicolor 为例
library(glmnet)
## 数据处理
data <- iris[1:100,]
data$Species <- as.factor(as.numeric(data$Species)-1)
n=dim(data)[1]
set.seed(12345)
id <- sample(1:n, floor(n*0.5))
train <- data[id,] # 训练集 50%
test <- data[-id,] # 测试集 50%
## 建模
glm <- glm(formula = Species~., # 以Species为y,其他特征为X
family = binomial(link = "logit"), # 适用于逻辑回归的二项分布
data = train) # 训练集训练数据
## 输出predication
ptrain <- predict(glm, train, type = "response")
ptest <- predict(glm, test, type = "response")
## 判正:概率大于0.5为正(positive),小于等于0.5为负(negative)
train$predict <- as.numeric(ptrain>0.5)
test$predict <- as.numeric(ptest>0.5)
【注意,默认下predict返回线性回归的结果,不返回逻辑回归参数,要用response才能返回需要的概率。详细查看模型可用函数summary(glm)
】
混淆矩阵
混淆矩阵(confusion matrix)是机器学习中的一个基础工具,可以通过其结果判断模型是否合理。相关知识超级烦人, 用一次忘一次
## 生成训练集的混淆矩阵
mat_train <- table(train$Species,
train$predict,dnn = c("Labels","prediction"))
cat("Confusion matrix of training set:\n")
mat_train
## 计算error rate
cat(paste0("error rate: ", round(1-(sum(diag(mat_train))/dim(train)[1]),3),"\n"))
## 计算precision
cat(paste0("precision: ", round(mat_train[2,2]/sum(mat_train[,2]),3),"\n"))
## 计算recall
cat(paste0("recall: ", round(mat_train[2,2]/sum(mat_train[2,]),3),"\n"))
【手打模型,这里 versicolor 为正(1), setosa 为负(0)】
Pred | Pos | Neg | |
Real | |||
Pos | TP (说中就中) | FN (真的被你错过了) | |
Neg | FP (假的还当真) | TN (说假就是假) |
结论中的 error rate , precision, recall 是说明模型输出好坏的三个参考值:
- error rate 或者 misclassification rate 如同字面意思就是错误率,其值反映了一组数据在输入模型后得到的所有错误error的占比。(相对应的,正确率为accuracy)
- precision 反映了在predication为正的输出中,原label也为正的比率。(你选中的, 几成是好东西)
- recall 反映了在原label为正的输出中,predication也为正的比率。(所有好东西, 你能挑出几个)
会发现其实混淆矩阵并不能仅仅通过正确率和错误率就来判断一个模型的好坏,还需要额外的precision值和recall值才行。这两个值非常像,但其实区别很大,好的模型这俩值都会很高,而不好的模型则其一或俩值都低,反映为,例如判正要求过于严格或过于松。
AUC (Area under the curve)
通常用的有两种, 一种ROC AUC, 一种PRC AUC. 都是通过调节一个分类模型的pos/neg阈值, 计算两个指标, 画出一条曲线, 一般曲线下面积越大证明模型越好.
注意: 无论是哪种curve都不是一条平滑的曲线, 因为每个阈值对应的两个指标是不确定的,印象里很容易朝一端汇集, 所以在真正应用是, 也会考虑加权weighted来优化曲线, 具体请参考scikit-learn里的介绍
ROC (Receiver operating characteristic) 接收者操作特征曲线
信息论里的名词. 计算原理, 参考指标是TPR和FPR. 下面是两个指数的计算公式, 可以看到就是 横着 看上面的混淆矩阵, 关注的的是TPR和FPR一起高的问题类型, 模型分类的效果不容易受到阈值影响, 随着假阳性增多, 真阳性也要多
优点: ROC AUC的最低值为0.5, 所以不同模型的ROC AUC存在可比性
缺点: 假设有一个模型一般阈值(如0.5)时得到如下混淆矩阵, 可能模型就太不行
Pred | Pos | Neg | |
Real | |||
Pos | 9 | 1 | |
Neg | 500 | 500 |
时,
, 这会导致点在贴近图的最上侧, 就会包括更多的面积(AUC), 但是我们知道这个模型的FP很多 (将大量的坏东西判断成了好东西), 这模型谁敢用
PRC
以precision和recall作为横纵坐标的曲线, 通常比RC更抖, 且precision与recall呈负相关. 由于precision和reall的计算都需要TP的参与, 所以这是一个极度关注TP的指标, 使用场景如制药中的靶点预测, 疾病检测等, 保证模型预测的阳性结果一定是真阳.
[PRC 例图, 最低值为0.52左右]
缺点: precision存在理论最低值, 即数据中的阳性阴性的比例, 所以PRC下的面积(AUC)是没法比较不同数据训练的模型的. 有很多文章介绍了如何正则化RPC AUC, 但感觉都不显著 (也许聊胜于无?)
例如用整体面积减去阳阴比后面积正则化等
结论
PRC AUC和ROC AUC, 以及其他参数, 如Fscore都要看!!!
How to Use ROC Curves and Precision-Recall Curves for Classification in Python https://machinelearningmastery.com/roc-curves-and-precision-recall-curves-for-classification-in-python/
ROC vs PRC 哪个能更好地评价不平衡数据集的模型表现 https://www.zealseeker.com/archives/roc-prc/