• R语言逻辑回归分析
千次阅读
2022-03-17 14:47:05

Logistic regression为非线性模型，回归系数是通过极大似然估计方法计算所得。响应变量取值为1（事件发生）或0（事件不发生）。

## 1. 数据集载入和划分

### 数据集载入和划分
library(AER)
data()  # 查看AER包里面的数据集
data(Affairs) # 载入Affairs数据集
# 查看数据集
summary(Affairs)
str(Affairs)
View(Affairs)

# 定义一个变量，作为y
Affairs$ynaffairs <- ifelse(Affairs$affairs>1,1,0)
Affairs$affairs <- NULL # 去掉affairs列 set.seed(110) is_train <- sample(c(TRUE,FALSE),nrow(Affairs),replace=TRUE,prob=c(0.7,0.3)) train <- Affairs[is_train,] # training dataset test <- Affairs[!is_train,] # test dataset library(caret) Train <- createDataPartition(Affairs$ynaffairs, p=0.7, list=FALSE)
train <- Affairs[Train, ]
test <- Affairs[-Train, ]

## 2. 逻辑回归模型构建和拟合

### 逻辑回归模型构建和拟合
glm.control(epsilon = 1e-8, maxit = 100, trace = FALSE)
aff_glm <- glm(ynaffairs ~ ., family = binomial(),
data = train)
# aff_glm <- glm(ynaffairs ~ ., family = binomial,
#                data = train)
# aff_glm <- glm(ynaffairs ~ ., family = binomial(link="logit"),
#                data = train)

# family(object, ...)
# quasi(link = "identity", variance = "constant")

summary(aff_glm)
# 根据因变量的显着性水平，找出和结果结果变量显著相关的因变量，重新建模
reduce_glm <- glm(ynaffairs ~ yearsmarried+religiousness+rating,
family = binomial(),data = train)
summary(reduce_glm)

# 模型是否有过度离势
reduce_glm2 <- glm(ynaffairs ~ yearsmarried+religiousness+rating,
family = quasibinomial(),data = train)

pchisq(summary(reduce_glm2)$dispersion * reduce_glm$df.residual,
reduce_glm$df.residual,lower = F) #模型比较 anova(reduce_glm,reduce_glm2,test="Chisq") anova(aff_glm,reduce_glm,test="Chisq") ## 3. 模型参数 ### 模型参数 coef(aff_glm) # 模型系数 exp(coef(aff_glm)) # OR值(e^^β) # OR：比值比，为实验组的事件发生几率(odds1)/对照组的事件发生几率(odds2)。 confint(aff_glm) # 模型系数95%置信区间 ## 4. 预测 ### 预测 # 预测rating的影响，其他因子取均值 test_data <-data.frame(yearsmarried = mean(Affairs$yearsmarried),
religiousness = mean(Affairs$religiousness), rating=seq(1:5)) y_pre <- predict(reduce_glm,test_data,type='response') # type参数 the type of prediction required. # The default is on the scale of the linear predictors; # the alternative "response" is on the scale of the response variable. # Thus for a default binomial model the default predictions # are of log-odds (probabilities on logit scale) and # type = "response" gives the predicted probabilities. # The "terms" option returns a matrix giving the fitted values # of each term in the model formula on the linear predictor scale. train_x <- train[,-9] train_y <- train$ynaffairs
train_pre <- predict(aff_glm,train_x,type='response') # 概率
train_pre_classes <- ifelse(train_pre > 0.5, 1, 0)

#names(test)
test_x <- test[,-9]
test_y <- test$ynaffairs test_pre <- predict(aff_glm,test_x,type='response') # 概率 test_pre_classes <- ifelse(test_pre > 0.5, 1, 0) ## 计算模型预测准确性 accuracy <- table(test_pre_classes, test_y) sum(diag(accuracy))/sum(accuracy) ## confusionMatrix {caret} confusionMatrix(data=as.factor(test_pre_classes), reference=as.factor(test$ynaffairs))

# K折交叉验证模型
# trainControl {caret}
ctrl <- trainControl(method = "repeatedcv", number = 5, savePredictions = TRUE)
# train {generics}:Estimate model parameters.
mod_fit <- train(ynaffairs ~ ., data=train, method="glm", family="binomial",
trControl = ctrl, tuneLength = 5)
pred = predict(mod_fit, newdata=test_x)

pred <- ifelse(pred > 0.5, 1, 0)

confusionMatrix(data=as.factor(pred),
reference = as.factor(test$ynaffairs)) ## 5. ROC作图 ### ROC作图 library(pROC) roc_train <- roc(train_y~train_pre, data=train) roc_train roc_test <- roc(test_y~test_pre, data=test) roc_test roc.test(roc_train,roc_test) #par(mfcol=c(2,1)) plot(roc_train,col="red") plot(roc_test,col="blue") # ?plot.roc ## 画多条ROC曲线 plot(roc_train, col="red") plot.roc(roc_test, add=TRUE, col="blue") ## 计算auc (area under curve) library(ROCR) # Compute AUC for predicting ynaffairs with the model prob <- predict(aff_glm, newdata=test_x, type="response") pred <- prediction(prob, test$ynaffairs)
perf <- performance(pred, measure = "tpr", x.measure = "fpr")
plot(perf)
auc <- performance(pred, measure = "auc")
auc <- auc@y.values[[1]]

## 6. 绘制列线图(nomogram)

###  绘制列线图(nomogram)
par(mgp=c(1.6,0.6,0),mar=c(2,2,2,2))  ##设置画布
library(rms)

# 设定环境参数
# lrm和nomogram来自rms包
rms_fit <- lrm(ynaffairs ~ ., data = Affairs)
nomogram <- nomogram(rms_fit,fun=function(x) 1/(1+exp(-x)), ##逻辑回归计算公式
fun.at = c(0.001,0.01,0.05,seq(0.1,0.9,by=0.1),0.95,0.99,0.999),#风险轴刻度
funlabel = "Risk of affairs", #风险轴便签
lp=F,  ##是否显示系数轴
conf.int = F, ##每个得分的置信度区间，用横线表示,横线越长置信度越
abbrev = F #是否用简称代表因子变量
)
plot(nomogram)

注：如果要加入正则项，如lasso回归，ridge回归，弹性网等用glmnet包。

更多相关内容
• logistic回归又称logistic回归分析，是一种广义的线性回归分析模型，常用于数据挖掘，疾病自动诊断，经济预测等领域。例如，探讨引发疾病的危险因素，并根据危险因素预测疾病发生的概率等。以胃癌病情分析为例，选择...
• 承接之前写的“机器学习之线性模型”的那篇文章，这里运用逻辑回归模型实现对文本的一个大体分类，目的是进一步熟悉逻辑回归的运用和sklearn工具包的使用，理解各参数代表的含义，并没有特意做数据处理、特征工程和...
• 主要介绍了Python利用逻辑回归模型解决MNIST手写数字识别问题,结合实例形式详细分析了Python MNIST手写识别问题原理及逻辑回归模型解决MNIST手写识别问题相关操作技巧,需要的朋友可以参考下
• 1.极大似然估计和似然函数 2.LR模型的学习过程 3.其它
• 逻辑回归模型实例
• 逻辑回归泰坦尼克数据集
• 逻辑回归模型 逻辑回归是应用非常广泛的一个分类机器学习算法，它将数据拟合到一个logit函数(或者叫做logistic函数)中，从而能够完成对事件发生的概率进行预测。 import numpy as np import tensorflow as tf ...
• ## 逻辑回归模型详解(Logistic Regression)

万次阅读 多人点赞 2020-11-10 20:41:30
目录 广义线性模型 极大似然法 ...逻辑回归与线性回归都是一种广义线性模型（generalized linear model，GLM）。具体的说，都是从指数分布族导出的线性模型，线性回归假设Y|X服从高斯分布，逻辑回...

目录

广义线性模型

极大似然法

逻辑回归的假设函数

逻辑回归的损失函数

交叉熵损失函数

为什么LR模型损失函数使用交叉熵不用均方差

交叉熵损失函数的数学原理

交叉熵损失函数的直观理解

交叉熵简介

对数损失函数和交叉熵损失函数

逻辑回归优缺点

其他

逻辑回归与线性回归的区别与联系

LR一般需要连续特征离散化原因

## 广义线性模型

逻辑回归与线性回归都是一种广义线性模型（generalized linear model，GLM）。具体的说，都是从指数分布族导出的线性模型，线性回归假设Y|X服从高斯分布，逻辑回归假设Y|X服从伯努利分布。

伯努利分布：伯努利分布又名0-1分布或者两点分布，是一个离散型概率分布。随机变量X只取0和1两个值，比如正面或反面，成功或失败，有缺陷或没有缺陷，病人康复或未康复。为方便起见，记这两个可能的结果为0和1，成功概率为p(0<=p<=1)，失败概率为q=1-p。

高斯分布：高斯分布一般指正态分布。

因此逻辑回归与线性回归有很多相同之处，去除Sigmoid映射函数的话，逻辑回归算法就是一个线性回归。可以说，逻辑回归是以线性回归为理论支持的，但是逻辑回归通过Sigmoid函数引入了非线性因素，因此可以轻松处理0/1分类问题。

这两种分布都是属于指数分布族，我们可以通过指数分布族求解广义线性模型（GLM）的一般形式，导出这两种模型，具体的演变过程如下：

## 极大似然法

极大似然估计，通俗理解来说，就是利用已知的样本结果信息，反推最具有可能（最大概率）导致这些样本结果出现的模型参数值。

极大似然估计的原理，用一张图片来说明，如下图所示：

原理：极大似然估计是建立在极大似然原理的基础上的一个统计方法，是概率论在统计学中的应用。

极大似然估计提供了一种给定观察数据来评估模型参数的方法，即：“模型已定，参数未知”。通过若干次试验，观察其结果，利用试验结果得到某个参数值能够使样本出现的概率为最大，则称为极大似然估计。

## 逻辑回归的假设函数

首先我们要先介绍一下Sigmoid函数，也称为逻辑函数（Logistic function）：

其函数曲线如下：

从上图可以看到sigmoid函数是一个s形的曲线，它的取值在[0, 1]之间，在远离0的地方函数的值会很快接近0或者1，它的这个特性对于解决二分类问题十分重要。

逻辑回归的假设函数形式如下：

所以：

其中 x 是我们的输入，θ 为我们要求取的参数。

一个机器学习的模型，实际上是把决策函数限定在某一组条件下，这组限定条件就决定了模型的假设空间。当然，我们还希望这组限定条件简单而合理。而逻辑回归模型所做的假设是：

这个函数的意思就是在给定 x 和 θ 的条件下，y = 1的概率。

## 逻辑回归的损失函数

通常提到损失函数，我们不得不提到代价函数（Cost Function）及目标函数（Object Function）。

损失函数（Loss Function) 直接作用于单个样本，用来表达样本的误差

代价函数（Cost Function）是整个样本集的平均误差，对所有损失函数值的平均

目标函数（Object Function）是我们最终要优化的函数，也就是代价函数+正则化函数（经验风险+结构风险）

概况来讲，任何能够衡量模型预测出来的值 h(θ) 与真实值 y 之间的差异的函数都可以叫做代价函数 C(θ) 如果有多个样本，则可以将所有代价函数的取值求均值，记做 J(θ) 。因此很容易就可以得出以下关于代价函数的性质：

• 选择代价函数时，最好挑选对参数 θ 可微的函数（全微分存在，偏导数一定存在）
• 对于每种算法来说，代价函数不是唯一的；
• 代价函数是参数 θ 的函数；
• 总的代价函数 J(θ) 可以用来评价模型的好坏，代价函数越小说明模型和参数越符合训练样本（x,y）；
• J(θ) 是一个标量；

经过上面的描述，一个好的代价函数需要满足两个最基本的要求：能够评价模型的准确性，对参数 θ 可微。

在线性回归中，最常用的是均方误差(Mean squared error)，即

在逻辑回归中，最常用的是代价函数是交叉熵(Cross Entropy)，交叉熵是一个常见的代价函数

通过梯度下降法求参数的更新式

我们下图为推倒式，这样可以使推导式更简洁。

求梯度：

学习率

LR在确定了模型的形式后，通过最大似然估计法来实现最小散度从而求出模型参数。

## 交叉熵损失函数

说起交叉熵损失函数「Cross Entropy Loss」，脑海中立马浮现出它的公式：

### 交叉熵损失函数的数学原理

我们知道，在二分类问题模型：例如逻辑回归「Logistic Regression」、神经网络「Neural Network」等，真实样本的标签为 [0，1]，分别表示负类和正类。模型的最后通常会经过一个 Sigmoid 函数，输出一个概率值，这个概率值反映了预测为正类的可能性：概率越大，可能性越大。

Sigmoid 函数的表达式和图形如下所示：

其中 s 是模型上一层的输出，Sigmoid 函数有这样的特点：s = 0 时，g(s) = 0.5；s >> 0 时， g ≈ 1，s << 0 时，g ≈ 0。显然，g(s) 将前一级的线性输出映射到 [0，1] 之间的数值概率上。这里的 g(s) 就是交叉熵公式中的模型预测输出 。

我们说了，预测输出即 Sigmoid 函数的输出表征了当前样本标签为 1 的概率：

很明显，当前样本标签为 0 的概率就可以表达成：

重点来了，如果我们从极大似然性的角度出发，把上面两种情况整合到一起：

不懂极大似然估计也没关系。我们可以这么来看：

当真实样本标签 y = 0 时，上面式子第一项就为 1，概率等式转化为：

当真实样本标签 y = 1 时，上面式子第二项就为 1，概率等式转化为：

两种情况下概率表达式跟之前的完全一致，只不过我们把两种情况整合在一起了。

重点看一下整合之后的概率表达式，我们希望的是概率 P(y|x) 越大越好。首先，我们对 P(y|x) 引入 log 函数，因为 log 运算并不会影响函数本身的单调性。则有：

我们希望 log P(y|x) 越大越好，反过来，只要 log P(y|x) 的负值 -log P(y|x) 越小就行了。那我们就可以引入损失函数，且令 Loss = -log P(y|x)即可。则得到损失函数为：

非常简单，我们已经推导出了单个样本的损失函数，是如果是计算 N 个样本的总的损失函数，只要将 N 个 Loss 叠加起来就可以了：

这样，我们已经完整地实现了交叉熵损失函数的推导过程。

### 交叉熵损失函数的直观理解

从图形的角度，分析交叉熵函数，加深大家的理解。首先，还是写出单个样本的交叉熵损失函数：

我们知道，当 y = 1 时：

这时候，L 与预测输出的关系如下图所示：

看了 L 的图形，简单明了！横坐标是预测输出，纵坐标是交叉熵损失函数 L。显然，预测输出越接近真实样本标签 1，损失函数 L 越小；预测输出越接近 0，L 越大。因此，函数的变化趋势完全符合实际需要的情况。

当 y = 0 时：

这时候，L 与预测输出的关系如下图所示：

同样，预测输出越接近真实样本标签 0，损失函数 L 越小；预测函数越接近 1，L 越大。函数的变化趋势也完全符合实际需要的情况。

从上面两种图，可以帮助我们对交叉熵损失函数有更直观的理解。无论真实样本标签 y 是 0 还是 1，L 都表征了预测输出与 y 的差距。

另外，重点提一点的是，从图形中我们可以发现：预测输出与 y 差得越多，L 的值越大，也就是说对当前模型的 “ 惩罚 ” 越大，而且是非线性增大，是一种类似指数增长的级别。这是由 log 函数本身的特性所决定的。这样的好处是模型会倾向于让预测输出更接近真实样本标签 y。

• 交叉熵能够衡量同一个随机变量中的两个不同概率分布的差异程度，在机器学习中就表示为真实概率分布与预测概率分布之间的差异。交叉熵的值越小，模型预测效果就越好。

• 交叉熵在分类问题中常常与softmax是标配，softmax将输出的结果进行处理，使其多个分类的预测值和为1，再通过交叉熵来计算损失。

交叉熵可在神经网络(机器学习)中作为损失函数，p表示真实标记的分布，q则为训练后的模型的预测标记分布，交叉熵损失函数可以衡量p与q的相似性。交叉熵作为损失函数还有一个好处是使用sigmoid函数在梯度下降时能避免均方误差损失函数学习速率降低的问题，因为学习速率可以被输出的误差所控制。

### 交叉熵简介

交叉熵是信息论中的一个重要概念，主要用于度量两个概率分布间的差异性，要理解交叉熵，需要先了解下面几个概念。

信息量

信息奠基人香农（Shannon）认为“信息是用来消除随机不确定性的东西”，也就是说衡量信息量的大小就是看这个信息消除不确定性的程度。

“太阳从东边升起”，这条信息并没有减少不确定性，因为太阳肯定是从东边升起的，这是一句废话，信息量为0。

”2018年中国队成功进入世界杯“，从直觉上来看，这句话具有很大的信息量。因为中国队进入世界杯的不确定性因素很大，而这句话消除了进入世界杯的不确定性，所以按照定义，这句话的信息量很大。

根据上述可总结如下：信息量的大小与信息发生的概率成反比。概率越大，信息量越小。概率越小，信息量越大。

设某一事件发生的概率为P(x)，其信息量表示为：

其中 I ( x ) 表示信息量，这里 log 表示以e为底的自然对数。

信息熵

信息熵也被称为熵，用来表示所有信息量的期望。

期望是试验中每次可能结果的概率乘以其结果的总和。

所以信息量的熵可表示为：（这里的X XX是一个离散型随机变量）

使用明天的天气概率来计算其信息熵：

对于0-1分布的问题，由于其结果只用两种情况，是或不是，设某一件事情发生的概率为P ( x ) ，则另一件事情发生的概率为1 − P ( x ) ，所以对于0-1分布的问题，计算熵的公式可以简化如下：

相对熵（KL散度）

如果对于同一个随机变量X XX有两个单独的概率分布 P(x) 和 Q(x)，则我们可以使用KL散度来衡量这两个概率分布之间的差异

下面直接列出公式，再举例子加以说明。

在机器学习中，常常使用 P(x) 来表示样本的真实分布，Q(x) 来表示模型所预测的分布，比如在一个三分类任务中（例如，猫狗马分类器）， x1​,x2​,x3​ 分别代表猫，狗，马，例如一张猫的图片真实分布 P(X)=[1,0,0] ，预测分布 Q(X)=[0.7,0.2,0.1] ，计算KL散度：

KL散度越小，表示 P(x) 与 Q(x) 的分布更加接近，可以通过反复训练 Q(x) 来使 Q(x) 的分布逼近 P(x)。

交叉熵

首先将KL散度公式拆开：

前者 H(p(x)) 表示信息熵，后者即为交叉熵，KL散度 = 交叉熵 - 信息熵

交叉熵公式表示为：

在机器学习训练网络时，输入数据与标签常常已经确定，那么真实概率分布 P(x) 也就确定下来了，所以信息熵在这里就是一个常量。由于KL散度的值表示真实概率分布 P(x) 与预测概率分布 Q(x) 之间的差异，值越小表示预测的结果越好，所以需要最小化KL散度，而交叉熵等于KL散度加上一个常量（信息熵），且公式相比KL散度更加容易计算，所以在机器学习中常常使用交叉熵损失函数来计算loss就行了。

## 逻辑回归优缺点

LR优点

1. 直接对分类的可能性建模，无需事先假设数据分布，避免了假设分布不准确带来的问题
2. 不仅预测出类别，还可得到近似概率预测
3. 对率函数是任意阶可导凸函数，有很好得数学性质，很多数值优化算法可直接用于求取最优解
4. 容易使用和解释，计算代价低
5. LR对时间和内存需求上相当高效
6. 可应用于分布式数据，并且还有在线算法实现，用较小资源处理较大数据
7. 对数据中小噪声鲁棒性很好，并且不会受到轻微多重共线性影响
8. 因为结果是概率，可用作排序模型

LR缺点

1. 容易欠拟合，分类精度不高
2. 数据特征有缺失或特征空间很大时效果不好

## 其他

### 逻辑回归与线性回归的区别与联系

区别

• 线性回归假设响应变量服从正态分布，逻辑回归假设响应变量服从伯努利分布
• 线性回归优化的目标函数是均方差（最小二乘），而逻辑回归优化的是似然函数（交叉熵）
• 线性归回要求自变量与因变量呈线性关系，而逻辑回归没有要求
• 线性回归分析的是因变量自身与自变量的关系，而逻辑回归研究的是因变量取值的概率与自变量的概率
• 逻辑回归处理的是分类问题，线性回归处理的是回归问题，这也导致了两个模型的取值范围不同：0-1和实数域
• 参数估计上，都是用极大似然估计的方法估计参数（高斯分布导致了线性模型损失函数为均方差，伯努利分布导致逻辑回归损失函数为交叉熵）

联系

• 两个都是线性模型，线性回归是普通线性模型，逻辑回归是广义线性模型
• 表达形式上，逻辑回归是线性回归套上了一个Sigmoid函数

### LR一般需要连续特征离散化原因

1. 离散特征的增加和减少都很容易，易于模型快速迭代
2. 稀疏向量内积乘法速度快，计算结果方便存储，容易扩展
3. 离散化的特征对异常数据有很强的鲁棒性(比如年龄为300异常值可归为年龄>30这一段)
4. 逻辑回归属于广义线性模型，表达能力受限。单变量离散化为N个后，每个变量有单独的权重，相当于对模型引入了非线性，能够提升模型表达能力，加大拟合
5. 离散化进行特征交叉，由 m+n 个变量为 m*n 个变量(将单个特征分成 m 个取值)，进一步引入非线性，提升表达能力
6. 特征离散化后，模型会更稳定(比如对用户年龄离散化，20-30作为一个区间，不会因为用户年龄，增加一岁变成完全不同的人，但区间相邻处样本会相反，所以怎样划分区间很重要)
7. 特征离散化后，简化了LR模型作用，降低模型过拟合风险

展开全文
• 逻辑回归模型中的一种新的随机约束岭估计，李英莉，左卫兵，针对逻辑回归模型中解释变量存在复共线性问题, 在随机约束岭最大似然估计的基础上, 通过添加岭参数 , 提出一种新的随机约束岭估计;
• 一元线性回归线性回归多元线性回归多个因变量与多个自变量的回归如何从数据推断回归模型基本假设的合理性基本假设不成立时如何对数据进行修正回归诊断判断回归...
• 逻辑回归模型训练分类器并可视化（每一行表示一个样本，每一行有三个数值，其中前两个值代表输入属性x，最后一个值代表标签y）
• 在不需要做额外特征提取工作的情况下，本项目意在通过逻辑回归模型的调优，得到较为准确可靠的反欺诈检测方法，分析过程中使用到了Python Pandas, Numpy, Matplotlib, Seaborn以及机器学习库Scikit-Learn等。...
• 1 简介 逻辑回归也被称为广义线性...线性回归是用来预测连续变量的，其取值范围（-∞，＋∞），而逻辑回归模型是用于预测类别的，例如，用逻辑回归模型预测某物品是属于A类还是B类，在本质上预测的是该物品属于A类或

# 1 简介

逻辑回归也被称为广义线性回归模型，它与线性回归模型的形式基本上相同，最大的区别就在于它们的因变量不同，如果是连续的，就是多重线性回归；如果是二项分布，就是Logistic回归。

Logistic回归虽然名字里带“回归”，但它实际上是一种分类方法，主要用于二分类问题（即输出只有两种，分别代表两个类别），也可以处理多分类问题。

线性回归是用来预测连续变量的，其取值范围（-∞，＋∞），而逻辑回归模型是用于预测类别的，例如，用逻辑回归模型预测某物品是属于A类还是B类，在本质上预测的是该物品属于A类或B类的概率，而概率的取值范围是0～1，因此不能直接用线性回归方程来预测概率，此时就涉及到Sigmoid函数，可将取值范围为（-∞，＋∞）的数转换到（0，1）之间。如下图所示。

总结来说，逻辑回归模型本质就是将线性回归模型通过Sigmoid函数进行了一个非线性转换，得到一个介于0～1之间的概率值，对于二分类问题（分类0和1）而言，其预测分类为1（或者说二分类中数值较大的分类）的概率可以用如下所示的公式计算。

因为概率和为1，则分类为0（或者说二分类中数值较小的分类）的概率为1-P。

逻辑回归模型的本质就是预测属于各个分类的概率，有了概率之后，就可以进行分类了。

# 2 优缺点

优点：速度快，适合二分类问题；简单、易于理解，可以直接看到各个特征的权重；能容易地更新模型吸收新的数据。

缺点：对数据和场景的适应能力有局限性，不如决策树算法适应性强。

# 3 适用场景

·寻找危险因素：寻找某一疾病的危险因素等；

·预测：根据模型，预测在不同的自变量情况下，发生某种疾病或某种情况的概率有多大；

·判别：实际上跟预测有些类似，也是根据模型，判断某人属于某种疾病或属于某种情况的概率有多大。

# 4 案例：客户流失预警模型

## 4.1 读取数据

df中共有约7000组历史数据，其中约2000组为流失客户，约5000组为未流失客户。

将“是否流失”作为目标变量，其他字段作为特征变量，通过一个客户的一些基本情况和交易记录来预测他是否会流失，或者说判断流失的概率大小。

## 4.3 模型搭建与使用

### 4.3.1 划分训练集与测试集

训练集用于训练数据和搭建模型，测试集则用于检验训练后所搭建模型的效果。

划分训练集和测试集的目的：一是为了对模型进行评估，二是可以通过测试集对模型进行调优。

划分训练集和测试集在某种程度上也是为了检查模型是否出现过拟合。

train_test_split()函数划分训练集和测试集，X_train、y_train为训练集的特征变量和目标变量数据，X_test、y_test则为测试集的特征变量和目标变量数据。train_test_split()函数的参数中，X和y便是之前划分的特征变量和目标变量；test_size则是测试集数据所占的比例，这里选择的是0.2，即20%。

每次运行程序时，train_test_split()函数都会随机划分数据，如果想要让每次划分数据的结果保持一致，可以设置random_state参数，代码如下。

X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=1)

为random_state参数赋值为1，该数字没有特殊含义，可以换成其他数字，它相当于一个种子参数，使得每次划分数据的结果一致。

### 4.3.3 预测数据结果及准确率

y_pred是一个numpy.ndarray类型的一维数组结构，y_test为Series类型的一维序列结构，用list()函数将它们都转换为列表，再将它们集成到一个DataFrame中，代码如下。

可以看到，前5项的预测准确度为80%。

如果想查看所有测试集数据的预测准确度，可以使用如下代码。

除了使用accuracy_score()函数，还可以使用模型自带的score()函数来计算预测准确度，代码如下，其结果同样为0.7963。

### 4.3.4 预测概率

逻辑回归模型的本质是预测概率，而不是直接预测具体类别。通过如下代码就可以获取概率值。

通过打印y_pred_proba[0:5]查看结果的前5项，结果是一个二维数组，数组左列是不流失（分类为0）概率，右列是流失（分类为1）概率。或者这样显示：

# 5 获取逻辑回归系数

逻辑回归模型在本质上是将线性回归模型通过Sigmoid函数进行非线性转换。本案例共有5个特征变量，所以预测y＝1（流失）的概率P的公式如下。

通过coef_属性可以获取特征变量前的系数ki，通过intercept_属性可以获取截距项k0。

# 6 代码汇总

# 1.读取数据
import pandas as pd

# 2.划分特征变量与目标变量
X = df.drop(columns='是否流失')
y = df['是否流失']

# 3.划分数据集与测试集
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2)

# 4.模型搭建
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(X_train,y_train)

# 5.预测分类结果
y_pred = model.predict(X_test)
y_pred[:20]

# 6.预测概率
y_pred_proba = model.predict_proba(X_test)
y_pred_proba[:5]

# 7.模型准确率
from sklearn.metrics import accuracy_score
accuracy = accuracy_score(y_pred,y_test)
# 或者
y_pred_accuracy = model.score(X_test,y_test)

# 7 模型评估方法：ROC曲线与KS曲线

模型搭建完成后，还需要对模型的优劣进行评估。

对于二分类模型来说，主流的评估方法有ROC曲线和KS曲线两种。

## 7.1 ROC曲线

### 7.1.1 ROC介绍

在商业实战中，更关心下表中的两个指标。

其中TP、FP、TN、FN的含义见下表，这个表也被称为混淆矩阵

以上述案例为例，7000个客户中实际有2000个客户流失，假设模型预测所有客户都不会流失，那么模型的假警报率（FPR）为0，即没有误伤一个未流失客户，但是此时模型的命中率（TPR）也为0，即没有揪出一个流失客户，见下表。

总体来说，命中率计算的是所有实际流失（分类为1）的客户中被预测为流失的客户所占的比例，也称真正率或召回率；而假警报率计算的则是所有实际未流失（分类为0）的客户中被预测为流失的客户所占的比例，也称假正率。可通过如下公式来帮助理解并加深记忆。

一个优秀的客户流失预警模型，命中率（TPR）应尽可能高，即能尽量揪出潜在流失客户，同时假警报率（FPR）应尽可能低，即不要把未流失客户误判为流失客户。然而这两者往往成正相关，因为如果调高阈值，例如认为流失概率超过90%才认定为流失，那么会导致假警报率很低，但是命中率也很低；而如果调低阈值，例如认为流失概率超过10%就认定为流失，那么命中率就会很高，但是假警报率也会很高。因此，为了衡量一个模型的优劣，根据不同阈值下的命中率和假警报率绘制了ROC曲线，如下图所示，其中横坐标为假警报率（FPR），纵坐标为命中率（TPR）。

如果把假警报率理解为代价的话，那么命中率就是收益，所以也可以说在阈值相同的情况下，希望假警报率（代价）尽可能小，命中率（收益）尽可能高，该思想反映在图形上就是ROC曲线尽可能地陡峭。曲线越靠近左上角，说明在相同的阈值条件下，命中率越高，假警报率越低，模型越完善。换一个角度来理解，一个完美的模型是在不同的阈值条件下，假警报率都接近于0，而命中率都接近于1，该特征反映在图形上就是ROC曲线非常接近（0，1）这个点，即曲线非常陡峭。

### 7.1.2 混淆矩阵的Python代码实现

可以看到，实际流失的348（192＋156）人中有156人被准确预测，命中率（TPR）为45%；实际未流失的1061（968＋93）人中有93人被误判为流失，假警报率（FPR）为8.8%。需要注意的是，这里的TPR和FPR都是在阈值为50%的条件下计算的。

通过如下代码计算命中率，无须手动计算。

precision（精准率）和f1-score。

### 7.1.3 案例：用ROC曲线评估客户流失预警模型

在商业实战中，我们希望在阈值相同的情况下，假警报率尽可能小，命中率尽可能高，该思想反映在图形上，就是ROC曲线非常接近（0，1），即曲线非常陡峭。

用曲线来描述会比较抽象，在数值上可以使用AUC值来衡量模型的好坏AUC值（AreaUnder Curve）指ROC曲线下方的面积，该面积的取值范围通常为0.5～1，0.5表示随机判断，1则代表完美的模型。在商业实战中，因为存在很多扰动因子，AUC值能达到0.75以上就已经可以接受，如果能达到0.85以上，就是非常不错的模型。

在Python中，通过如下代码就可以求出不同阈值下的命中率（TPR）和假警报率（FPR）的值，从而绘制出ROC曲线。

roc_curve()函数返回的是一个含有3个元素的元组，其中默认第1个元素为假警报率，第2个元素为命中率，第3个元素为阈值，所以这里将三者分别赋给变量fpr（假警报率）、tpr（命中率）、thres（阈值）。

通过如下代码则可以快速求出模型的AUC值。

获得的AUC值为0.81，可以说预测效果还是不错的。

### 7.1.4 阈值的取值方法

在测试样本中，对预测分类为1的概率进行排序，使用sort_values()函数，并设置ascending参数为False进行降序排列。得到如下结果。

可以看到，序号326的样本其分类为1的概率最高，为0.930369，这个概率就是之前提到的阈值（在之前的表格中，它是除1.930369外最大的阈值）。所有样本的分类就是根据这个阈值进行的，分类为1的概率小于该阈值的样本都被列为分类0，大于等于该阈值的样本都被列为分类1，因为只有序号326的样本满足分类为1的概率大于等于该阈值，所以只有该样本会被列为分类1（实际上该样本也的确为分类1），其余样本都被列为分类0。由上可知，一共有348个实际分类为1的样本，所以此时命中率（TPR）为1/348＝0.002874，与通过程序获得的结果是一致的。

至此，可以得出结论，这些阈值都是各个样本分类为1的概率（其实并没有全部都取，例如，序号366的样本分类为1的概率就没有被取为阈值）。

## 7.2 KS曲线

### 7.2.1 KS介绍

KS曲线和ROC曲线在本质上是相同的，同样关注命中率（TPR）和假警报率（FPR），希望命中率（TPR）尽可能高，即尽可能揪出潜在流失客户，同时也希望假警报率（FPR）尽可能低，即不要把未流失客户误判为流失客户。

区别于ROC曲线将假警报率（FPR）作为横坐标，将命中率（TPR）作为纵坐标，KS曲线将阈值作为横坐标，将命中率（TPR）与假警报率（FPR）之差作为纵坐标，如下图所示。

使用KS值来衡量模型预测效果。

KS值就是KS曲线的峰值。具体来说，每一个阈值都对应一个（TPR-FPR）值，那么一定存在一个阈值，使得在该阈值条件下，（TPR-FPR）值最大，那么此时的（TPR-FPR）值便称为KS值。例如，上图中当阈值等于40%时，命中率（TPR）为80%，假警报率（FPR）为25%，所以（TPR-FPR）值为55%，该值是所有阈值条件下最大的（TPR-FPR）值，因此，这个模型的KS值为55%。

用更通俗易懂的话来说，该模型在阈值为40%时能尽可能地识别坏人，并尽可能地不误伤好人，此时命中率（TPR）减去假警报率（FPR）的差值为55%，即该模型的KS值。

一般情况下，我们希望模型有较大的KS值，因为较大的KS值说明模型有较强的区分能力。

不同取值范围的KS值的含义如下：

·KS值小于0.2，一般认为模型的区分能力较弱；

·KS值在[0.2，0.3]区间内，模型具有一定区分能力；

·KS值在[0.3，0.5]区间内，模型具有较强的区分能力。

但KS值也不是越大越好，如果KS值大于0.75，往往表示模型有异常。在商业实战中，KS值处于[0.2，0.3]区间内就已经算是挺不错的了。

### 7.2.2 案例：用KS曲线评估客户流失预警模型

通过如下代码求出在不同阈值下的假警报率（FPR）和命中率（TPR），从这一点也可以看出KS曲线和ROC曲线其实是同根同源的。

第1～3行代码绘制的曲线均以阈值为横坐标，而纵坐标分别为命中率、假警报率及两者之差。因为表格第1行中的阈值大于1，无意义，会导致绘制出的图形不美观，所以通过切片的方式将第1行剔除，其中thres[1:]、tpr[1:]、fpr[1:]都表示从第2个元素开始绘制。

第6行代码反转x轴，即把阈值从大到小排序再绘制KS曲线。具体来说，先用gca()函数（gca代表get current axes）获取坐标轴信息，再用invert_xaxis()函数反转x轴。

通过如下代码则可以快速求出KS值。

打印输出该KS值，结果为0.4754，在[0.3，0.5]区间内，因此，该模型具有较强的区分能力。

# 参考书籍

《Python大数据分析与机器学习商业案例实战》

展开全文
• ## 解析逻辑回归模型

千次阅读 2018-06-18 11:33:24
逻辑回归模型是业界运用最为广泛的模型，我们从下面几个方面讨论这个模型： 1. 在模型层面上，逻辑回归模型是被用来解决分类问题的。由于分类是一个非线性问题，所以建模的主要难点是如何将非线性问题转化为线性...

## 介绍

逻辑回归模型是业界运用最为广泛的模型，我们从下面几个方面讨论这个模型：
1. 在模型层面上，逻辑回归模型是被用来解决分类问题的。由于分类是一个非线性问题，所以建模的主要难点是如何将非线性问题转化为线性问题。主要从两方面入手：
- 从分解问题的角度入手：通过引入隐含变量（这里举一个例子，来解释什么是隐含变量：当人们在购买衣服的时候，能被其他人观察到的只有购买与否这个行为，而忽略了在这行为之前的内心博弈的过程。这个博弈的过程其实就是内心在比较购买带来的快乐多还是购买带来的烦恼多，是一个概率问题，在统计上，这个过程我们可以看成事件发生比，它表示的是该事件发生于不发生的比率）。将问题划分为两个层次，一个是线性的隐含变量模型，另一个是基于隐含变量模型结果的非线性的变换。

正态分布的累积分布函数几乎和逻辑分布的累积分布函数一样。其中虚线，呈S形状，因此也被称为S函数（sigmoid函数），它其实就是描述了某一方竞争胜出的概率。
- 从图像的角度入手：逻辑回归通过非线性的空间变换，将原空间内非线性的分类问题转换为新空间内的线性问题，再用线性模型去解决。

上图中右图表示原空间，左图表示变换后的空间。可以形象地把右图想象成橡皮泥，握住里面曲线的两头，用力将其拉成一条直线，就得到了左图，换句话说，在新的线性空间中，线性回归模型就可以很好的拟合数据了。
2. 在模型评估层面，对于分类问题的预测结果，可以定义相应的查准率和查全率，以及综合这两种效应的F1评分。对于基于概率的分类模型，还可以绘制他的ROC曲线，以及计算曲线下的AUC值。
3. 在数据分类不均衡层面，最常见的也是最方便的方法是修改损失函数里不同类别的权重。将它的损失函数改写成：

当类别1所占比例很少时，则增加w1，也就是增加模型对于类别1所承受的损失，反之亦然。在很多情况下，类别权重的选择原则是，类别权重等于类别所占比例的倒数。同时，对于不均衡的数据也可以使用重新采样的方法，将多的类别变少将少的类别变多。这里需要注意的是：在使用不均衡数据建模的时候，使用准确度进行模型评估会失真，而使用AUC（曲线下的面积）是可以保持稳定的，不会像准确度那样失真。

## 上手实践

结合具体的数据，搭建逻辑回归模型。我们使用的数据是美国个人收入的普查数据。
1. 读取数据

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import statsmodels.api as sm
from sklearn.model_selection import train_test_split
%matplotlib inline

data.head()

data.info()

这里为了专注于逻辑回归模型本身，先使用数值型变量加性别字符型变量，因为女性和男性之间没有什么关联，我们也考虑进去，所以使用年限、受教育年限、该年度投资收益、该年度投资损失和每个星期工作的时间。

2. 数据分析
查看数据的缺失值

data.isnull().sum()

数据转换

# 将"female"用0表示，将"male"用1表示。
data["sex_code"] = pd.Categorical(data.sex).codes
# 将"<=50K"用0表示，将">50K"用1表示。
data["label_code"] = pd.Categorical(data.label).codes
cols = ["age", "education_num", "capital_gain", "capital_loss", "hours_per_week", "sex_code", "label_code"]

可视化各个特征

# data[["age", "hours_per_week", "education_num", "label_code"]].hist()
fig = plt.figure(figsize=(10,6))
sns.distplot(data.age, hist= False, ax=ax1)
sns.distplot(data.hours_per_week, hist= False, ax=ax2)
sns.distplot(data.education_num, hist= False, ax=ax3)
sns.distplot(data.label_code, kde= False, ax=ax4, bins=20)
plt.show(block=False)

受教育年限与收入的关系
使用交叉报表统计：

cross1 = pd.crosstab(pd.qcut(data.education_num, [0, .25, .5, .75, 1]), data.label)
cross1

然后，接着可视化——马赛克图展示变化趋势：

from statsmodels.graphics.mosaicplot import mosaic
import matplotlib as mpl
plt.style.use("ggplot")
mpl.rcParams['xtick.labelsize'] = 16
mpl.rcParams['ytick.labelsize'] = 16
mpl.rcParams["axes.labelcolor"] = "k"
mpl.rcParams["axes.labelsize"] = 20
mpl.rcParams['font.size'] = 15
fig = plt.figure(figsize=(16,6))
props = lambda key: {"color": "0.45"} if ' >50K' in key else {"color": "#C6E2FF"}
mosaic(cross1.stack(), ax=ax, properties=props)
plt.show(block=False)

接下来我们再看每周工作时间与收入的关系。

# 计算hours_per_week, label 交叉报表
cross2 = pd.crosstab(pd.cut(data.hours_per_week, 5), data.label)
# 标准化一下
cross2_norm = cross2.div(cross2.sum(1).astype(float), axis=0)
cross2_norm

可视化

cross2_norm.plot(kind="bar", color=["green", "red"], rot=45)

3. 搭建模型
首先整理数据

df = data[cols]
df.head()

将数据全部转化为数值型
首先，我使用Statsmodels库来搭建模型，从统计学的层面来观察模型。

# 切分数据成训练集和测试集
train_data, test_data = train_test_split(df, test_size=.2)
# 搭建模型
formula = "label_code ~ age + education_num + capital_gain + capital_loss + hours_per_week + sex_code"
model = sm.Logit.from_formula(formula=formula, data=train_data)
re = model.fit()
re.summary()

coef是代表各个变量的参数估计值，P>|Z| 代表参数是否显著。通过上图，我们可以清楚的看出各个变量都是与因变量收入成正相关的，且都是显著影响收入的。
同时，我们还可以对各个变量的参数进行T检验，看是否显著。

# 检验的假设为：变量education_num的系数等于0。
re.f_test("education_num=0")

结果：

P-value小于0，拒绝education_num的系数等于0这个假设，即他的系数是显著的。

3. 模型评估
首先使用查准率查全率以及F1评分

那么可以得到公式：
Precision = TP / (TP + FP)
Recall = TP / (TP + FN)
而，f1则是综合了查准率和查全率这两个指标，是它们的加权调和平均数
F1 = 2 x precision x recall / (precision + recall)
用代码表示：

test_data["prob"] = re.predict(test_data)
test_data["pred"] = test_data.apply(lambda x: 1 if x["prob"] > 0.5 else 0, axis=1)
bins = np.array([0, 0.5, 1])
label = test_data["label_code"]
pred = test_data["pred"]
tp, fp, fn, tn = np.histogram2d(label, pred, bins=bins)[0].flatten()
precision = tp / (tp + fp)
recall = tp / (tp + fn)
f1 = 2 * precision * recall / (precision + recall)
print("查准率：%3f, 查全率：%3f， f1：%3f" % (precision, recall, f1))

结果：
查准率：0.935549, 查全率：0.844853， f1：0.887891

接下来使用ROC曲线评估模型
其实，如果我们仔细体会查全率的定义：TP / (TP + FN)，公式中的分母为实际上年收入大于5万的居民数，而查准率：****TP / (TP + FP)，公式中的分母为预测结果中年收入大于5万的居民数。也就是说分子和分母都是受模型的影响，因此当查准率变化时，很难说清是哪一部分在变化，继而不能有效的进行下一步分析。
为了解决这个问题，引入了两个新指标：真阳性率（TPR）和伪阳性率（FPR）
TPR = TP / (TP + FN)
FPR = FP / (FP + TN)
我们可以将这两个指标放在同一和空间内对数据模型进行评估，这就有了ROC空间。它是以伪阳性率为横轴，以真阳性率为纵轴画一个长度为1的正方形。在这个空间中越离左上角近的点预测的准确率越高，同时正方形的对角线表示随机分类的预测结果，这说明要高于这个对角线才算模型正常，不然，这个模型的准确性比随机概率0.5还低了，就不行了。
下面用代码演示（使用sklearn库）：

from sklearn import metrics
from sklearn.linear_model import LogisticRegression

features = ["age", "education_num", "capital_gain", "capital_loss", "hours_per_week"]
labels = "label_code"
trainSet, testSet = train_test_split(data, test_size=0.2, random_state=2310)
model = LogisticRegression()
model.fit(data[features], data[labels])
# 得到预测的概率
preds = model.predict_proba(testSet[features])[:,1]
# 得到False positive rate和True positive rate
fpr, tpr, _ = metrics.roc_curve(testSet[labels], preds)
# 得到AUC
auc = metrics.auc(fpr, tpr) # 0.83

可视化：

plt.rcParams["font.sans-serif"]=["SimHei"]
# 创建一个图形框
fig = plt.figure(figsize=(6, 6), dpi=80)
# 在图形框里只画一幅图
# 在Matplotlib中显示中文，需要使用unicode
ax.set_title("%s" % u"ROC曲线")
ax.set_xlabel("伪阳性率（False positive rate）")
ax.set_ylabel("真阳性率（True positive rate）")
ax.plot([0, 1], [0, 1], "r--")
ax.set_xlim([0, 1])
ax.set_ylim([0, 1])
ax.plot(fpr, tpr, "k", label="%s; %s = %0.2f" % (u"ROC曲线",
u"曲线下面积（AUC）", auc))
ax.fill_between(fpr, tpr, color="grey", alpha=0.6)
plt.show()

可以看出AUC值与查全率查准率不同，它不依赖与模型所定阈值，而是完全取决于模型本身。因此，它也被看出是评估模型更加全面的指标了。

展开全文
• 文章目录前言一、了解数据概况二、单变量分析三、可视化二、使用步骤1.引入库2.读入数据总结 前言 提示：这里可以添加本文要记录的大概内容： 例如：随着人工智能的不断发展，机器学习这门技术也越来越重要，很多人...
• 对事故发生前的速度、流量、天气的数据进行提取总结和统计分析，探究交通事故在人、车、路和环境方面的因素特点，并从逻辑回归模型的角度分析各因素对交通事故的显著影响程度，为交通安全的改进提供理论参考。...
• 泰坦尼克号数据集：准备的逻辑回归模型和完成的随机森林分析
• 所以在常规的逻辑回归模型中，只有两个类别，0或者1，适合二分类问题。 模型函数 逻辑回归模型可以看成是将线性回归模型放入一个sigmoid函数中。 线性回归模型为 。 sigmoid函数是。 所以逻辑回归模型函数是。...
• 回归和分类方法是机器学习中经常用到的方法 区分回归问题和分类问题：回归问题：输入变量和输出变量...联系：从prediction角度来看，分类模型和回归模型本质相同，分类模型是将回归模型的输出离散化，比如：1、Logisti
• 逻辑回归 logistic regression
• 该代码是主要基于tensorflow框架下的逻辑回归模型，使用经典的梯度下降算法来最小化误差，加了L2正则化以减小过拟合。主要是针对没有测试集的数据，利用五折交叉验证并重复十次来计算AUC值，以评估模型。
• 对于逻辑回归模型，可以理解成是有两个步骤的模型，第一步是计算x+b，第二步是计算sigmoid函数 。  构建上图最上面的单层的神经网络，其实是希望通过样本数据（，），其中m表示样本的个数，k表示输入值x的特征...
• Keras简单逻辑回归模型导入安装包加载数据创建模型并训练评估模型 导入安装包 import pandas as pd from keras.models import Sequential from keras.layers import Dense from keras.layers import Flatten import ...
• 爆炸性数据分析-EDA基本和逻辑回归模型：爆炸性数据分析（EDA）基础和逻辑回归模型
• 这里将建立一个逻辑回归模型来预测一个学生是否被大学录取。 假设你是一个大学的管理员，你想根据两次考试的结果来决定每个申请人的录取机会，你有以前的申请人的历史数据。可以用历史数据作为逻辑回归的训练集。...

...