大师兄的Python机器学习笔记:实现评估模型

2020-05-15  本文已影响0人  superkmi

大师兄的Python机器学习笔记:数据重抽样
大师兄的Python机器学习笔记:Pandas库

一、混淆矩阵

1. 关于混淆矩阵(Confusion Matrix)
实际值/预测值 相关(Relevant),正类 无关(NonRelevant),负类
被检索到(Retrieved) 正类判断为正类(TP) 负类判断为正类(FP)
未被检索到(Not Retrieved) 正类判断为负类(FN) 负类判断为负类(TN)

例:二分类混淆矩阵

  • 比如有一群动物包含猫和狗,现在希望取出一只猫作为样本:
  • 如果将猫判断为猫,即为TP。
  • 如果将猫判断为非猫,即为FN。
  • 如果将狗判断为猫,即为FP。
  • 如果将狗判断为非猫,即为TN。
2. 混淆矩阵的特性
3. 案例及代码实现

例:多分类混淆矩阵

  • 比如有一群动物,包括20只猫、50只狗和30只兔子。
  • 现在挑选出60只猫,其中包括20只猫,还错把20只狗和20只兔子作为猫挑出来了。
实际/预测 兔子
20 0 0
20 30 0
兔子 20 0 10
>>>import numpy as np

>>>def base_data():
>>>    # 100只动物包含猫、狗和兔子
>>>    cats = np.asanyarray(['cat']*20)
>>>    dogs = np.asanyarray(['dog']*50)
>>>    rabbits = np.asanyarray(['rabbit']*30)
>>>    return np.concatenate((cats,dogs,rabbits))

>>>def actual_data(base_data):
>>>    # 随机抽取60只动物
>>>    return np.random.choice(base_data,60)

>>>def predicted_data(base_data):
>>>    # 预测挑出了60只猫
>>>    return np.random.choice(base_data,60)

>>>def confusion_maxtrix(actual_data,predicted_data):
>>>    # 生成一个混淆矩阵
>>>    unique_class_in_data = set(actual_data)
>>>    matrix = [list() for x in range(len(unique_class_in_data))]
>>>    for i in range(len(unique_class_in_data)):
>>>        matrix[i] = [0 for x in range(len(unique_class_in_data))]
>>>    indexing_our_class = dict()

>>>    # 贴标签
>>>    for i ,class_value in enumerate(unique_class_in_data):
>>>        indexing_our_class[class_value] = i

>>>    for i in range(len(actual_data)):
>>>        col=indexing_our_class[actual_data[i]]
>>>        row=indexing_our_class[predicted_data[i]]
>>>        matrix[row][col] +=1
>>>    return unique_class_in_data,matrix

>>>def pretty_confusion_matrix(unique_class_in_data,matrix):
>>>    # 输出到控制台
>>>    print('(A/P)' +' '.join(str(x) for x in unique_class_in_data))
>>>    for i,x in enumerate(unique_class_in_data):
>>>        print(f"{x} | {' '.join(str(x) for x in matrix[i])}")

>>>if __name__ == '__main__':
>>>    ad = actual_data(base_data())
>>>    pd = predicted_data(base_data())
>>>    index,matrix = confusion_maxtrix(ad,pd)
>>>    pretty_confusion_matrix(index,matrix)
(A/P)cat rabbit dog
cat | 1 4 9
rabbit | 5 5 14
dog | 7 3 12
>>>from sklearn.metrics import confusion_matrix
>>>import sklearn.metrics
>>>import itertools
>>>import matplotlib.pyplot as plt
>>>import numpy as np

>>>def base_data():
>>>    # 100只动物包含猫、狗和兔子
>>>    cats = np.asanyarray(['cat']*20)
>>>    dogs = np.asanyarray(['dog']*50)
>>>    rabbits = np.asanyarray(['rabbit']*30)
>>>    return np.concatenate((cats,dogs,rabbits))

>>>def actual_data(base_data):
>>>    # 随机抽取60只动物
>>>    return np.random.choice(base_data,60)

>>>def predicted_data(base_data):
>>>    # 预测挑出了60只猫
>>>    return np.random.choice(base_data,60)

>>>def confusion_maxtrix(actual_data,predicted_data):
>>>    # 生成一个混淆矩阵
>>>    return confusion_matrix(actual_data, predicted_data, labels=["cat", "dog", "rabbit"])

>>>def get_report(actual_data,predicted_data):
>>>    # 生成报告
>>>    return sklearn.metrics.classification_report(actual_data, predicted_data,target_names=["cat", "dog", "rabbit"])

>>>def pretty_confusion_matrix(confusion_box):
>>>    # 生成图片
>>>    classes = ['cat','dog','rabbit']
>>>    plt.imshow(confusion_box,interpolation='nearest',cmap=plt.cm.get_cmap('rainbow',1000))
>>>    plt.title('confusion matrix demo')
>>>    plt.colorbar()
>>>    tick_marks = np.arange(len(classes))
>>>    plt.xticks(tick_marks,classes,rotation=0)
>>>    plt.yticks(tick_marks,classes)

>>>    thresh = confusion_box.max()/2.
>>>    for i,j in >>>itertools.product(range(confusion_box.shape[0]),range(confusion_box.shape[1])):
>>>        plt.text(j,i,confusion_box[i,j],horizontalalignment="center", color="white" if confusion_box[i,j] > thresh else "black")
>>>    plt.tight_layout()
>>>    plt.ylabel("True value")
>>>    plt.xlabel("Predicted value")
>>>    plt.show()

>>>if __name__ == '__main__':
>>>    ad = actual_data(base_data())
>>>    pd = predicted_data(base_data())
>>>    matrix_box = confusion_maxtrix(ad,pd)
>>>    print(f"矩阵值:{'*'*20}\n", matrix_box)
>>>    print(f"矩阵属性:{'*'*20}\n",get_report(ad,pd))
>>>    pretty_confusion_matrix(matrix_box)
矩阵值:********************
 [[ 2  3  2]
 [ 7  9 11]
 [ 8 10  8]]
矩阵属性:********************
               precision    recall  f1-score   support

         cat       0.12      0.29      0.17         7
         dog       0.41      0.33      0.37        27
      rabbit       0.38      0.31      0.34        26

    accuracy                           0.32        60
   macro avg       0.30      0.31      0.29        60
weighted avg       0.36      0.32      0.33        60

二、准确度、精确度和召回率

1. 准确度(Accuracy)

例:

  • 比如有一群动物,包括20只猫、50只狗和30只兔子。
  • 现在挑选出60只猫,其中包括20只猫,还错把20只狗和20只兔子作为猫挑出来了。
  • 准确度 = (20 + (50-30) + (30-20) / 100 = 50%
2. 精确度(Precision)

例:

  • 比如有一群动物,包括20只猫、50只狗和30只兔子。
  • 现在挑选出60只猫,其中包括20只猫,还错把20只狗和20只兔子作为猫挑出来了。
  • 精确度 = 20 / 20+20+20 = 33%
3.召回率(Recall)

例:

  • 比如有一群动物,包括20只猫、50只狗和30只兔子。
  • 现在挑选出60只猫,其中包括20只猫,还错把20只狗和20只兔子作为猫挑出来了。
  • 召回率 = 20 / 20 = 100%
>>>import numpy as np
>>>from collections import Counter

>>>def base_data():
>>>    # 100只动物包含猫、狗和兔子
>>>    cats = np.asanyarray(['cat']*20)
>>>    dogs = np.asanyarray(['dog']*50)
>>>    rabbits = np.asanyarray(['rabbit']*30)
>>>    return np.concatenate((cats,dogs,rabbits))

>>>def actual_data(base_data):
>>>    # 随机抽取60只动物
>>>    return np.random.choice(base_data,60)

>>>def predicted_data():
>>>    # 预测挑出了60只猫
>>>    return np.asanyarray(['cat']*60)

>>>def calculate_the_accuracy_of_prediction(actual_data,predicted_data,base_data):
>>>    # 计算准确率
>>>    correct_num = 0
>>>    correct_left = (Counter(base_data).get('dog')- Counter(actual_data).get('dog'))+ (Counter(base_data).get('rabbit')- Counter(actual_data).get('rabbit')) # 计算没有被选入的狗和兔子
>>>    for i in range(len(actual_data)):
>>>        if actual_data[i]==predicted_data[i]:
>>>            correct_num +=1
>>>    return (correct_num+correct_left)/float(len(base_data))

>>>def calculate_the_precision_of_prediction(actual_data,predicted_data):
>>>    # 计算精确率
>>>    correct_num = 0
>>>    for i in range(len(actual_data)):
>>>        if actual_data[i]==predicted_data[i]:
>>>            correct_num +=1
>>>    return correct_num/float(len(actual_data))

>>>def calculate_the_recall_of_prediction(actual_data,predicted_data,base_data):
>>>    # 计算召回率
>>>    correct_num = 0
>>>    correct_not_retrieved = (Counter(base_data).get('cat')- Counter(actual_data).get('cat'))
>>>    for i in range(len(actual_data)):
>>>        if actual_data[i]==predicted_data[i]:
>>>            correct_num +=1
>>>    return correct_num/(correct_num+correct_not_retrieved)

>>>def show_data(ad,pd):
>>>    for a,p in zip(ad,pd):
>>>        print(f"实际值:{a},预测值:{p},结果:{a==p}")

>>>if __name__ == '__main__':
>>>    bd = base_data()
>>>    ad = actual_data(bd)
>>>    pd = predicted_data()
>>>    print(f"准确率为:{calculate_the_accuracy_of_prediction(ad,pd,bd)}")
>>>    print(f"精确率为:{calculate_the_precision_of_prediction(ad,pd)}")
>>>    print(f"召回率为:{calculate_the_recall_of_prediction(ad,pd,bd)}")
>>>    print(f'{"*"*20}')
>>>    show_data(ad,pd)
准确率为:0.4
精确率为:0.16666666666666666
召回率为:0.5
********************
实际值:dog,预测值:cat,结果:False
实际值:dog,预测值:cat,结果:False
实际值:rabbit,预测值:cat,结果:False
实际值:cat,预测值:cat,结果:True
... ...
上一篇下一篇

猜你喜欢

热点阅读