看到此篇文章内容干货较多,转载过来学习。
链接:https://www.52ml.net/20410.html
参考:https://blog.csdn.net/shenxiaoming77/article/details/72626218
https://blog.csdn.net/pacosonswjtu/article/details/56871762
一般情况来说,F1评分或者R平方(R-Squared value)等数值评分可以告诉我们训练的机器学习模型的好坏。也有其它许多度量方式来评估拟合模型。
你应该猜出来,我将提出使用可视化的方法结合数值评分来更直观的评判机器学习模型。接下来的几个部分将分享一些有用的工具。
首先想声明的,单单一个评分或者一条线,是无法完全评估一个机器学习模型。偏离真实场景来评估机器学习模型(’good’ or ‘bad’)都是“耍流氓”。某个机器学习模型若可“驾驭”小样本数据集生成最多预测模型(即,命中更多预测数据集)。如果一个拟合模型比其它拟合过的模型形式或者你昨天的预测模型能够得到更好的结果,那即是好(’good’)。
下面是一些标准指标: confusion_matrix,mean_squared_error, r2_score,这些可以用来评判分类器或者回归的好坏。表格中给出的是Scikit-Learn中的函数以及描述:
评估分类模型:
指标 | 描述 | Scikit-learn函数 |
Precision | 精准度 | from sklearn.metrics import precision_score |
Recall | 召回率 | from sklearn.metrics import recall_score |
F1 | F1值 | from sklearn.metrics import f1_score |
Confusion Matrix | 混淆矩阵 | from sklearn.metrics import confusion_matrix |
ROC | ROC曲线 | from sklearn.metrics import roc |
AUC | ROC曲线下的面积 | from sklearn.metrics import auc |
评估回归模型:
指标 | 描述 | Scikit-learn函数 |
Mean Square Error (MSE, RMSE) | 平均方差 | from sklearn.metrics import mean_squared_error |
Absolute Error (MAE, RAE) | 绝对误差 | from sklearn.metrics import mean_absolute_error, median_absolute_error |
R-Squared | R平方值 | from sklearn.metrics import r2_score |
下面开始使用Scikit-Learn的可视化工具来更直观的展现模型的好坏。
我们评估分类器是判断预测值时否很好的与实际标记值相匹配。正确的鉴别出正样本(True Positives)或者负样本(True Negatives)都是True。同理,错误的判断正样本(False Positive,即一类错误)或者负样本(False Negative,即二类错误)。
注意:True和False是对于评价预测结果而言,也就是评价预测结果是正确的(True)还是错误的(False)。而Positive和Negative则是样本分类的标记。
通常,我们希望通过一些参数来告知模型评估如何。为此,我们使用混淆矩阵。
幸运的是,Scikit-Learn提供内建函数(sklearn.metrics.confusion_matrix)来计算混淆矩阵。输入数据集实际值和模型预测值作为参数,输出即为混淆矩阵,结果类似这样:
[[1238 19] # True Positives = 1238, False Negatives = 19
[ 2 370]] # False Positives = 2, True Negatives = 370
分类报告除了包括混淆矩阵,也增加了其它优势,比如,混淆矩阵会标示样例是否被正确鉴别,同时也提供precision,recall和 F1 值三种评估指标。
from sklearn.metrics import classification_report
print(classification_report(y_true, y_pred, target_names=target_names))
…………
此处省略,可参见:https://blog.csdn.net/shenxiaoming77/article/details/72626218
…………
另一种评估分类模型的方法是ROC(Receiver Operating Characteristic)曲线。我们能从Scikit-Learn 指标模块中import roc_curve,计算 true positive率和false positive 率的数值。我们也可以画出ROC曲线来权衡模型的敏感性和特异性。
下面的代码将画出ROC,Y轴代表true positive率,X轴代表false positive 率。同时,我们也可以增加同时比较两种不同的拟合模型,这里看到的是 KNeighborsClassifier 分类器远胜 LinearSVC 分类器:
…………
此处省略,可参见上述地址
…………
在ROC空间,ROC曲线越凸向左上方向效果越好;越靠近对角线,分类器越趋向于随机分类器。
同时,我们也会计算曲线下的面积(AUC),可以结合上图。如果AUC的值达到0.80,那说明分类器分类非常准确;如果AUC值在0.60~0.80之间,那分类器还算好,但是我们调调参数可能会得到更好的性能;如果AUC值小于0.60,那就惨不忍睹了,你得好好分析下咯。
既然已经这么多评价标准,为什么还要使用ROC和AUC呢?因为ROC曲线有个很好的特性:当测试集中的正负样本的分布变化的时候,ROC曲线能够保持不变。在实际的数据集中经常会出现类不平衡(class imbalance)现象,即负样本比正样本多很多(或者相反),而且测试数据中的正负样本的分布也可能随着时间变化。下图是ROC曲线和Precision-Recall曲线的对比:
在上图中,(a)和(c)为ROC曲线,(b)和(d)为Precision-Recall曲线。(a)和(b)展示的是分类其在原始测试集(正负样本分布平衡)的结果,(c)和(d)是将测试集中负样本的数量增加到原来的10倍后,分类器的结果。可以明显的看出,ROC曲线基本保持原貌,而Precision-Recall曲线则变化较大。
参考链接:https://www.jianshu.com/p/c61ae11cc5f6
对于混凝土数据集试验一些不同的机器学习模型,然后评判哪种更好。在第二篇文章中,我们使用的平均方差和 R 平方值,比如:
Mean squared error = 116.268
R2 score = 0.606
这些数值是有用的,特别是对不同的拟合模型比较平均方差和 R 平方值。但是,这是不够的,它不能告诉我们为什么一个模型远胜于另外一个;也不能告诉我们如何对模型调参数提高评分。接下来,我们将看到两种可视化的评估技术来帮助诊断模型有效性:预测错误曲线 和 残差曲线。
…………
此处省略,可参见上述地址
…………
在文章开篇,我们提出了两个问题:我们如何知道一个机器学习模型可以工作?我们如何让这个模型工作(运行)的更好?
接下来,我们将回答第二个问题。如果你有注意,我们用的模型都是使用Scikit-Learn 默认的参数。对于我们的大部分拟合模型来讲,评分已经相当好了。但有时并没有那么幸运,这时我们就得自己调参数。
如何选择最好的模型参数呢?一种方法是,用单一参数的不同值去验证一个模型的评估分数。让我们拿SVC 分类器来试验,通过调不同的gama值来画出训练值和测试值的曲线。
我们的关注点是训练值和测试值都高的点。如果两者都低,那是欠拟合(underfit);如果训练值高但是测试值低,那说明是过拟合(overfit)。
下面的代码画出来的曲线是拿信用卡数据集来做例子,这里用的 6折交叉验证。
def plot_val_curve(features, labels, model):
p_range = np.logspace(-5, 5, 5)
train_scores, test_scores = validation_curve(
model, features, labels, param_name='gamma', param_range=p_range,
cv=6, scoring='accuracy', n_jobs=1
)
train_scores_mean = np.mean(train_scores, axis=1)
train_scores_std = np.std(train_scores, axis=1)
test_scores_mean = np.mean(test_scores, axis=1)
test_scores_std = np.std(test_scores, axis=1)
plt.title('Validation Curve')
plt.xlabel('$\gamma$')
plt.ylabel('Score')
plt.semilogx(p_range, train_scores_mean, label='Training score', color='#E29539')
plt.semilogx(p_range, test_scores_mean, label='Cross-validation score', color='#94BA65')
plt.legend(loc='best')
plt.show()
X = scale(credit[['limit','sex','edu','married','age','apr_delay']])
y = credit['default']
plot_val_curve(X, y, SVC())
对于超参数调优,大部分人使用的grid search。Grid search是一种暴力调参方法,即遍历所有可能的参数值。
对于信用卡数据集使用 SVC模型,我们通过试验不同内核系数gama来提高预测准确性:
from sklearn.grid_search import GridSearchCV
def blind_gridsearch(model, X, y):
C_range = np.logspace(-2, 10, 5)
gamma_range = np.logspace(-5, 5, 5)
param_grid = dict(gamma=gamma_range, C=C_range)
grid = GridSearchCV(SVC(), param_grid=param_grid)
grid.fit(X, y)
print(
'The best parameters are {} with a score of {:0.2f}.'.format(
grid.best_params_, grid.best_score_
)
)
features = credit[['limit','sex','edu','married','age','apr_delay']]
labels = credit['default']
blind_gridsearch(SVC(), features, labels)
但是,grid search需要我们理解哪些参数是合适的,参数的意义,参数是如何影响模型的以及参数的合理的搜索范围来初始化搜索。
这里,我们使用 visual_gridsearch 代替 blind_gridsearch 函数:
def visual_gridsearch(model, X, y):
C_range = np.logspace(-2, 10, 5)
gamma_range = np.logspace(-5, 5, 5)
param_grid = dict(gamma=gamma_range, C=C_range)
grid = GridSearchCV(SVC(), param_grid=param_grid)
grid.fit(X, y)
scores = [x[1] for x in grid.grid_scores_]
scores = np.array(scores).reshape(len(C_range), len(gamma_range))
plt.figure(figsize=(8, 6))
plt.subplots_adjust(left=.2, right=0.95, bottom=0.15, top=0.95)
plt.imshow(scores, interpolation='nearest', cmap=ddlheatmap)
plt.xlabel('gamma')
plt.ylabel('C')
plt.colorbar()
plt.xticks(np.arange(len(gamma_range)), gamma_range, rotation=45)
plt.yticks(np.arange(len(C_range)), C_range)
plt.title(
"The best parameters are {} with a score of {:0.2f}.".format(
grid.best_params_, grid.best_score_)
)
plt.show()
visual_gridsearch(SVC(), features, labels)
visual_gridsearch 的方法可以帮助我们理解不同的模型参数下的精确值。但是超参数调优的路程很长,好些人为此研究了几十年。
这是可视化机器学习部分的最后一篇,可视化在机器学习的过程占用重要的角色。许多工具都提供这个功能,比如, Scikit-Learn ,Matplotlib , Pandas ,Bokeh 和 Seaborn。