性能评价

模型评估与参数调优实战:
通过对算法进行调优来构建性能良好的机器学习模型,并对模型的性能进行评估。

基于流水线的工作流:
在使用训练数据对模型进行拟合时就得到了一些参数,但将模型用于新数据时需重设这些参数。
scikit-learn中的Pipline类可以拟合出包含任意多个处理步骤的模型,并将模型用于新数据的预测。
无需在训练数据集和测试数据集上分别进行模型拟合、数据转换,而是通过流水线将StandardScaler、PCA,以及LogisticRegression对象串联起来
pipe_lr = Pipeline([('scl',StandardScaler()),("pca",PCA(n_components=2)),("clf",LogisticRegression(random_state=1))])
Pipeline对象采用元组的序列作为输入,其中每个元组中的第一个值为一个字符串,它可以是任意的标识符,我们通过它来访问流水线中的元素,
而元组的第二个值则为scikit-learn中的一个转换器或者评估器。

流水线中包含了scikit-learn中用于数据预处理的类,最后还包括一个评估器。
在前面的示例代码中,流水线中有两个预处理环节,分别是用于数据缩放和转换的StandardScaler及PCA,最后还有一个作为评估器的逻辑斯谛回归分类器。
当在流水线pipe_lr上执行fit方法时,StandardScaler会在训练数据上执行fit和transform操作,经过转换后的训练数据将传递给流水线上的下一个对象——PCA。
与前面的步骤类似,PCA会在前一步转换后的输入数据上执行fit和transform操作,并将处理过的数据传递给流水线中的最后一个对象——评估器。

使用k折交叉验证评估模型性能
如果一个模型过于简单,将会面临欠拟合(高偏差)的问题,而模型基于训练数据构造得过于复杂,则会导致过拟合(高方差)问题。
为了在偏差和方差之间找到可接受的折中方案,我们需要对模型进行评估。

holdout交叉验证(holdoutcross-validation)和k折交叉验证(k-fold cross-validation),
借助于这两种方法,我可以得到模型泛化误差的可靠估计,即模型在新数据上的性能表现。

holdout方法:
holdout交叉验证是评估机器学习模型泛化性能的一个经典且常用的方法。
通过holdout方法,我们将最初的数据集划分为训练数据集和测试数据集:前者用于模型的训练,而后者则用于性能的评估。
然而,在典型的机器学习应用中,为进一步提高模型在预测未知数据上的性能,我们还要对不同参数设置进行调优和比较。
该过程称为模型选择(model selection),指的是针对给定分类问题我们调整参数以寻求最优值(也称为超参,hyperparameter)的过程。

但是,如果我们在模型选择过程中不断重复使用相同的测试数据,它们可看作训练数据的一部分,模型更易于过拟合。
尽管存在此问题,许多人仍旧在模型选择过程中使用这些测试数据,这对机器学习来说不是一种好的做法。

使用holdout进行模型选择更好的方法是将数据划分为三个部分:训练数据集、验证数据集和测试数据集。
训练数据集用于不同模型的拟合,模型在验证数据集上的性能表现作为模型选择的标准。
使用模型训练及模型选择阶段不曾使用的数据作为测试数据集的优势在于:评估模型应用于新数据上能够获得较小偏差。

交叉验证中,在使用不同参数值对模型进行训练之后,我们使用验证数据集反复进行模型性能的评估。
一旦参数优化获得较为满意的结果,我们就可以在测试数据集上对模型的泛化误差进行评估

holdout方法的一个缺点在于:模型性能的评估对训练数据集划分为训练及验证子集的方法是敏感的;评价的结果会随样本的不同而发生变化。

k折交叉验证:
在k折交叉验证中,我们不重复地随机将训练数据集划分为k个,其中k-1个用于模型的训练,剩余的1个用于测试(k次holdout方法)。
重复此过程k次,我们就得到了k个模型及对模型性能的评价。

基于这些独立且不同的数据子集上得到的模型性能评价结果,我们可以计算出其平均性能,与holdout方法相比,这样得到的结果对数据划分方法的敏感性相对较低。
通常情况下,我们将k折交叉验证用于模型的调优,也就是找到使得模型泛化性能最优的超参值。
一旦找到了满意的超参值,我们就可以在全部的训练数据上重新训练模型,并使用独立的测试数据集对模型性能做出最终评价。

由于k折交叉验证使用了无重复抽样技术,该方法的优势在于(每次迭代过程中)每个样本点只有一次被划入训练数据集或测试数据集的机会,
与holdout方法相比,这将使得模型性能的评估具有较小的方差。

k折交叉验证中k的标准值为10,这对大多数应用来说都是合理的。但是,如果训练数据集相对较小,那就有必要加大k的值。
如果我们增大k的值,在每次迭代中将会有更多的数据用于模型的训练,这样通过计算各性能评估结果的平均值对模型的泛化性能进行评价时,可以得到较小的偏差。
但是,k值的增加将导致交叉验证算法运行时间延长,而且由于各训练块间高度相似,也会导致评价结果方差较高。

另一方面,如果数据集较大,则可以选择较小的k值,如k=5,这不光能够降低模型在不同数据块上进行重复拟合和性能评估的计算成本,
还可以在平均性能的基础上获得对模型的准确评估。

k折交叉验证的一个特例就是留一(leave-ont-out,LOO)交叉验证法。
在LOO中,我们将数据子集划分的数量等同于样本数(k=n),这样每次只有一个样本用于测试。当数据集非常小时,建议使用此方法进行验证。

分层k折交叉验证:对标准k折交叉验证做了稍许改进,它可以获得偏差和方差都较低的评估结果,特别是类别比例相差较大时。
在分层交叉验证中,类别比例在每个分块中得以保持,这使得每个分块中的类别比例与训练数据集的整体比例一致。

scikit-learn中的StratifiedKFold迭代器实现标准k折交叉验证:
kfold = StratifiedKFold(n_splits=10,random_state=1)
scores = []
for k,(train,test) in enumerate(kfold.split(X_train,y_train)):
# from sklearn.base import clone复制一份clf
pipe_lr.fit(X_train[train],y_train[train]) # 使用train中返回的索引去拟合本章开始时所构建的逻辑斯谛回归流水线
score = pipe_lr.score(X_train[test],y_train[test]) # 使用test索引计算模型的准确率
scores.append(score)
print("Fold:%s,Class dist.:%s,Acc:%.3f" %(k+1,np.bincount(y_train[train]),score))
使用分层k折交叉验证对模型进行评估
scores = cross_val_score(estimator=pipe_lr,X=X_train,y=y_train,cv=10,n_jobs=1)
# cv为折数
cross_val_score方法具备一个极为有用的特点,它可以将不同分块的性能评估分布到多个CPU上进行处理。
如果将n_jobs参数的值设为1,则与例子中使用的StratifiedKFold类似,只使用一个CPU对性能进行评估。
如果设定n_jobs=2,我们可以将10轮的交叉验证分布到两块CPU(如果使用的计算机支持)上进行,
如果设置n_jobs=-1,则可利用计算机所有的CPU并行地进行计算。

其他的交叉验证技术,如.632 Bootstrap交叉验证(.632 Bootstrapcross-validation)方法

通过学习及验证曲线来调试算法:
两个有助于提高学习算法性能的简单但功能强大的判定工具:学习曲线(learning curve)与验证曲线(validation curve)。
使用学习曲线判定偏差和方差问题:

使用学习曲线判定偏差和方差问题
如果一个模型在给定训练数据上构造得过于复杂——模型中有太多的自由度或者参数——这时模型可能对训练数据过拟合,而对未知数据泛化能力低下。
通常情况下,收集更多的训练样本有助于降低模型的过拟合程度。但是,在实践中,收集更多数据会带来高昂的成本,或者根本不可行。
通过将模型的训练及准确性验证看作是训练数据集大小的函数,并绘制其图像,我们可以很容易看出模型是面临高方差还是高偏差的问题,
以及收集更多的数据是否有助于解决问题。

画出模型在训练集上的表现,同时画出以训练集规模为自变量的训练集函数。为了得到图像,需要在训练集的不同规模子集上进行多次训练。
for m in range(1, len(X_train)):
model.fit(X_train[:m], y_train[:m])
y_train_predict = model.predict(X_train[:m])
y_val_predict = model.predict(X_val)
train_errors.append(mean_squared_error(y_train_predict, y_train[:m]))
# 如果你的模型在训练集上是欠拟合的,添加更多的样本是没用的。你需要使用一个更复杂的模型或者找到更好的特征。
# 改善模型过拟合的一种方法是提供更多的训练数据,直到训练误差和验证误差相等。

左上方图像显示的是一个高偏差模型。此模型的训练准确率和交叉验证准确率都很低,这表明此模型未能很好地拟合数据。
解决此问题的常用方法是增加模型中参数的数量,例如,收集或构建额外特征,或者降低类似于SVM和逻辑斯谛回归器等模型的正则化程度。

右上方图像中的模型面临高方差的问题,表明训练准确度与交叉验证准确度之间有很大差距。
针对此类过拟合问题,我们可以收集更多的训练数据或者降低模型的复杂度,如增加正则化的参数;

对于不适合正则化的模型,也可以通过第4章介绍的特征选择,或者第5章中的特征提取来降低特征的数量。
需要注意:收集更多的训练数据可以降低模型过拟合的概率。不过该方法并不适用于所有问题,
例如:训练数据中噪声数据较多,或者模型本身已经接近于最优。

使用scikit-learn中的学习曲线函数评估模型
train_sizes,train_scores,test_scores = learning_curve(estimator=pipe_lr,X=X_train,y=y_train,train_sizes=np.linspace(0.1,1.0,10),
cv=10,n_jobs=1)
通过learning_curve函数的train_size参数,我们可以控制用于生成学习曲线的样本的绝对或相对数量。
在此,通过设置train_sizes=np.linspace(0.1,1.0,10)来使用训练数据集上等距间隔的10个样本。
默认情况下,learning_curve函数使用分层k折交叉验证来计算交叉验证的准确性,通过cv参数将k的值设置为10。
然后,我们可以简单地通过不同规模训练集上返回的交叉验证和测试评分来计算平均准确率,并且,我们使用matplotlib的plot函数绘制出准确率图像。
此外,在绘制图像时,我们通过fill_between函数加入了平均准确率标准差的信息,用以表示评价结果的方差。

在训练准确率曲线与交叉验证准确率之间,存在着相对较小差距,这意味着模型对训练数据有轻微的过拟合。

在统计和机器学习领域有个重要的理论:一个模型的泛化误差由三个不同误差的和决定:
1.偏差:泛化误差的这部分误差是由于错误的假设决定的。例如实际是一个二次模型,你却假设了一个线性模型。一个高偏差的模型最容易出现欠拟合。
2.方差:这部分误差是由于模型对训练数据的微小变化较为敏感,一个多自由度的模型更容易有高的方差(例如一个高阶多项式模型),
因此会导致模型过拟合。
3.不可约误差:这部分误差是由于数据本身的噪声决定的。降低这部分误差的唯一方法就是进行数据清洗(例如:修复数据源,修复坏的传感器,
识别和剔除异常值)。

通过验证曲线来判定过拟合与欠拟合:
验证曲线是一种通过定位过拟合或欠拟合等诸多问题所在,来帮助提高模型性能的有效工具。
验证曲线与学习曲线相似,不过绘制的不是样本大小与训练准确率、测试准确率之间的函数关系,而是准确率与模型参数之间的关系,
例如,逻辑斯谛回归模型中的正则化参数C。

使用scikit-learn来绘制验证曲线:
train_scores,test_scores = validation_curve(estimator=pipe_lr,X=X_train,y=y_train,
param_name="clf__C",
param_range=param_range,
cv=10)
与learning_curve函数类似,如果我们使用的是分类算法,则validation_curve函数默认使用分层k折交叉验证来评价模型的性能。
在validation_curve函数内,我们可以指定想要验证的参数。
在本例中,需要验证的是参数C,即定义在scikit-learn流水线中的逻辑斯谛回归分类器的正则化参数,我们将其记为'clf_C',
并通过param_range参数来设定其值的范围。

虽然不同C值之间准确率的差异非常小,但我们可以看到,如果加大正则化强度(较小的C值),会导致模型轻微的欠拟合;
如果增加C的值,这意味着降低正则化的强度,因此模型会趋向于过拟合。

使用网格搜索调优机器学习模型
在机器学习中,有两类参数:通过训练数据学习得到的参数,如逻辑斯谛回归中的回归系数;以及学习算法中需要单独进行优化的参数。
后者即为调优参数,也称为超参,对模型来说,就如逻辑斯谛回归中的正则化系数,或者决策树中的深度参数。

本节中,我们将学习一种功能强大的超参数优化技巧:网格搜索(grid search),它通过寻找最优的超参值的组合以进一步提高模型的性能。

使用网络搜索调优超参:
结合网格搜索进行k折交叉验证,通过超参数值的改动对机器学习模型进行调优。
网格搜索法非常简单,它通过对我们指定的不同超参列表进行暴力穷举搜索,并计算评估每个组合对模型性能的影响,以获得参数的最优组合。
gs = GridSearchCV(estimator=pipe_svc,param_grid=param_grid,cv=10,n_jobs=-1)
gs.fit(X_train,y_train)

对线性SVM来说,我们只需调优正则化参数(C);对基于RBF的核SVM来说,我们同时需要调优C和gamma参数。请注意此处的gamma是针对核SVM特别定义的。

在训练数据集上完成网格搜索后,可以通过best_scroe_属性得到最优模型的性能评分,具体参数信息可通过best_params_属性得到。

最后,我们将使用独立的测试数据集,通过GridSearchCV对象的best_estimator_属性对最优模型进行性能评估:
clf = gs.best_estimator_
clf.fit(X_train,y_train)
虽然网格搜索是寻找最优参数集合的一种功能强大的方法,但评估所有参数组合的计算成本也是相当昂贵的。
使用scikit-learn抽取不同参数组合的另一种方法就是随机搜索(randomized search)。
借助于scikit-learn中的RandomizedSearchCV类,我们可以以特定的代价从抽样分布中抽取出随机的参数组合。

通过嵌套交叉验证选择算法:
如果要在不同机器学习算法中做出选择,则推荐另外一种方法——嵌套交叉验证
在一项对误差估计的偏差情形研究中,Varma和Simon给出了如下结论:使用嵌套交叉验证,估计的真实误差与在测试集上得到的结果几乎没有差距。

在嵌套交叉验证的外围循环中,我们将数据划分为训练块及测试块;而在用于模型选择的内部循环中,我们则基于这些训练块使用k折交叉验证。
在完成模型的选择后,测试块用于模型性能的评估。
下图通过5个外围模块及2个内部模块解释了嵌套交叉验证的概念,这适用于计算性能要求比较高的大规模数据集。
这种特殊类型的嵌套交叉验证也称为5×2交叉验证(5×2 cross-validation):

借助于scikit-learn,我们可以通过如下方式使用嵌套交叉验证:
gs = GridSearchCV(estimator=pipe_svc,param_grid=param_grid,cv=10,n_jobs=-1,scoring="accuracy")
scores = cross_val_score(gs,X,y,scoring="accuracy",cv=5)
代码返回的交叉验证准确率平均值对模型超参调优的预期值给出了很好的估计,且使用该值优化过的模型能够预测未知数据。

可以使用嵌套交叉验证方法比较SVM模型与简单的决策树分类器;为了简单起见,我们只调优树的深度参数:
嵌套交叉验证对SVM模型性能的评分(97.8%)远高于决策树的(90.8%)。由此,可以预期:SVM是用于对此数据集未知数据进行分类的一个好的选择。

不同的性能评价指标
使用模型准确性对模型进行了评估,这是通常情况下有效量化模型性能的一个指标。
不过还有其他几个性能指标可以用来衡量模型的相关性能,比如准确率(precision)、召回率(recall)以及F1分数(F1-score)。

读取混淆矩阵
混淆矩阵(confusion matrix):即展示学习算法性能的一种矩阵。
混淆矩阵是一个简单的方阵,用于展示一个分类器预测结果——
· 真正(true positive)、真负(false negative)、假正(false positive)及假负(false negative)——的数量

虽然这指标的数据可以通过人工比较真实类标与预测类标来获得,不过scikit-learn提供了一个方便使用的confusion_matrix函数,其使用方法如下:
pipe_svc = Pipeline([('scl',StandardScaler()),("clf",SVC(random_state=1))])
pipe_svc.fit(X_train,y_train)
y_pred = pipe_svc.predict(X_test)
confmat = confusion_matrix(y_true=y_test,y_pred=y_pred)
# predict得到的是没有交叉验证的预测类标
# 交叉验证的预测结果可以通过以下得到
from sklearn.model_selection import cross_val_predict
y_train_pred = cross_val_predict(sgd_clf,X_train,y_train_9,cv=3) # cross_val_score得到的是各次k折的预测精度
# cross_val_predict(sgd_clf,X_train,y_train_9,cv=3,method='decision_function')得到分数值
在执行上述代码后,返回的数组提供了分类器在测试数据集上生成的不同错误信息,我们可以使用matplotlib中的matshow函数将它们表示为
上图所示的混淆矩阵形式:
fig,ax = plt.subplots(figsize=(2.5,2.5))
ax.matshow(confmat,cmap=plt.cm.Blues,alpha=0.3) # 可以扩展到多类别,行表示真实类标,列表示预测类标
for i in range(confmat.shape[0]):
for j in range(confmat.shape[1]):
ax.text(x=j,y=i,s=confmat[i,j],va='center',ha='center')

在本例中,假定类别1(恶性)为正类,模型正确地预测了71个属于类别0的样本(真负),以及40个属于类别1的样本(真正)。
不过,我们的模型也错误地将两个属于类别0的样本划分到了类别1(假负),另外还将一个恶性肿瘤误判为良性的(假正)。

让我们关注仅包含误差数据的图像呈现。首先你需要将混淆矩阵的每一个值除以相应类别的图片的总数目。
这样子,你可以比较错误率,而不是绝对的错误数(这对大的类别不公平)。
row_sums = conf_mx.sum(axis=1, keepdims=True)
norm_conf_mx = conf_mx / row_sums

现在让我们用 0 来填充对角线。这样子就只保留了被错误分类的数据。让我们画出这个结果。
np.fill_diagonal(norm_conf_mx, 0)
分析混淆矩阵通常可以给你提供深刻的见解去改善你的分类器。回顾这幅图,看样子你应该努力改善分类器在数字 8 和数字 9 上的表现,
和纠正 3/5 的混淆。举例子,你可以尝试去收集更多的数据,或者你可以构造新的、有助于分类器的特征。
举例子,写一个算法去数闭合的环(比如,数字 8 有两个环,数字 6 有一个, 5 没有)。
又或者你可以预处理图片(比如,使用 Scikit-Learn,Pillow, OpenCV)去构造一个模式,比如闭合的环。

分析独特的误差,是获得关于你的分类器是如何工作及其为什么失败的洞见的一个好途径。但是这相对难和耗时。

优化分类模型的准确率和召回率:
预测误差(error,ERR)和准确率(accuracy,ACC)都提供了误分类样本数量的相关信息。
误差可以理解为预测错误样本的数量与所有被预测样本数量的比值,而准确率计算方法则是正确预测样本的数量与所有被预测样本数量的比值:
ERR = (FP+FN)/(FP+FN+TP+TN)
ACC = (TP+TN)/(FP+FN+TP+TN) = 1-ERR

对于类别数量不均衡的分类问题来说,真正率(TPR)与假正率(FPR)是非常有用的性能指标:
FPR = FP / N = FP / (FP+TN)
TPR = TP / P = TP / (TP+FN)
以肿瘤诊断为例,我们更为关注的是正确检测出恶性肿瘤,使得病人得到恰当治疗。
然而,降低良性肿瘤(假正)错误地划分为恶性肿瘤事例的数量固然重要,但对患者来说影响并不大。
与FPR相反,真正率提供了有关正确识别出来的恶性肿瘤样本(或相关样本)的有用信息。

准确率(precision,PRE)和召回率(recall,REC)是与真正率、真负率相关的性能评价指标,实际上,召回率与真正率含义相同:
PRE = TP / TP + FP
REC = TPR = TP / P = TP / (TP+FN)

在实践中,常采用准确率与召回率的组合,称为F1分数:
F1 = 2* (PRE*REC)/(PRE+REC) # 有的场景你会绝大程度地关心准确率,而另外一些场景你会更关心召回率。如儿童观看视频分类器,更关心准确率
# 增加准确率会降低召回率,反之亦然。这叫做准确率与召回率之间的折衷。
所有这些评分指标均以在scikit-learn中实现,可以从sklearn.metric模块中导入使用,示例代码如下:
print(precision_score(y_true=y_test,y_pred=y_pred))
print(recall_score(y_true=y_test,y_pred=y_pred))
print(f1_score(y_true=y_test,y_pred=y_pred))

此外,通过评分参数,我们还可以在GridSerch中使用包括准确率在内的其他多种不同评分标准。

请记住scikit-learn中将正类类标标识为1。如果我们想指定一个不同的正类类标,可通过make_scorer函数来构建我们自己的评分,
那样我们就可以将其以参数的形式提供给GridSearchCV:

准确率/召回率之间的折衷:
Scikit-Learn 不让你直接设置阈值,但是它给你提供了设置决策分数的方法,这个决策分数可以用来产生预测。
它不是调用分类器的 predict() 方法,而是调用 decision_function() 方法。
这个方法返回每一个样例的分数值,而不是类标,然后基于这个分数值,使用你想要的任何阈值做出预测。
y_scores = sgd_clf.decision_function([some_digit])
或交叉验证:
y_scores = cross_val_predict(sgd_clf,X_train,y_train_9,cv=3,method='decision_function')
得到分数值后,使用 precision_recall_curve() ,你都可以计算准确率和召回率:
precisions,recalls,thresholds = precision_recall_curve(y_train_9,y_scores)

另一个选出好的准确率/召回率折衷的方法是直接画出准确率对召回率的曲线。

绘制ROC曲线:
受试者工作特征曲线(receiver operator characteristic,ROC)是基于模型假正率和真正率等性能指标进行分类模型选择的有用工具,
假正率和真正率可以通过移动分类器的分类阈值来计算。
ROC的对角线可以理解为随机猜测,如果分类器性能曲线在对角线以下,那么其性能就比随机猜测还差。
对于完美的分类器来说,其真正率为1,假正率为0,这时的ROC曲线即为横轴0与纵轴1组成的折线。
基于ROC曲线,我们就可以计算所谓的ROC线下区域(area under the curve,AUC),用来刻画分类模型的性能。
from sklearn.metrics import roc_curve,auc
probas = pipe_lr.fit(X_train2[train],y_train[train]).predict_proba(X_train2[test])
fpr,tpr,thresholds = roc_curve(y_train[test],probas[:,1],pos_label=1) # 使用正例概率probas[:,1],或者上面的分数值
roc_auc = auc(fpr,tpr)

与ROC曲线类似,我们也可以计算不同概率阈值下一个分类器的准确率-召回率曲线。绘制此准确率-召回率曲线的方法也在scikit-learn中得以实现。
from sklearn.metrics import precision_recall_curve

如果我们仅对ROC AUC的得分感兴趣,也可以直接从sklearn.metircs子模块中导入roc_auc_score函数。
pipe_svc = Pipeline([('scl',StandardScaler()),("clf",SVC(random_state=1))])
pipe_svc.fit(X_train2,y_train)
y_pred2 = pipe_svc.predict(X_test[:,[4,14]])
print(roc_auc_score(y_true=y_test,y_score=y_pred2))
print(accuracy_score(y_true=y_test,y_pred=y_pred2))

通过ROC AUC得到的分类器性能可以让我们进一步洞悉分类器在类别不均衡样本集合上的性能。
然而,既然准确率评分可以解释为ROC曲线上某个单点处的值,A.P.Bradley认为ROC AUC与准确率矩阵之间是相互一致的。

一个笨拙的规则是,优先使用 PR 曲线当正例很少,或者当你关注假正例多于假反例的时候。其他情况使用 ROC 曲线。
如正类标很少的情况下,ROC 曲线和 ROC AUC 数值会很好,但PR 曲线清楚显示出这个分类器还有很大的改善空间(PR 曲线应该尽可能地靠近右上角)。

多类别分类的评价标准:
本节中讨论的评分标准都是基于二类别分类系统的。不过,scikit-learn实现了macro(宏)及micro(微)均值方法,
旨在通过一对多(One vs All,OvA)的方式将评分标准扩展到了多类别分类问题。微均值是通过系统的真正、真负、假正,以及假负来计算的。
例如,k类分类系统的准确率评分的微均值可按如下公式进行计算:
PRE_micro = (TP_1+...+TP_k)/(TP_1+...+TP_k+FP_1+...+FP_k)
宏均值仅计算不同系统的平均分值:
PRE_macro = (PRE_1+ ... + PRE_k)/k

当我们等同看待每个实例或每次预测时,微均值是有用的,而宏均值则是我们等同看待各个类别,
将其用于评估分类器针对最频繁类标(即样本数量最多的类)的整体性能。

如果我们使用别二类别分类性能指标来衡量scikit-learn中的多类别分类模型,会默认使用一个归一化项或者是宏均值的一个加权变种。
计算加权宏均值时,各类别以类内实例的数量作为评分的权值。当数据中类中样本分布不均衡时,也就是类标数量不一致时,采用加权宏均值比较有效。

由于加权宏均值是scikit-learn中多类别问题的默认值,我们可以通过sklearn.metrics模块导入其他不同的评分函数,如precision_score或make_scorer函数等,
并利用函数内置的avarage参数定义平均方法:
pre_scorer = make_scorer(score_func=precision_score,pos_label=1,greater_is_better=True,average="micro")

猜你喜欢

转载自www.cnblogs.com/czlong/p/11701467.html
今日推荐