目录
第1关:为什么要有训练集与测试集
第2关:欠拟合与过拟合
第3关:偏差与方差
第4关:验证集与交叉验证
第5关:衡量回归的性能指标
第6关:准确度的陷阱与混淆矩阵
第7关:精准率与召回率
第8关:F1 Score
第9关:ROC曲线与AUC
第10关:sklearn中的分类性能指标
任务描述
本关任务:根据本节课所学知识完成本关所设置的选择题。
相关知识
为了完成本关任务,你需要掌握:1.为什么要有训练集与测试集,2.如何划分训练集与测试集。
为什么要有训练集与测试集
我们想要利用收集的西瓜数据构建一个机器学习模型,用来预测新的西瓜的好坏,但在将模型用于新的测量数据之前,我们需要知道模型是否有效,也就是说,我们是否应该相信它的预测结果。不幸的是,我们不能将用于构建模型的数据用于评估模型的性能。因为我们的模型会一直记住整个训练集,所以,对于训练集中的任何数据点总会预测成正确的标签。这种记忆无法告诉我们模型的泛化能力如何,即预测新样本的能力如何。我们要用新数据来评估模型的性能。新数据是指模型之前没见过的数据,而我们有这些新数据的标签。通常的做法是,我们把手头上的数据分为两部分,训练集与测试集。训练集用来构建机器学习模型,测试集用来评估模型性能。
如何划分训练集与测试集
通常我们将手头数据的百分之 70 或 80 用来训练数据,剩下的百分之 30 或 20 作为测试用来评估模型性能。值得注意的是,在划分数据集之前,我们要先把手头上的数据的顺序打乱,因为我们搜集数据时,数据可能是按照标签排放的。比如,现在有 100 个西瓜的数据,前 50 个是好瓜,后 50 个是坏瓜,如果将后面的 30 个西瓜数据当做测试集,这时测试集中只有坏瓜一个类别,这无法告诉我们模型的泛化能力如何,所以我们将数据打乱,确保测试集中包含所有类别的数据。
编程要求
根据相关知识,按照要求完成右侧选择题任务。
测试说明
平台会对你的代码进行运行测试,如果实际输出与预期输出相同,则算通关。
什么是欠拟合与欠拟合的原因
如上面例子,我们的数据是一份非线性数据,如果你想要用线性回归来拟合这份数据,由于数据是非线性的,模型是线性,则过于简单。所以,无论模型怎么训练,最终都不能很好的拟合数据。
什么是过拟合与过拟合的原因
如上面例子,在训练集上,模型为了拟合数据,添加了更多的多次项,使模型过于复杂,对噪音数据也能很好的拟合,所以在训练集上正确率很高,而在测试集上没有这些噪音数据,所以正确率很低。
在分类的问题中,如下例子:
欠拟合:由于模型过于简单,只学习到绿色这个特征,只要是绿色就都判断为树叶,结果将树当做了树叶。
过拟合:模型过于复杂,将锯齿这个普通特征,看的过于重要,认为必须有锯齿才是树叶,结果将树叶误判为不是树叶。
在上一部分,我们知道了欠拟合是模型在训练集上误差过高,过拟合模型是在训练集上误差低,在测试集上误差高。那么模型误差的来源是什么呢?
其实,模型在训练集上的误差来源主要来自于偏差,在测试集上误差来源主要来自于方差。
import numpy as np
def confusion_matrix(y_true, y_predict):
'''
构建二分类的混淆矩阵,并将其返回
:param y_true: 真实类别,类型为ndarray
:param y_predict: 预测类别,类型为ndarray
:return: shape为(2, 2)的ndarray
'''
#********* Begin *********#
def TN(y_true, y_predict):
return np.sum((y_true == 0) & (y_predict == 0))
def FP(y_true, y_predict):
return np.sum((y_true == 0) & (y_predict == 1))
def FN(y_true, y_predict):
return np.sum((y_true == 1) & (y_predict == 0))
def TP(y_true, y_predict):
return np.sum((y_true == 1) & (y_predict == 1))
return np.array([
[TN(y_true, y_predict), FP(y_true, y_predict)],
[FN(y_true, y_predict), TP(y_true, y_predict)]
])
#********* End *********#
import numpy as np
def precision_score(y_true, y_predict):
'''
计算精准率并返回
:param y_true: 真实类别,类型为ndarray
:param y_predict: 预测类别,类型为ndarray
:return: 精准率,类型为float
'''
#********* Begin *********#
def TP(y_true, y_predict):
return np.sum((y_true ==1)&(y_predict == 1))
def FP(y_true,y_predict):
return np.sum((y_true ==0)&(y_predict==1))
tp =TP(y_true, y_predict)
fp =FP(y_true, y_predict)
try:
return tp /(tp+fp)
except:
return 0.0
#********* End *********#
def recall_score(y_true, y_predict):
'''
计算召回率并召回
:param y_true: 真实类别,类型为ndarray
:param y_predict: 预测类别,类型为ndarray
:return: 召回率,类型为float
'''
#********* Begin *********#
def FN(y_true, y_predict):
return np.sum((y_true ==1)&(y_predict == 0))
def TP(y_true,y_predict):
return np.sum((y_true ==1)&(y_predict==1))
fn =FN(y_true, y_predict)
tp =TP(y_true, y_predict)
try:
return tp /(tp+fn)
except:
return 0.0
#********* End *********#
import numpy as np
def f1_score(precision, recall):
'''
计算f1 score并返回
:param precision: 模型的精准率,类型为float
:param recall: 模型的召回率,类型为float
:return: 模型的f1 score,类型为float
'''
#********* Begin *********#
try:
return 2*precision*recall / (precision+recall)
except:
return 0.0
#********* End ***********#
import numpy as np
def calAUC(prob, labels):
'''
计算AUC并返回
:param prob: 模型预测样本为Positive的概率列表,类型为ndarray
:param labels: 样本的真实类别列表,其中1表示Positive,0表示Negtive,类型为ndarray
:return: AUC,类型为float
'''
#********* Begin *********#
a = list(zip(prob,labels))
rank =[values2 for values1,values2 in sorted(a, key=lambda x:x[0])]
rankList=[i+1 for i in range(len(rank))if rank[i] ==1]
posNum =0
negNum =0
for i in range(len(labels)):
if(labels[i]==1):
posNum+=1
else:
negNum+=1
auc= (sum(rankList)-(posNum*(posNum+1))/2)/(posNum*negNum)
return auc
#********* End *********#
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score
def classification_performance(y_true, y_pred, y_prob):
'''
返回准确度、精准率、召回率、f1 Score和AUC
:param y_true:样本的真实类别,类型为`ndarray`
:param y_pred:模型预测出的类别,类型为`ndarray`
:param y_prob:模型预测样本为`Positive`的概率,类型为`ndarray`
:return:
'''
#********* Begin *********#
return accuracy_score(y_true, y_pred),precision_score(y_true, y_pred),recall_score(y_true, y_pred),f1_score(y_true, y_pred),roc_auc_score(y_true, y_prob)
#********* End *********#