TASK04|分类分析

分类分析

回归和分类是数据分析的两大重要任务
回归分析的因变量是连续变量;
分类分析的因变量是分类属性变量
在进行分类分析之前,我们必须要弄清楚我们建模的目的是推断还是预测
以推断/分析为主,那么我们在建模时所采用的模型最好是易于解释的白盒模型,如一众线性模型
以预测为主,则我们建模的依据主要是预测的精度,模型的可解释性相对而言不那么重要

对于分类任务而言,当前预测精度高的模型基本上都是深度学习/机器学习模型(如:支持向量机、随机森林、Xgboost等),而这些模型的可解释性一般都很差
如果我们追求分类模型的可解释性,探究各自变量对分类决策的影响,那么使用线性模型框架下的分类模型就比较合适了(如:Logistic回归、Probit回归等)。

分类问题与对应的模型

分类问题按照被分类对象的类别划分,总共可以分为三类:二分类问题、无序多分类问题、有序多分类问题。

二分类问题:二分类Logistic回归模型与Probit模型
无序多分类问题(二分类问题的延伸):多类别logistic回归模型建模
有序多分类问题:有序Logistic回归

二分类问题

1.1 线性回归模型是如何处理分类问题的

· 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=1x)

· 概率的映射
与回归问题因变量天然确定的情况不一样,分类问题中概率的形式是需要我们人为确定的,即我们要确定如何将线性模型的直接输出值 y y y映射成概率值 P ( y = 1 ∣ x ) P(y=1 \mid x) P(y=1x)

我们可以看到多元线性模型
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=1x)呢?即有
P ( y = 1 ∣ x ) = y = β 0 + β 1 x 1 + ⋯ + β k x k + u P(y=1\mid x)=y=\beta _0+\beta _1x_1+\cdots +\beta _kx_k+u P(y=1x)=y=β0+β1x1++βkxk+u
这样做有一个最大的缺点—— y ^ \hat{y} y^可能不在区间(0,1)内,而概率只能在(0,1)区间内。(当然,还有其他的缺点,但大家只需要记住这个就可以了)

两种映射函数——Logistic函数与Probit函数

logistic函数

若映射函数为Logistic函数
G ( y ) = 1 1 + e − y G(y)=\frac{1}{1+e^{-y}} G(y)=1+ey1
则整个预测模型被称为Logistic线性回归模型

Probit函数

若映射函数为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(Yy)=y2π 1exp(21x2)dx
则整个预测模型被称为Probit线性回归模型。注意到,Probit函数实际上就是标准正态分布的累积函数。

在这里插入图片描述
(1)单调递增性质的可逆函数
(2)值域位于(0,1)之间

logistic线性回归函数

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)=p\left( x \right) =\frac{1}{1+e^{-y}}=\frac{1}{1+e^{-x^{'}\beta}} P(y=1x)=p(x)=1+ey1=1+exβ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(1p(x)p(x))=β0+β1x1++βkxk
Logistic回归模型与一般多元回归模型的一大区别在于,前者的因变量是一个有关概率 p ( y = 1 ∣ x ) p\left( 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)=\Phi\left(x^{\prime} \beta\right) 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=βj0H1:βj=βj0
则单参数检验统计量为
β ^ j − β j s d ( β ^ j ) ⇒ N ( 0 , 1 ) \frac{\hat{\beta}_{j}-\beta_{j}}{s d\left(\hat{\beta}_{j}\right)} \Rightarrow N(0,1) sd(β^j)β^jβjN(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} =-2\cdot log\left( likelihood(model) \right) Deviance=2log(likelihood(model))

它是-2倍的模型对数似然比,而模型的对数似然比在summary播报中正是指标Log-Likelihood。

当两个模型的离差足够大时
D r − D u r > C D_{r}-D_{u r}>C DrDur>C

我们便可以拒绝原假设,认为参数是联合显著的。

与其他假设检验一样,我们需要知道该检验所采用的检验统计量及其服从的分布,计算p值后再判断是否拒绝原假设。在这个检验中,似然比检验统计量定义为
L R = 2 ( l u r − l r ) = D r − D u r ∼ H 0 χ q 2 L R=2\left(l_{u r}-l_{r}\right)=D_{r}-D_{u r} \sim^{H_{0}} \chi_{q}^{2} LR=2(lurlr)=DrDurH0χ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=2\cdot \frac{precision\cdot recall}{precision+recall} Fscore=2precision+recallprecisionrecall

# 以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))

能改变样本预测的分布,使分布更符合我们实际的需求
需要改进预测效果,要么换一种精度更高的模型,要么进行调参处理

2. 无序多分类问题

多分类logistic的回归预测

无序多分类Logistic回归
sklearn也具有做Logistic回归的功能,但它注重预测结果输出,而在统计推断结果的可视化上,sklearn做的远远不如statsmodels。

2.1 多分类Logistic回归的两种算法

K类别的多分类Logistic回归主要有两种:
一种是修改概率映射函数,将其中一个类作为基类,通过修改过后的映射函数获得k-1个对数胜率;
另一种是“一对其余”(one-vs-rest),对每个类别都建立一个二分类Logistic回归,将本类别的样本定义为0,其余类别的样本定义为1,在所有类别的分类器中,概率 p p p最高的类别就是实际判定的类别。

2.1.1 算法1:修改概率映射函数

二分类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(1p(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_m\left( x \right) =\log \left( \frac{p(y=m|x)}{p(y=0|x)} \right) =\beta _{m0}+\beta _{m1}x_1+\cdots +\beta _{mk}x_k\text{,}m=1,…,M gm(x)=log(p(y=0∣x)p(y=mx))=βm0+βm1x1++βmkxkm=1,,M
这些函数的实际意义是“目标类别 j j j与基类 0 0 0的对数胜率”

使用一个变式的Logit映射函数计算每个类别的条件概率 P ( y = m ∣ x ) P(y=m\mid \mathbf{x}) P(y=mx)
P ( y = m ∣ x ) = e g m ( x ) 1 + ∑ m = 1 M − 1 e g m ( x ) P(y=m\mid \mathbf{x})=\frac{e^{g_m(\mathbf{x})}}{1+\sum_{m=1}^{M-1}{e^{g_m(\mathbf{x})}}} P(y=mx)=1+m=1M1egm(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分数等;当然,我们可以输出混淆矩阵。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值