MNIST是最经常使用的用来实验分类模型的数据集,有7w多张手写0-9的白底黑字数字图像,每张图像大小 28*28,共784个像素,像素取值范围为[0-255],0表示白色背景,255表示纯黑,以下图:ide
数字识别是个多分类问题,首先咱们从两分类问题开始入手,即判断一张图片是5或者非5。应用sklearn线性模型的SGDClassifier直接训练,损失函数默认是 hinge loss,即SVM分类器,若是想用logistic regression来分类,能够选用 log loss。SGDClassifier 分类器还支持不一样的损失函数,如 perceptron等,这里就不一一列举了。因为SGD分类器对训练样本的顺序是敏感的,因此在模型训练以前须要shuffle训练集。函数
用SVM训练结束后,用模型预测获得测试集的预测结果,评估准确率(accuracy)大概是96%,看起来是一个不错的结果,可是若是咱们把全部的测试样本都断定为非5,准确率也能有90%(十分之九都是对的)。看来光凭准确率,在这种状况下不能说明咱们模型学习得很好,看来如何评价模型的学习能力不是件那么简单的事情。学习
“观察到的一个有意思的细节:一些喜爱机器学习或者数据科学的初学工程师和有机器学习或者数据科学背景的科学家,在工做上的主要区别在于如何对待负面的实验(包括线下和线上)结果。初学者每每就开始琢磨如何改模型,加Feature,调参数;思考如何从简单模型转换到复杂模型。有经验的人每每更加去了解实验的设置有没有问题;实验的Metrics的Comparison是到底怎么计算的;到真须要去思考模型的问题的时候,有经验的人每每会先反思训练数据的收集状况,测试数据和测试评测的真实度问题。初学者有点相似程咬金的三板斧,有那么几个技能,用完了,要是尚未效果,也就完了。而有经验的数据科学家,每每是从问题出发,去看是否是对问题本质的把握(好比优化的目标是否是对;有没有Counterfactual的状况)出现了误差,最后再讨论模型。”测试
—— by @洪亮劼
从源头出发,以下图,x、o分别表示label为负和正的样本,划分为上下两列,假设模型预测值是一个连续值(如为正的几率),把正负样本按照预测值从低到高分别排列好。一个好的模型,应该是左上角分布较密集,表示不少负样本预测值较小,右下角分布也很密集,表示为模型预测正样本的几率值广泛偏高。固然,通常模型也没法作到百分之百的分类准确,因此存在少许的负样本预测几率较高,正样本预测几率偏低,如图右上角和左下角。
咱们设定一个阈值,用图中蓝色的竖线表示,高于阈值的模型预测为正样本,反之则为负样本。这个阈值是咱们能够自行设定的,蓝色的竖线能够左右移动。红色的横线和蓝色的竖线将整个测试集数据分红四个部分,TN(True Positive)、FP(False Positive)、FN(False Negative)、TP(True Positive)。TPR(TP rate)即recall= TP/(TP+FN),precision=TP/(TP+FP)。上面咱们计算accuracy其实是 (TN+TP)/ALL,对于一个测试集来讲,底下分母是不变的,若是TN对比TP很大,TP的变更很难经过accuracy反映出来。一个好的分类器,应该TP包含大部分圆圈,FP和FN几乎为空,因此不少比赛的评测指标是precision和recall的harmonic平均值,即:
harmonic平均比直接除以2更看重较小的那个值,只有两个值都比较大,总体才会大。
为了获得较好的F1,须要调节适当的阈值。蓝色的线从最左往右滑动时,recall= TP/(TP+FN),分母不变,分子逐渐变小,从1单调递减到0。precision=TP/(TP+FP),分子和分母同时变小,整体上,TP变小的速度慢不少,大致上是递增的,可是并不绝对单调,尤为在靠近右侧。常常能够看到TP-1,FP不变,则precision反而变小:
关于Recall和Precision的tradeoff,还能够画一条PR 曲线:
ROC曲线是另一种衡量二分类模型的方法,y轴是recall=TP/(TP+FN),x轴是FPR=FP/(FP+TN):
PR曲线与ROC曲线的区别在于,PR曲线不关心TN(x、y计算公式都没有包含TN),因此在负样本比例很高的时候,PR曲线波动比ROC曲线明显,更能体现优化空间。另外,ROC曲线关心TN刚好也是它的优点,好比在推荐、搜索等learn to rank 任务中,咱们关心的是整个数据集的排序状况,TN也是须要考虑在内的,因此常常离线计算AUC(ROC曲线下方面积)来衡量rank model的优劣。
中场休息时间。。。喝口茶~ 欢迎关注公众号:kaggle实战,或博客:http://www.cnblogs.com/daniel-D/
多分类器是指能区别两个以上类别的分类器,好比手写数字识别这个数据集要区分0-9,像大型图像数据集可能有几万个类别。有些算法能够直接区分多类,如softmax、RF或者贝叶斯,有些算法没法直接区分,好比上面用到的线性分类器等二分类器。二分类器也能够组合造成多分类器,常见的策略有 One vs All和 One vs One。
在数字识别这个任务中,One vs All(OVA) 一共要训练10个分类器,分别是0 vs 非0,1 vs 非1……预测的时候,10个分类器依次输出为0,为1等的几率,可直接取最大几率做为预测值。One vs One则须要10*(10-1)/ 2个分类器,依次是 0 vs 1,0 vs 2……8 vs 9。OVO和OVA在实际使用很少,这里就不赘述了。
用RF模型训练后,在预测集上预测图像属于哪一个类别,因为模型不是百分百准确的,会有0断定成1或者1断定成2的状况,用rowIndex表示实际的label,colIndex表示预测的label,统计预测的label落到实际label的个数,能够获得如下矩阵:
可视化以后获得下图:
能够看到对角线方块很亮,说明全部类别基本断定准确。可是“5”方块较暗,多是因为5的图片数量较少,或者5的准确率偏低致使,要具体分析数据才能找到缘由。除了对角线方块,咱们还想分析其他方块的状况,能够把Confusion Matrix每一个元素处理该行的总和,对角线置0,获得下图:
能够看到3和五、7和9都容易混淆,想经过RF模型要提高效果的突破口可能就在这里。
实际上,3和五、7和9容易混淆的缘由在于,他们形态较为类似,直接用像素做为特征,相同的数字,在图像中旋转微小角度或者平移,都会致使像素空间的巨大变化,kaggle上高分kernel广泛都用神经网络里的CNN来提取特征,准确率能够轻松超过98%。预处理流程为:
而后定义一个最经常使用CNN网络结构和主要的超参数以下:
卷积参数:通常设置stride=1,卷积后保持原尺寸,用0填充,非线性变换采用relu;pooling大小2*2,stride=2,取maxPooling
网络结构:
因为MNIST数据集各种分布都比较均匀,用准确率就能较好评估模型了,比其余指标更加直白
详细代码能够参考这个kernel:https://www.kaggle.com/kakauandme/tensorflow-deep-nn
附:公众号
顺便测试下赞扬码