Logistic回归模型

Logistic回归模型

Logistich回归模型也被成为广义线性回归模型。
它是将线性回归模型的预测值经过非线性的Logit函数转换为[0,1]之间的概率值。
研究得是分类问题,跟之前的线性回归、岭回归、Lasso回归不同。

混淆矩阵

 					实际值
预				0			1	
测		0		A			B		A+B
值		1		C			D		C+D
			  	A+C			B+D
--------------------------------------------------    
A:表示正确预测负例的样本个数,⽤TN表示。
B:表示预测为负例但实际为正例的个数,⽤FN表示。
C:表示预测为正例但实际为负例的个数,⽤FP表示。
D:表示正确预测正例的样本个数,⽤TP表示。
准确率:表示正确预测的正负例样本数与所有样本数量的⽐值,即(A+D)/(A+B+C+D)。
正例覆盖率:表示正确预测的正例数在实际正例数中的⽐例,即D/(B+D)。
负例覆盖率:表示正确预测的负例数在实际负例数中的⽐例,即A/(A+C)。
正例命中率:表示正确预测的正例数在预测正例数中的⽐例,即D/(C+D)。

ROC曲线

通常绘制ROC曲线,不仅仅是得到左侧的图形,更重要的是计算
折线下的⾯积,即图中的阴影部分,这个⾯积称为AUC。
在做模型评估时,希望AUC的值越⼤越好,通常情况下,
当AUC在0.8以上时,模型就基本可以接受了。

KS曲线

# 导入第三方模块
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 自定义绘制ks曲线的函数
def plot_ks(y_test, y_score, positive_flag):
    # 对y_test重新设置索引
    y_test.index = np.arange(len(y_test))
    # 构建目标数据集
    target_data = pd.DataFrame({'y_test':y_test, 'y_score':y_score})
    # 按y_score降序排列
    target_data.sort_values(by = 'y_score', ascending = False, inplace = True)
    # 自定义分位点
    cuts = np.arange(0.1,1,0.1)
    # 计算各分位点对应的Score值
    index = len(target_data.y_score)*cuts
    scores = np.array(target_data.y_score)[index.astype('int')]
    # 根据不同的Score值,计算Sensitivity和Specificity
    Sensitivity = []
    Specificity = []
    for score in scores:
        # 正例覆盖样本数量与实际正例样本量
        positive_recall = target_data.loc[(target_data.y_test == positive_flag) & (target_data.y_score>score),:].shape[0]
        positive = sum(target_data.y_test == positive_flag)
        # 负例覆盖样本数量与实际负例样本量
        negative_recall = target_data.loc[(target_data.y_test != positive_flag) & (target_data.y_score<=score),:].shape[0]
        negative = sum(target_data.y_test != positive_flag)
        Sensitivity.append(positive_recall/positive)
        Specificity.append(negative_recall/negative)
    # 构建绘图数据
    plot_data = pd.DataFrame({'cuts':cuts,'y1':1-np.array(Specificity),'y2':np.array(Sensitivity), 
                              'ks':np.array(Sensitivity)-(1-np.array(Specificity))})
    # 寻找Sensitivity和1-Specificity之差的最大值索引
    max_ks_index = np.argmax(plot_data.ks)
    plt.plot([0]+cuts.tolist()+[1], [0]+plot_data.y1.tolist()+[1], label = '1-Specificity')
    plt.plot([0]+cuts.tolist()+[1], [0]+plot_data.y2.tolist()+[1], label = 'Sensitivity')
    # 添加参考线
    plt.vlines(plot_data.cuts[max_ks_index], ymin = plot_data.y1[max_ks_index], 
               ymax = plot_data.y2[max_ks_index], linestyles = '--')
    # 添加文本信息
    plt.text(x = plot_data.cuts[max_ks_index]+0.01,
             y = plot_data.y1[max_ks_index]+plot_data.ks[max_ks_index]/2,
             s = 'KS= %.2f' %plot_data.ks[max_ks_index])
    # 显示图例
    plt.legend()
    # 显示图形
    plt.show()
    
    
# 导入虚拟数据
virtual_data = pd.read_excel(r'virtual_data.xlsx')
# 应用自定义函数绘制k-s曲线
plot_ks(y_test = virtual_data.Class, y_score = virtual_data.Score,positive_flag = 'P')
    
    
'''
于KS值⽽⾔,是希望越⼤越好,通常情况下,当KS值⼤于0.4时,模型基本可以接受。
'''

函数说明

LogisticRegression(tol=0.0001, fit_intercept=True,class_weight=None, max_iter=100)

tol:⽤于指定模型跌倒收敛的阈值
fit_intercept:bool类型参数,是否拟合模型的截距项,默认为True
class_weight:⽤于指定因变量类别的权重,如果为字典,则通过字典的形式{class_label:weight}传
递每个类别的权重;如果为字符串'balanced',则每个分类的权重与实际样本中的⽐例成反⽐,当各分
类存在严重不平衡时,设置为'balanced'会⽐较好;如果为None,则表示每个分类的权重相等
max_iter:指定模型求解过程中的最⼤迭代次数, 默认为100

演示

# 导入第三方模块
import pandas as pd
import numpy as np
from sklearn import model_selection
from sklearn import linear_model

# 读取数据
sports = pd.read_csv(r'Run or Walk.csv')
# 提取出所有自变量名称
predictors = sports.columns[4:]
# 构建自变量矩阵
X = sports.ix[:,predictors]
# 提取y变量值
y = sports.activity
# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = model_selection.train_test_split(X, y, test_size = 0.25, random_state = 1234)

# 利用训练集建模
sklearn_logistic = linear_model.LogisticRegression()
sklearn_logistic.fit(X_train, y_train)
# 返回模型的各个参数
print(sklearn_logistic.intercept_, sklearn_logistic.coef_)

# 模型预测
sklearn_predict = sklearn_logistic.predict(X_test)
# 预测结果统计
pd.Series(sklearn_predict).value_counts()

# 导入第三方模块
from sklearn import metrics
# 混淆矩阵
cm = metrics.confusion_matrix(y_test, sklearn_predict, labels = [0,1])
cm

# 计算正确与覆盖率
Accuracy = metrics.scorer.accuracy_score(y_test, sklearn_predict)
Sensitivity = metrics.scorer.recall_score(y_test, sklearn_predict)
Specificity = metrics.scorer.recall_score(y_test, sklearn_predict, pos_label=0)
print('模型准确率为%.2f%%:' %(Accuracy*100))
print('正例覆盖率为%.2f%%' %(Sensitivity*100))
print('负例覆盖率为%.2f%%' %(Specificity*100))

# 混淆矩阵的可视化
# 导入第三方模块
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib
# 绘制热力图
sns.heatmap(cm, annot = True, fmt = '.2e',cmap = 'GnBu')
# 图形显示
plt.show()

sklearn_logistic.predict_proba(X_test)
# y得分为模型预测正例的概率
y_score = sklearn_logistic.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')
# 添加边际线
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)
# 添加x轴与y轴标签
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
# 显示图形
plt.show()

# 调用自定义函数,绘制K-S曲线
plot_ks(y_test = y_test, y_score = y_score, positive_flag = 1)
posted @ 2020-10-30 01:47  最冷不过冬夜  阅读(1706)  评论(0编辑  收藏  举报