- 分类分析
- 分类问题与对应的模型
- 二分类问题
- 1.1 线性回归模型是如何处理分类问题的
- 两种映射函数——Logistic函数与Probit函数
- logistic函数
- Probit函数
- logistic线性回归函数
- Probit线性回归模型
- 模型推断
- 分类预测
- 1.5.1 模型预测的原理
- 1.5.2 预测结果呈现——混淆矩阵与多指标
- 混淆矩阵
- “样本不均衡”
- 1.5.3 对抗不平衡数据集——改变阈值
- 2. 无序多分类问题
- 多分类logistic的回归预测
- 2.1 多分类Logistic回归的两种算法
- 2.1.1 算法1:修改概率映射函数
- 2.1.2 算法2:一对其余算法
- 3. 以预测为目的分类问题实操流程——基于sklearn
- 3.1 划分训练集/测试集
- 3.2 训练模型/模型预测
- 3.3 预测结果分析
回归和分类是数据分析的两大重要任务
回归分析的因变量是连续变量;
分类分析的因变量是分类属性变量
在进行分类分析之前,我们必须要弄清楚我们建模的目的是推断还是预测
以推断/分析为主,那么我们在建模时所采用的模型最好是易于解释的白盒模型,如一众线性模型
以预测为主,则我们建模的依据主要是预测的精度,模型的可解释性相对而言不那么重要
对于分类任务而言,当前预测精度高的模型基本上都是深度学习/机器学习模型(如:支持向量机、随机森林、Xgboost等),而这些模型的可解释性一般都很差
如果我们追求分类模型的可解释性,探究各自变量对分类决策的影响,那么使用线性模型框架下的分类模型就比较合适了(如:Logistic回归、Probit回归等)。
分类问题按照被分类对象的类别划分,总共可以分为三类:二分类问题、无序多分类问题、有序多分类问题。
二分类问题:二分类Logistic回归模型与Probit模型
无序多分类问题(二分类问题的延伸):多类别logistic回归模型建模
有序多分类问题:有序Logistic回归
· Example12. ST是我国股市特有的一项保护投资者利于的决策,当上市公司因财务状况不佳导致投资者难以预测其前景时,交易所会标记该公司股票为ST,并进行一系列限制措施。而在这项任务中,因变量就是公司是否会被ST,数学表示为:
y
=
{
1
,
S
T
0
,
Otherwise
y= begin{cases}1, & S T \ 0, & text { Otherwise }end{cases}
y={1,0,ST Otherwise
在回归问题中,对于一个待预测样本 x x x,模型输出值 y ^ hat{y} y^的性质就是因变量的性质
概率!准确来说是在给定
x
x
x下,
y
=
1
y=1
y=1的概率
P
(
y
=
1
∣
x
)
P(y=1 mid x)
P(y=1∣x)
· 概率的映射
与回归问题因变量天然确定的情况不一样,分类问题中概率的形式是需要我们人为确定的,即我们要确定如何将线性模型的直接输出值
y
y
y映射成概率值
P
(
y
=
1
∣
x
)
P(y=1 mid x)
P(y=1∣x)。
我们可以看到多元线性模型
y
=
β
0
+
β
1
x
1
+
⋯
+
β
k
x
k
+
u
y=beta_{0}+beta_{1} x_{1}+cdots+beta_{k} x_{k}+u
y=β0+β1x1+⋯+βkxk+u
的输出值
y
y
y是一个连续变量,而概率也是一个连续的变量,那么我们能不能让这个输出值
y
=
P
(
y
=
1
∣
x
)
y=P(y=1 mid x)
y=P(y=1∣x)呢?即有
P
(
y
=
1
∣
x
)
=
y
=
β
0
+
β
1
x
1
+
⋯
+
β
k
x
k
+
u
P(y=1mid x)=y=beta _0+beta _1x_1+cdots +beta _kx_k+u
P(y=1∣x)=y=β0+β1x1+⋯+βkxk+u
这样做有一个最大的缺点——
y
^
hat{y}
y^可能不在区间(0,1)内,而概率只能在(0,1)区间内。(当然,还有其他的缺点,但大家只需要记住这个就可以了)
若映射函数为Logistic函数
G
(
y
)
=
1
1
+
e
−
y
G(y)=frac{1}{1+e^{-y}}
G(y)=1+e−y1
则整个预测模型被称为Logistic线性回归模型
若映射函数为Probit函数
Φ
(
y
)
=
P
(
Y
≤
y
)
=
∫
−
∞
y
1
2
π
exp
(
−
1
2
x
2
)
d
x
Phi(y)=P(Y leq y)=int_{-infty}^{y} frac{1}{sqrt{2 pi}} exp left(-frac{1}{2} x^{2}right) d x
Φ(y)=P(Y≤y)=∫−∞y2π
1exp(−21x2)dx
则整个预测模型被称为Probit线性回归模型。注意到,Probit函数实际上就是标准正态分布的累积函数。
(1)单调递增性质的可逆函数
(2)值域位于(0,1)之间
记
y
=
x
′
β
=
β
0
+
β
1
x
1
+
⋯
+
β
k
x
k
y=x^{prime} beta=beta_{0}+beta_{1} x_{1}+cdots+beta_{k} x_{k}
y=x′β=β0+β1x1+⋯+βkxk,则Logistic回归模型形式为
P
(
y
=
1
∣
x
)
=
p
(
x
)
=
1
1
+
e
−
y
=
1
1
+
e
−
x
′
β
P(y=1 mid x)=pleft( x right) =frac{1}{1+e^{-y}}=frac{1}{1+e^{-x^{'}beta}}
P(y=1∣x)=p(x)=1+e−y1=1+e−x′β1
log
(
p
(
x
)
1
−
p
(
x
)
)
=
β
0
+
β
1
x
1
+
⋯
+
β
k
x
k
log left(frac{p(x)}{1-p(x)}right)=beta_{0}+beta_{1} x_{1}+cdots+beta_{k} x_{k}
log(1−p(x)p(x))=β0+β1x1+⋯+βkxk
Logistic回归模型与一般多元回归模型的一大区别在于,前者的因变量是一个有关概率
p
(
y
=
1
∣
x
)
pleft( y=1|x right)
p(y=1∣x)的函数,而后者的因变量只是其本身。
胜率(odd)=成功/失败
当其他自变量不变时,变量
x
i
x_i
xi提升一个单位,胜率odd会提升
β
j
%
beta_j %
βj%
import pandas as pd import numpy as np import statsmodels.api as sm from scipy import stats
st_logit=sm.formula.logit('ST~ARA+ASSET+ATO+ROA+GROWTH+LEV+SHARE',data=ST).fit()
print(st_logit.summary())
Probit线性回归模型
模型形式:
Probit回归模型形式为
p
(
x
)
=
Φ
(
x
′
β
)
p(x)=Phileft(x^{prime} betaright)
p(x)=Φ(x′β)
其中,
Φ
Phi
Φ就是标准正态分布的累积函数
模型解释:
Probit模型的系数解释不直观,但可以确定的是,当
β
j
>
0
beta_j>0
βj>0时,
x
j
x_j
xj的增加会导致响应概率
p
(
x
)
p(x)
p(x)的增加。
st_probit=sm.formula.probit('ST~ARA+ASSET+ATO+ROA+GROWTH+LEV+SHARE',data=ST).fit()
print(st_probit.summary())
模型推断
Logistic回归与Probit回归在统计推断上是一致的。
与OLS估计的多元线性回归不同的是,这两种分类回归模型采用的是极大似然估计法对模型参数进行估计,在极大似然估计的一般理论下,我们可以证明模型估计系数
β
^
hat{beta}
β^是
β
beta
β的一致估计。
基于极大似然估计的Logistic回归与Probit回归与基于OLS的多元线性回归在参数假设检验的思想上是相似的,只不过它们的检验统计量所服从的分布会有所不同。
· 单参数显著性检验
假设设置如下:
H
0
:
β
j
=
β
j
0
↔
H
1
:
β
j
≠
β
j
0
H_{0}: beta_{j}=beta_{j 0} leftrightarrow H_{1}: beta_{j} neq beta_{j 0}
H0:βj=βj0↔H1:βj=βj0
则单参数检验统计量为
β
^
j
−
β
j
s
d
(
β
^
j
)
⇒
N
(
0
,
1
)
frac{hat{beta}_{j}-beta_{j}}{s dleft(hat{beta}_{j}right)} Rightarrow N(0,1)
sd(β^j)β^j−βj⇒N(0,1)
该统计量渐进服从标准正态分布,可以看到,python中播报的也是z统计量的p值。
print('logistic回归报告')
print(st_logit.summary().tables[1])
print('----------------------------')
print('probit回归报告')
print(st_probit.summary().tables[1])
· 多参数联合显著性检验
在Logit模型与Probit模型中,我们同样可以检验部分因素的统计显著性,且检验的思想依旧是比较有约束模型与无约束模型的“差异度”。
与多元线性回归模型不一样的是,分类模型没有残差平方和RSS的概念,那么联合检验的检验统计量自然也不是原来的F统计量了。但是,在似然理论下,存在一个比残差平方和更广泛的概念——离差(Deviance)
D
e
v
i
a
n
c
e
=
−
2
⋅
l
o
g
(
l
i
k
e
l
i
h
o
o
d
(
m
o
d
e
l
)
)
,,mathrm{Deviance} =-2cdot logleft( likelihood(model) right)
Deviance=−2⋅log(likelihood(model))
它是-2倍的模型对数似然比,而模型的对数似然比在summary播报中正是指标Log-Likelihood。
当两个模型的离差足够大时
D
r
−
D
u
r
>
C
D_{r}-D_{u r}>C
Dr−Dur>C
我们便可以拒绝原假设,认为参数是联合显著的。
与其他假设检验一样,我们需要知道该检验所采用的检验统计量及其服从的分布,计算p值后再判断是否拒绝原假设。在这个检验中,似然比检验统计量定义为
L
R
=
2
(
l
u
r
−
l
r
)
=
D
r
−
D
u
r
∼
H
0
χ
q
2
L R=2left(l_{u r}-l_{r}right)=D_{r}-D_{u r} sim^{H_{0}} chi_{q}^{2}
LR=2(lur−lr)=Dr−Dur∼H0χq2
它服从自由度为约束个数
q
q
q的卡方分布,因此我们需要用卡方分布累积分布函数。
我们用python实现logit模型多参数显著性检验,原假设设为
H
0
:
β
1
=
β
2
=
⋯
=
β
7
=
0
H_{0}: beta_{1}=beta_{2}=cdots=beta_{7}=0
H0:β1=β2=⋯=β7=0
#训练有约束的模型
st_logit_r=sm.formula.logit('ST~1',data=ST).fit()
# 计算检验统计量
st_logit_ll=st_logit.llf
st_logit_r_ll=st_logit_r.llf
LR=2*(st_logit_ll-st_logit_r_ll)
# 计算p值
pvalue=stats.chi2.sf(LR,7)
print('联合检验的p值为:{}'.format(pvalue))
分类预测
1.5.1 模型预测的原理
对于一组给定的解释变量取值
x
0
x_0
x0,我们将之代入模型中计算概率值
p
(
x
)
p(x)
p(x)
p
^
(
x
0
)
=
e
x
0
′
β
^
1
+
e
x
0
′
β
^
hat{p}left(x_{0}right)=frac{e^{x_{0}^{prime} hat{beta}}}{1+e^{x_{0}^{prime} hat{beta}}}
p^(x0)=1+ex0′β^ex0′β^
这一概率是在样本自变量
x
=
x
0
x=x_0
x=x0下,
y
0
=
1
y_0=1
y0=1的概率
# 输出st_logit模型对ST数据集前五个样本的预测p(x) logit_pred=st_logit.predict() print(logit_pred[:5])
规定一个阈值
α
alpha
α,当概率
p
(
x
)
>
α
p(x)>alpha
p(x)>α时,样本被划分为1类,否则划分为0类。即
y
^
0
=
{
1
,
p
^
(
x
0
)
>
α
0
,
Otherwise
hat{y}_{0}= begin{cases}1, & hat{p}left(x_{0}right)>alpha \ 0, & text { Otherwise }end{cases}
y^0={1,0,p^(x0)>α Otherwise
一般情况下,阈值
α
alpha
α默认为0.5。
logit_res=list()
for i in np.arange(len(logit_pred)):
if logit_pred[i]>0.5:
logit_res.append(1)
else :
logit_res.append(0)
#输出前5个样本的预测
print('前五个样本的预测结果为:{}'.format(logit_res[:5]))
1.5.2 预测结果呈现——混淆矩阵与多指标
评判模型的预测性能
混淆矩阵import mglearn mglearn.plots.plot_binary_confusion_matrix()
negative通常指代“反类”,分类标签通常设置为0;
positive通常指代“正类”,分类标签通常设置为1
横行表示样本实际的属性
纵列表示样本被模型预测的属性
from sklearn.metrics import confusion_matrix confusion_matrix(ST.ST,logit_res) # 注意:第一个值输入的是真实的标签集, #第二个值输入的是预测的标签集
在阈值
α
=
0.5
alpha=0.5
α=0.5下
logit模型的分类精度(也就是分类正确率),分类精度的公式为
A
c
c
u
r
a
c
y
=
T
P
+
T
N
T
P
+
T
N
+
F
P
+
F
N
Accuracy=frac{TP+TN}{TP+TN+FP+FN}
Accuracy=TP+TN+FP+FNTP+TN
# 计算logits模型分类精度
logit_accuracy=(647+1)/(647+1+35+1)
print('分类精度为{}'.format(logit_accuracy))
“样本不均衡”
仅靠分类精度是远远不够。还需要引入精确率、召回率、F分数。
精确率(Precision) 衡量的是所有被预测为正类的样本中,预测正确的比例,公式为:
P
r
e
c
i
s
i
o
n
=
T
P
T
P
+
F
P
Precision=frac{TP}{TP+FP}
Precision=TP+FPTP
# 以st=1为正类,计算logits模型精确率
logit_precision=(1)/(1+1)
print('精确率为{}'.format(logit_precision))
召回率(Recall) 衡量的是所有正类样本中,预测正确的比例,公式为:
R
e
c
a
l
l
=
T
P
T
P
+
F
N
mathrm{Re}call=frac{TP}{TP+FN}
Recall=TP+FNTP
# 以st=1为正类,计算logits模型召回率
logit_recall=(1)/(1+35)
print('召回率为{}'.format(logit_recall))
F分数(F-score) 是精确率与召回率的调和平均,是两者的综合取舍,公式为:
F
−
s
c
o
r
e
=
2
⋅
p
r
e
c
i
s
i
o
n
⋅
r
e
c
a
l
l
p
r
e
c
i
s
i
o
n
+
r
e
c
a
l
l
F-score=2cdot frac{precisioncdot recall}{precision+recall}
F−score=2⋅precision+recallprecision⋅recall
# 以st=1为正类,计算logits模型F分数
logit_f1=2*logit_recall*logit_precision/(logit_recall+logit_precision)
print('F分数为{}'.format(logit_f1))
还可以使用一个输出以上所有指标的函数。
from sklearn.metrics import classification_report print(classification_report(ST.ST,logit_res)) # 注意:第一个值输入的是真实的标签集, #第二个值输入的是预测的标签集1.5.3 对抗不平衡数据集——改变阈值
不平衡的数据集会导致模型的训练产生偏好性,由于ST=0的样本远远多于ST=1的样本,模型会更多地学习到ST=0的样本特征,而对ST=1的样本特征学习不足,于是对于一个未知样本,模型会更倾向于将它预测成大样本的类别。
可以降低“门槛”
α
alpha
α,让其等于一个很小的数,这样子又可以有更多的样本被预测到ST=1的行列当中了。
logit_res=list() for i in np.arange(len(logit_pred)): if logit_pred[i]>0.0526: logit_res.append(1) else: logit_res.append(0) # 混淆矩阵 print(confusion_matrix(ST.ST,logit_res)) # 综合报告 print(classification_report(ST.ST,logit_res))
能改变样本预测的分布,使分布更符合我们实际的需求
需要改进预测效果,要么换一种精度更高的模型,要么进行调参处理
无序多分类Logistic回归
sklearn也具有做Logistic回归的功能,但它注重预测结果输出,而在统计推断结果的可视化上,sklearn做的远远不如statsmodels。
K类别的多分类Logistic回归主要有两种:
一种是修改概率映射函数,将其中一个类作为基类,通过修改过后的映射函数获得k-1个对数胜率;
另一种是“一对其余”(one-vs-rest),对每个类别都建立一个二分类Logistic回归,将本类别的样本定义为0,其余类别的样本定义为1,在所有类别的分类器中,概率
p
p
p最高的类别就是实际判定的类别。
二分类Logistic回归的模型
log
(
p
(
x
)
1
−
p
(
x
)
)
=
β
0
+
β
1
x
1
+
⋯
+
β
k
x
k
log left(frac{p(x)}{1-p(x)}right)=beta_{0}+beta_{1} x_{1}+cdots+beta_{k} x_{k}
log(1−p(x)p(x))=β0+β1x1+⋯+βkxk
等式稍微变化一下
log
(
p
(
y
=
1
∣
x
)
p
(
y
=
0
∣
x
)
)
=
β
0
+
β
1
x
1
+
⋯
+
β
k
x
k
log left( frac{p(y=1|x)}{p(y=0|x)} right) =beta _0+beta _1x_1+cdots +beta _kx_k
log(p(y=0∣x)p(y=1∣x))=β0+β1x1+⋯+βkxk
多分类问题选取一个类别作为基类,分别计算0类与剩余类别之间的对数概率之比
g
m
(
x
)
=
log
(
p
(
y
=
m
∣
x
)
p
(
y
=
0
∣
x
)
)
=
β
m
0
+
β
m
1
x
1
+
⋯
+
β
m
k
x
k
,
m
=
1
,
…
,
M
g_mleft( x right) =log left( frac{p(y=m|x)}{p(y=0|x)} right) =beta _{m0}+beta _{m1}x_1+cdots +beta _{mk}x_ktext{,}m=1,…,M
gm(x)=log(p(y=0∣x)p(y=m∣x))=βm0+βm1x1+⋯+βmkxk,m=1,…,M
这些函数的实际意义是“目标类别
j
j
j与基类
0
0
0的对数胜率”
使用一个变式的Logit映射函数计算每个类别的条件概率
P
(
y
=
m
∣
x
)
P(y=mmid mathbf{x})
P(y=m∣x)
P
(
y
=
m
∣
x
)
=
e
g
m
(
x
)
1
+
∑
m
=
1
M
−
1
e
g
m
(
x
)
P(y=mmid mathbf{x})=frac{e^{g_m(mathbf{x})}}{1+sum_{m=1}^{M-1}{e^{g_m(mathbf{x})}}}
P(y=m∣x)=1+∑m=1M−1egm(x)egm(x)
在进行模型预测的时候,我们可以先选出这M-1个概率中的最大概率者,在用这个概率与阈值 α alpha α进行比较。
2.1.2 算法2:一对其余算法将二分类算法推广至多分类算法的一种常见方法就是“一对其余”
对每个类别都学习一个二分类模型,将这个类别与所有其余类别尽量分开,这样会生成与类别个数M相同个数的分类器,每个分类器都会输出一个概率,概率最高者“胜出”,并将这个类别的标签返回作为预测结果。
sklearn中的LogisticRegression的多分类形式就是采用了这样的算法。我们用一个含有三个类别、两个特征的玩具数据集来实操一波,来看看模型是如何处理多分类问题的
# 加载基础包 import mglearn import matplotlib.pyplot as plt from IPython.display import display
# 加载数据集
from sklearn.datasets import make_blobs
X,y=make_blobs(random_state=42)
print('前5个样本的X特征',X[:5])
print('前5个样本的y标签',y[:5])
# 利用散点图对数据集进行可视化
mglearn.discrete_scatter(X[:,0],X[:,1],y)
plt.xlabel('feature 0')
plt.ylabel('feature 1')
plt.legend(['class 0','class 1','class 2'])
训练一个多分类Logistic回归模型,对上述样本进行分类。
from sklearn.linear_model import LogisticRegression
logis_multi=LogisticRegression(multi_class='multinomial').fit(X,y)
# 不同于statsmodels,在sklearn中我们需要在接口fit()中填入训练模型的数据,X为自变量数据,y为因变量数据
# 查看三个分类模型的模型参数
## 截距
print(logis_multi.intercept_)
## 系数
print(logis_multi.coef_)
######将三个分类器所代表的直线画到上图中
mglearn.discrete_scatter(X[:,0],X[:,1],y)
line_x=np.linspace(-15,15)
for coef,intercept,color in zip(logis_multi.coef_,logis_multi.intercept_,['b','r','g']):
plt.plot(line_x,-(line_x*coef[0]+intercept)/coef[1],c=color)
plt.ylim(-10,15)
plt.xlim(-10,8)
plt.xlabel('feature 0')
plt.ylabel('feature 1')
plt.legend(['class 0','class 1','class 2','line class 0','line class 1','line class 2'],loc=(1.01,0.3))
3. 以预测为目的分类问题实操流程——基于sklearn
3.1 划分训练集/测试集
#加载函数
from sklearn.model_selection import train_test_split
#数据集切分
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.25,random_state=0)
# test_size为测试集数据量占原始数据的比例
print('train_size',len(X_train)/len(X))
print('test_size',len(X_test)/len(X))
3.2 训练模型/模型预测
from sklearn.linear_model import LogisticRegression # 使用训练集进行训练 logit_multi=LogisticRegression(multi_class='multinomial').fit(X_train,y_train) # 使用测试集进行预测 y_pred=logis_multi.predict(X_test) # 查看预测结果 print(y_pred)3.3 预测结果分析
完成预测后,我们需要对模型的预测结果进行分析,常见的分析指标有:分类精度,精确率,召回率,f分数等;当然,我们可以输出混淆矩阵。



