大师兄的数据分析学习笔记(三十二):模型评估(一)

大师兄的数据分析学习笔记(三十一):机器学习模型总结
大师兄的数据分析学习笔记(三十三):模型评估(二)

一、分类模型评估

1. 二分类
  • 二分类就是标注分类时有两类的分类,在数据挖掘中是常见的类型。
  • 通常会将二分类中更被关注的类定义成正类,用数字1来表示。
  • 另一个类定义成负类,用数字0表示。
  • Y\_test:[0,1,0,0,......0,1]
  • Y\_pred:[0,1,0,0,......0,1]
  • 有时0和1不是直接得到的,而是经过模型输出后被划分为正类的概率:
  • Y\_pred:[0.5,0.6,0.1,0.8......0.4,0.5]
  • 这时需要确定一个阈值(比如0.5),大于阈值为1,否则为0。
2. 混淆矩阵
  • 如果把测试集的真实分类和经过模型预测后最终的判别结果进行整理,会得到四种映射关系:
名称 实际值 预测值
TP(True Positive)
FN(False Negative),漏分类
FP(False Positive),假正类
TN(True Negative)
  • 如果把上图中各类映射的数量数出来,并整理成为一个矩阵的形式,就是混淆矩阵
/ 0 1
0 Y_00 Y_01
1 Y_10 Y_11
  • 矩阵中的每一行代表一个真实的分类
  • 矩阵中的每一列代表一个预测的分类
  • 如果把四个映射找到混淆矩阵中的位置,则如图:
/ 0 1
0 TN FP
1 FN TP
  • 可以看出,对角线上的分类属于正确分类。
  • 不在对角线上的分类数据错误分类。
  • 所以理想的模型应该是一个对角阵,如果得不到对角阵,对角线上的数字加和占统治地位也是可以的。
3. 关键指标
  • 可以通过混淆矩阵获得关键指标
  • 正确率(Accuracy Rate)\frac{TP+TN}{TP+TN+FN+FP}
  • 召回率(Recall,True Positive Rate)\frac{TP}{TP+FN}
  • F-measure(正确率和召回率的权衡值)\frac{2{\times}Recall{\times}Accuracy}{Recall+Accuracy}
  • 准确率(Precision)\frac{TP}{TP+FP}
  • 错误接收率(FPR)\frac{FP}{FP+TN}
  • 错误拒绝率(FRR)\frac{FN}{TP+FN}
4. 多元混淆矩阵
  • 二分类不同,多分类中的每个类都是被关注的。
  • 多分类也可以制作成混淆矩阵,同样对角线上的值表示正确值。
/ 0 1 2
0 Y_00 Y_01 Y_02
1 Y_10 Y_11 Y_12
2 Y_20 Y_21 Y_22
  • 准确率:和二分类保持一致。
  • 召回率/F-measure
  1. 先计算所有的TP、FN等,再以二分类方法计算。
  2. 分别把每个类当做正类,都算一个召回率/F-measure,然后取加权或者不加权的平均值。
  • 如果值是模型输出后被划分的概率,可以使用ROCAUC
4.1 ROC
  • ROC(Receiver Operating characteristic Curve)可以很容易查出任意界限值时的对性能的识别能力 。
  • 首先将模型输出的预测结果得分从大到小进行排列:


  • 将不同阈值得出的关键指标结果画到坐标系上,连成一条线:
4.2 AUC
  • AUC(Area Under Curve)被定义为ROC下与坐标轴围成的面积。
  • 由于ROC一般都处于y=x直线的上方,所以AUC的取值范围在0.5和1之间。
  • AUC越接近1.0,检测方法真实性越高;等于0.5时,则真实性最低,无应用价值。
4.3 增益图
  • 增益图可以在宏观上反应分类器的分类效果。
4.4 KS图
  • KS图可以通过TPRFPR的差距,反映出对正类样本分类的区分度。
5. 代码实现
>>>import os
>>>import numpy as np
>>>import pandas as pd
>>>import tensorflow as tf
>>>import matplotlib.pyplot as plt
>>>from sklearn.model_selection import train_test_split
>>>from sklearn.metrics import roc_curve,auc,roc_auc_score
>>>from sklearn.preprocessing import StandardScaler
>>>from keras.models import Sequential
>>>from keras.layers.core import Dense,Activation

>>>df = pd.read_csv(os.path.join(".", "data", "WA_Fn-UseC_-HR-Employee-Attrition.csv"))

>>>X_tt,X_validation,Y_tt,Y_validation = train_test_split(df.JobLevel,df.JobSatisfaction,test_size=0.2)
>>>StandardScaler().fit_transform(np.array(X_tt).reshape(-1,1))
>>>X_train,X_test,Y_train,Y_test = train_test_split(X_tt,Y_tt,test_size=0.25)

>>>mdl = Sequential()
>>>mdl.add(Dense(50))
>>>mdl.add(Activation("sigmoid"))
>>>mdl.add(Dense(2))
>>>mdl.add(Activation("softmax"))
>>>mdl.compile(loss="mean_squared_error",optimizer=tf.keras.optimizers.SGD(lr=0.05))
>>>mdl.fit(X_train,np.array([[0,1] if i==1 else [1,0] for i in Y_train]),epochs=50,batch_size=800)

>>>f = plt.figure()

>>>xy_lst = [(X_train,Y_train),(X_validation,Y_validation),(X_test,Y_test)]
>>>for i in range(len(xy_lst)):
>>>    X_part = xy_lst[i][0]
>>>    Y_part = [0 if x<=1 else 1 for x in xy_lst[i][1]]

>>>    Y_pred = mdl.predict(X_part)
>>>    Y_pred = np.array(Y_pred[:,1]).reshape((1,-1))[0]
>>>    f.add_subplot(1,3,i+1)
>>>    fpr,tpr,threshold = roc_curve(Y_part,Y_pred)
>>>    plt.plot(fpr,tpr)
>>>    print("NN","AUC",auc(fpr,tpr))
>>>    print("NN","AUC_Score",roc_auc_score(Y_part,Y_pred))
>>>    print("="*40)
>>>plt.show()
Epoch 1/50
2/2 [==============================] - 0s 1ms/step - loss: 0.2929
Epoch 2/50
2/2 [==============================] - 0s 1ms/step - loss: 0.2168
Epoch 3/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1858
Epoch 4/50
2/2 [==============================] - 0s 1ms/step - loss: 0.1738
Epoch 5/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1673
Epoch 6/50
2/2 [==============================] - 0s 0s/step - loss: 0.1638
Epoch 7/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1623
Epoch 8/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1616
Epoch 9/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1613
Epoch 10/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1606
Epoch 11/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1602
Epoch 12/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1599
Epoch 13/50
2/2 [==============================] - 0s 1ms/step - loss: 0.1598
Epoch 14/50
2/2 [==============================] - 0s 0s/step - loss: 0.1596
Epoch 15/50
2/2 [==============================] - 0s 1ms/step - loss: 0.1596
Epoch 16/50
2/2 [==============================] - 0s 0s/step - loss: 0.1596
Epoch 17/50
2/2 [==============================] - 0s 1ms/step - loss: 0.1596
Epoch 18/50
2/2 [==============================] - 0s 0s/step - loss: 0.1596
Epoch 19/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1596
Epoch 20/50
2/2 [==============================] - 0s 0s/step - loss: 0.1596
Epoch 21/50
2/2 [==============================] - 0s 0s/step - loss: 0.1596
Epoch 22/50
2/2 [==============================] - 0s 1ms/step - loss: 0.1595
Epoch 23/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1596
Epoch 24/50
2/2 [==============================] - 0s 0s/step - loss: 0.1596
Epoch 25/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1596
Epoch 26/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1595
Epoch 27/50
2/2 [==============================] - 0s 0s/step - loss: 0.1595
Epoch 28/50
2/2 [==============================] - 0s 1ms/step - loss: 0.1595
Epoch 29/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1595
Epoch 30/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1596
Epoch 31/50
2/2 [==============================] - 0s 0s/step - loss: 0.1596
Epoch 32/50
2/2 [==============================] - 0s 0s/step - loss: 0.1596
Epoch 33/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1596
Epoch 34/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1595
Epoch 35/50
2/2 [==============================] - 0s 0s/step - loss: 0.1595
Epoch 36/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1595
Epoch 37/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1596
Epoch 38/50
2/2 [==============================] - 0s 0s/step - loss: 0.1596
Epoch 39/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1596
Epoch 40/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1595
Epoch 41/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1596
Epoch 42/50
2/2 [==============================] - 0s 1ms/step - loss: 0.1595
Epoch 43/50
2/2 [==============================] - 0s 1ms/step - loss: 0.1596
Epoch 44/50
2/2 [==============================] - 0s 0s/step - loss: 0.1597
Epoch 45/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1596
Epoch 46/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1596
Epoch 47/50
2/2 [==============================] - 0s 1ms/step - loss: 0.1596
Epoch 48/50
2/2 [==============================] - 0s 0s/step - loss: 0.1595
Epoch 49/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1596
Epoch 50/50
2/2 [==============================] - 0s 1000us/step - loss: 0.1595
28/28 [==============================] - 0s 444us/step
NN AUC 0.4800573010558846
NN AUC_Score 0.4800573010558846
========================================
10/10 [==============================] - 0s 556us/step
NN AUC 0.5361630625365283
NN AUC_Score 0.5361630625365283
========================================
10/10 [==============================] - 0s 667us/step
NN AUC 0.5459870673259795
NN AUC_Score 0.5459870673259795
========================================
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,924评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,781评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,813评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,264评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,273评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,383评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,800评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,482评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,673评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,497评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,545评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,240评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,802评论 3 304
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,866评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,101评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,673评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,245评论 2 341

推荐阅读更多精彩内容