Logistic回归是一种广义线性回归模型,解决的是因变量为二分类变量的预测或判别问题。
一、模型建立
1.Logit函数
其中,当z趋向于正无穷大时g(z)趋向于1;当z趋向于负无穷大时g(z)趋向于0;当z=0时g(z)=0.5。
2.Logistic模型
如果将z换成多元线性回归模型的形式,,则这就是Logistic回归模型,通过Logit变换将线性回归模型的预测值转换为[0,1]之间的概率值。
3.优势比(odds)
对于给定,代表了y取1的概率,代表了y取0的概率。这两个条件概率我们分别表示为
称为优势比或发生比,代表了某个事件发生与不发生的概率比值。而
二、参数推导
条件概率可以改写为其中y=1或0。
由于是非线性模型,很难直接求得参数的无偏估计,所以Logistic回归模型通常使用最大似然估计,并采取梯度下降法求得未知参数。
1.最大似然估计
最大似然估计:假设某一个分布的概率密度函数(连续型)或概率分布律(离散型)为,其中为未知参数,从分布中抽取一个包含n个值的样本,则可以计算出其概率,最大似然估计的思想通俗的理解就是我们已经抽取到了这样一个样本,那么这个样本出现的概率应该是很大的,所以的取值应该是使得最大的那个。
假设样本集合为包含n个样本,且相互独立,则似然函数为
求似然函数最大值通常做对数处理
目标是要寻找使得最大。但这里令是无法简单求得的,因为求偏导并非关于的多元一次方程组。这里采用梯度下降法求得参数。
2.梯度下降法
梯度下降法:对于可微的,向量称为的梯度,则沿梯度的负方向函数值是下降最快的,则可以通过不断的按一定的步长沿梯度负方向运动,一般情况下,梯度向量为0的话说明是到了一个极值点,此时运动的幅值也为0。迭代公式为,是学习率,也就是参数变化的步长,可以取0.1,0.05,0.01等。实际运用中只需要小于一个非常小的阈值即可。
由于最大似然估计要求的是似然函数取最大值,而梯度下降求的是最小值,所以令,迭代过程为
表示第j个变量在第i个样本上的观测值。
三、分类模型的评估
1.混淆矩阵
如果所示就是一个混淆矩阵,竖向代表预测值,横向代表实际值,都分别有0和1两个类别,对角线上的A和D表示正确预测的数量,非对角线上的B和C表示未正确预测的数量。通过混淆矩阵可以得到四个指标:
- 准确率(Accuracy):(A+D)/(A+B+C+D)
- 正例覆盖率(Sensitivity):D/(B+D)
- 负例覆盖率(Specificity):A/(A+C)
- 正例命中率(Precision):D/(C+D)
前三个指标越高,说明模型越理想。
2.ROC曲线
ROC曲线x轴为1-Specificity,即负例错判率;y轴为Sensitivity,即正例覆盖率。Logistic回归模型得到的是一个[0,1]之间的值,设置不同的值作为判断类别的阈值会将样本预测为不同的类别(比如Logistic回归模型得到的值是0.6,如果我们设置阈值为0.5,则将其预测为正例;如果设置阈值为0.7,则将其预测为负例)。[0,1]上的每一个不同的阈值就对应了一对(1-Specificity, Sensitivity),于是就组成了ROC曲线。
红色虚线作为参考线代表了不使用模型的情况下1-Specificity与Sensitivity之比恒等于1。ROC曲线下方的面积称为AUC(Area Under Curve),AUC越大越好,通常高于0.8就可以。
3.K-S曲线
(1)将样本代入Logistic回归模型计算得到的值从大到小排序。
(2)取出10%,20%,…,90%对应的分位数,分别以此分位数作为阈值,计算1-Specificity与Sensitivity。
(3)以10%,20%,…,90%为x轴坐标,以对应的1-Specificity与Sensitivity值为y轴坐标绘制两条曲线。
如图两条折线分别代表不同分位点下的1-Specificity与Sensitivity曲线,KS值等于Sensitivity-(1-Specificity),通常以最大的KS值作为衡量模型的指标,KS值越大越好,通常大于0.4就可以。
四、代码实现
LogisticRegression(penalty=‘l2’, dual=False, tol=0.0001, C=1.0, fit_intercept=True, intercept_scaling=1, class_weight=None, random_state=None, solver=‘liblinear’, max_iter=100, multi_class=‘ovr’, verbose=0, warm_start=False, n_jobs=1)
• penalty:为Logistic回归模型的目标函数添加正则化惩罚项,默认为L2范数。
• dual:bool类型,是否求解对偶形式,默认为False。只有penalty参数为’l2’、solver参数为’liblinear’时才可使用对偶形式。
• tol:指定模型迭代收敛的阈值。
• C:指定惩罚项系数的倒数,值越小,正则化项越大。
• fit_intercept:bool类型,是否拟合模型的截距项,默认为True。相当于在X数据集上人为添加常数列1,用于计算截距项。
• intercept_scaling:当solver参数为’liblinear’时该参数有效,用于降低X矩阵中人为设定的常数列1的影响。
• class_weight:指定因变量类别的权重,可通过字典的形式{class_label:weight};也可通过字符串的形式,‘balanced’表示每个分类的权重与实际样本中的比例成反比,None表示每个分类权重相等。
• random_state:指定随机数生成器的种子。
• solver:指定求解目标函数最优化的算法,默认为’liblinear’。
• max_iter:指定模型求解最大的迭代次数,默认为100。
• multi_class:当因变量不止两个分类时通过此参数指定多分类问题的解决办法,默认为’ovr’,即one-vs-rest方法,也可指定’multinomial’,使用多分类逻辑回归模型(Softmax分类)。
• verbose:bool类型,是否输出模型迭代过程的信息,默认为0不输出。
• warm_start:bool类型,是否基于上一次训练结果继续训练模型,默认为False。
• n_jobs:指定CPU使用数量,默认为1,如果为-1表示使用所有可用的CPU。
import pandas as pd
from sklearn import linear_model
from sklearn import model_selection
from sklearn import metrics
import matplotlib.pyplot as plt
import seaborn as sns
data=pd.read_csv(r'C:\Users\Administrator\Desktop\Run or Walk.csv')
predictors=data.columns[4:]
#构建自变量矩阵
X=data[predictors]
#因变量y
y=data.activity
#拆分训练集和测试集
X_train,X_test,y_train,y_test=model_selection.train_test_split(X,y,test_size=0.25,random_state=1234)
#建模
logistic_model=linear_model.LogisticRegression()
logistic_model.fit(X_train,y_train)
#打印参数
print('Intercept:',logistic_model.intercept_)
print('Coef:',logistic_model.coef_)
#模型预测
pred=logistic_model.predict(X_test)
print(pd.Series(pred).value_counts())
#模型评估
#混淆矩阵
cm=metrics.confusion_matrix(y_test,pred,labels=[0,1])
print('混淆矩阵:\n',cm)
Accuracy=metrics.scorer.accuracy_score(y_test,pred)
Sensitivity=metrics.scorer.recall_score(y_test,pred)
Specificity=metrics.scorer.recall_score(y_test,pred,pos_label=0)
print('准确率:%.2f%%' % (Accuracy*100))
print('正例覆盖率:%.2f%%' % (Sensitivity*100))
print('负例覆盖率:%.2f%%' % (Specificity*100))
#绘制混淆矩阵的热力图
sns.heatmap(cm,annot=True,fmt='.2e',cmap='GnBu')
plt.show()
#ROC曲线
#y_score为模型预测正例的概率
y_score=logistic_model.predict_proba(X_test)[:,1]
#计算不同阈值下,fpr和tpr的组合之,fpr表示1-Specificity,tpr表示Sensitivity
fpr,tpr,threshold=metrics.roc_curve(y_test,y_score)
#计算AUC
roc_auc=metrics.auc(fpr,tpr)
#绘制面积图
plt.stackplot(fpr,tpr,color='steelblue',alpha=0.5,edgecolor='black')
#添加ROC曲线的轮廓
plt.plot(fpr,tpr,color='black',lw=1)
#添加对角线作为参考线
plt.plot([0,1],[0,1],color='red',linestyle='--')
plt.text(0.5,0.3,'ROC curve (area=%0.2f)' % roc_auc)
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
plt.show()
参考文献:
[1]Peter Harrington.《机器学习实战》.人民邮电出版社,2013-6
[2]刘顺祥.《从零开始学Python数据分析与挖掘》.清华大学出版社,2018