【数据分析实践】Task 1.3 模型评估

模型构建

导入包

import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score, precision_score, recall_score,\
                            confusion_matrix, f1_score, roc_curve, roc_auc_score
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from lightgbm import LGBMClassifier
from xgboost import XGBClassifier
import warnings

%matplotlib inline
plt.rc('font', family='SimHei', size=14)
plt.rcParams['axes.unicode_minus']=False
%config InlineBackend.figure_format = 'retina'
warnings.filterwarnings(module='sklearn*', action='ignore', category=DeprecationWarning)

导入数据

从data_all.csv文件中导入原始数据,并查看数据相关信息:

data_origin = pd.read_csv('data_all.csv')

划分数据集

首先将status列作为数据标签y,其余列作为数据集X:

y = data_origin.status
X = data_origin.drop(['status'], axis=1)

再调用sklearn包将此金融数据集按比例7:3划分为训练集和数据集,随机种子2018:

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=2018)

训练模型

构建并训练本次需要用到的七个模型,包含四个集成模型:XGBoost,LightGBM,GBDT,随机森林,和三个非集成模型:逻辑回归,SVM,决策树。所有模型暂时先使用默认参数。

# 逻辑回归
log_reg = LogisticRegression(random_state=2018).fit(X_train, y_train)
# SVM,注意Probability参数要设置为True,便于后续绘制ROC曲线
svc = SVC(random_state=2018, probability=True) .fit(X_train, y_train)
# 决策树
dt_clf = DecisionTreeClassifier(random_state=2018).fit(X_train, y_train)
# 随机森林
rf_clf = RandomForestClassifier(random_state=2018).fit(X_train, y_train)
# GBDT
gbdt = GradientBoostingClassifier(random_state=2018).fit(X_train, y_train)
# XGBoost
xgb = XGBClassifier(random_state=2018).fit(X_train, y_train)# LightGBM
lgbm = LGBMClassifier(random_state=2018).fit(X_train, y_train)

计算各指标值

首先定义两个字典,一个是要评估的七个模型,便于后续循环计算。另一个是数值型指标,用于最后整合结果。

models = {'随机森林': rf_clf,
          'GBDT': gbdt,
          'XGBoost': xgb,
          'LightGBM': lgbm,
          '逻辑回归': log_reg,
          'SVM': svc,
          '决策树': dt_clf}

assessments = {
    'Accuracy': [],
    'Precision': [],
    'Recall': [],
    'F1-score': [],
    'AUC': []
} 

准确度Accuracy

计算模型准确度并加入assessments中

for name, model in models.items():
    acc_test = accuracy_score(model.predict(X_test), y_test) * 100
    acc_train = accuracy_score(model.predict(X_train), y_train) * 100
    accuracy = '训练集:%.2f%%;测试集:%.2f%%' % (acc_train, acc_test)
    assessments['Accuracy'].append(accuracy)

混淆矩阵

混淆矩阵中的每一行表示一个实际的类, 而每一列表示一个预测的类。一个完美的分类器将只有真反例和真正例,所以混淆矩阵的左上到右下的对角线值越小越好。根据混淆矩阵定义,在二元分类任务中,根据scklearn文档,混淆矩阵的四个值的意义为:

True Negative(TN) False Positive(FP)
False Negative(FN) True Positive(TP)
  • True Positive(TP)表示被正确预测的正例个数

  • False Positive(FP)表示被错误预测的正例个数

  • False Negative(FN)表示被错误预测的反例个数

  • True Negative(TN)表示被正确预测的反例个数

此处仅使用七个模型对测试集进行混淆矩阵的计算,作为示例。

def plot_confusion_matrix(conf, classes, title, cmap=plt.cm.gray):
    plt.imshow(conf, interpolation='nearest', cmap=cmap)
    plt.title(title)
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes)
    plt.yticks(tick_marks, classes)
    plt.ylabel('真实标签')
    plt.xlabel('预测标签')
    plt.tight_layout()
fig = plt.figure(figsize=(12, 9))
i=1
classes=['未逾期', '逾期']
for name, model in models.items():
    conf = confusion_matrix(model.predict(X_test), y_test) * 100
    print('%s模型的混淆矩阵为\n%s' % (name, conf))
    subfig = plt.subplot(3,3,i)
    plot_confusion_matrix(conf, classes, name)
    plt.subplots_adjust(wspace =0, hspace =0.4)
    i += 1
随机森林模型的混淆矩阵为
[[100500  26400]
 [  6300   9500]]
GBDT模型的混淆矩阵为
[[98800 23300]
 [ 8000 12600]]
XGBoost模型的混淆矩阵为
[[99300 23100]
 [ 7500 12800]]
LightGBM模型的混淆矩阵为
[[97300 23300]
 [ 9500 12600]]
逻辑回归模型的混淆矩阵为
[[106800  35900]
 [     0      0]]
SVM模型的混淆矩阵为
[[106800  35900]
 [     0      0]]
决策树模型的混淆矩阵为
[[82900 21100]
 [23900 14800]]

在这里插入图片描述

精确率Precision

精确率的定义如下:
P r e c i s i o n = T P T P + F P Precision=\frac{TP}{TP+FP}
即在所有预测为正例的测试样本中,正确预测的比例。

for name, model in models.items():
    pre_test = precision_score(model.predict(X_test), y_test) * 100
    pre_train = precision_score(model.predict(X_train), y_train) * 100
    precision = '训练集:%.2f%%;测试集:%.2f%%' % (pre_train, pre_test)
    assessments['Precision'].append(precision)

召回率Recall

召回率定义如下:
R e c a l l = T P T P + F N Recall=\frac{TP}{TP+FN}
即在所有实际为正例的测试样本中,正确预测的比例。

for name, model in models.items():
    rec_test = recall_score(model.predict(X_test), y_test) * 100
    rec_train = recall_score(model.predict(X_train), y_train) * 100
    recall = '训练集:%.2f%%;测试集:%.2f%%' % (rec_train, rec_test)
    assessments['Recall'].append(recall)
UndefinedMetricWarning: Recall is ill-defined and being set to 0.0 due to no true samples.
  'recall', 'true', average, warn_for)

在模型预测的结果中,若不存在TP和FN样本,会导致Recall定义式的分母为0,即定义错误(ill-dedined)。sklearn会因此给出相关警告信息,并将Recall值设置为0。
返回之前的混淆矩阵计算结果可以分析出,警告是在计算SVM和逻辑回归的Recall值时产生的,因为它们的FN、TP值均为0。

F1值

F1值的定义如下:
F 1   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 F1\space Score=\frac{2\times precision\times recall}{precision + recall}
F1值是在认为召回率和精确率权重(重要性)相等的情况下,对两者的综合考虑。

for name, model in models.items():
    f1_test = f1_score(model.predict(X_test), y_test) * 100
    f1_train = f1_score(model.predict(X_train), y_train) * 100
    f1 = '训练集:%.2f%%;测试集:%.2f%%' % (f1_train, f1_test)
    assessments['F1-score'].append(f1)
UndefinedMetricWarning: F-score is ill-defined and being set to 0.0 due to no true samples.
  'recall', 'true', average, warn_for)

和之前Recall值的警告原因类似。在模型预测的结果中,若precision和recall值均为0,会导致F1定义式的分母为0,即定义错误(ill-dedined)。sklearn会因此给出相关警告信息,并将F1值设置为0。
从Recall和Precision计算结果(见总结指标部分)可以分析出,警告是同样是在计算SVM和逻辑回归的Recall值时产生的,因为它们的FN、TP值均为0。

ROC曲线

首先考虑两个指标True positive rate(TPR)和False positive rate(FPR)。TPR定义和召回率相同,而FPR定义如下:
F P R = F P F P + T N = 1 T P R FPR = \frac{FP}{FP+TN}=1-TPR
以FPR为x轴,TPR为y轴,就得到了ROC曲线。

# ROC曲线绘制函数
def plot_roc_curve(fpr, tpr, label=None):
    plt.plot(fpr, tpr, label=label)
    plt.plot([0, 1], [0, 1], 'k--')
    plt.axis([0, 1, 0, 1])
    plt.xlabel('False Positive Rate')
    plt.ylabel('True Positive Rate')
    plt.legend()
    plt.tight_layout()

单独计算每个模型训练集和测试集的ROC曲线:

for name, model in models.items():
    fig = plt.figure(figsize=(8, 6))
    proba = model.predict_proba(X_test)[:,1]
    fpr, tpr, thresholds = roc_curve(y_test, proba)
    plot_roc_curve(fpr, tpr, label='测试集')
    
    proba = model.predict_proba(X_train)[:,1]
    fpr, tpr, thresholds = roc_curve(y_train, proba)
    plot_roc_curve(fpr, tpr, label='训练集')
    plt.title(name)

七个模型对训练集的ROC曲线:

fig = plt.figure(figsize=(8, 6))
for name, model in models.items():
    proba = model.predict_proba(X_train)[:,1]
    fpr, tpr, thresholds = roc_curve(y_train, proba)
    plot_roc_curve(fpr, tpr, label=name)

七个模型对测试集的ROC曲线:

fig = plt.figure(figsize=(8, 6))
for name, model in models.items():
    proba = model.predict_proba(X_test)[:,1]
    fpr, tpr, thresholds = roc_curve(y_test, proba)
    plot_roc_curve(fpr, tpr, label=name)

这里省略结果,放在总结中。

AUC值

AUC值即为ROC曲线下的面积,AUC值越大,模型的区分能力就越强。

for name, model in models.items():
    auc_test = roc_auc_score(y_test, model.predict_proba(X_test)[:,1]) * 100
    auc_train = roc_auc_score(y_train, model.predict_proba(X_train)[:,1]) * 100
    auc = '训练集:%.2f%%;测试集:%.2f%%' % (auc_train, auc_test)
    assessments['AUC'].append(auc)

总结指标

数值型指标:

ass_df = pd.DataFrame(assessments, index=models.keys())
ass_df
AUC Accuracy F1-score Precision Recall
随机森林 训练集:99.95% 测试集:71.90% 训练集:98.47% 测试集:77.08% 训练集:96.85% 测试集:36.75% 训练集:93.88%: 测试集:26.46% 训练集:100.00% 测试集:60.13%
GBDT 训练集:92.07%: 测试集:76.38% 训练集:86.23%: 测试集:78.07% 训练集:65.41%: 测试集:44.60% 训练集:51.92%: 测试集:35.10% 训练集:88.37% 测试集:61.17%
XGBoost 训练集:91.84% 测试集:77.14% 训练集:85.24% 测试集:78.56% 训练集:62.08% 测试集:45.55% 训练集:48.20% 测试集:35.65% 训练集:87.20% 测试集:63.05%
LightGBM 训练集:100.00% 测试集:75.74% 训练集:99.73% 测试集:77.01% 训练集:99.46% 测试集:43.45% 训练集:98.92% 测试集:35.10% 训练集:100.00% 测试集:57.01%
逻辑回归 训练集:57.62% 测试集:56.75% 训练集:74.93% 测试集:74.84% 训练集:0.00% 测试集:0.00% 训练集:0.00% 测试集:0.00% 训练集:0.00% 测试集:0.00%
SVM 训练集:0.00% 测试集:50.00% 训练集:100.00% 测试集:74.84% 训练集:100.00% 测试集:0.00% 训练集:100.00% 测试集:0.00% 训练集:100.00% 测试集:0.00%
决策树 训练集:100.00% 测试集:59.42% 训练集:100.00% 测试集:68.47% 训练集:100.00% 测试集:39.68% 训练集:100.00% 测试集:41.23% 训练集:100.00% 测试集:38.24%
ROC曲线:
集成模型 非集成模型
在这里插入图片描述 在这里插入图片描述
在这里插入图片描述 在这里插入图片描述
在这里插入图片描述 在这里插入图片描述
在这里插入图片描述

综合比较ROC曲线:

训练集 测试集
在这里插入图片描述 在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/bear507/article/details/85922463
1.3