对模型的评价是在test set上进行的,本文首先介绍测试集应该知足的特征,而后介绍四种评价方法。python
1、测试集的选择app
一、首先,测试集必须是严格独立于训练集的,不然评价结果必定很高,可是虚高,不适用于新案例。dom
二、若是分类的类别比较少,好比只有两个,并且每类的样本数大体相等,那100个样本大小的测试集也是够用的;但若是类别数比较多,且分布十分不均,那测试集的大小要保证最稀少的种类的样本数很多于50;此外,若是测试集的样本相互之间比较类似,就要适当的扩大测试集来弥补多样性的缺少对评价的影响。当样本数比较大时,一般的作法是取整个数据集的10%做为测试集。测试
三、测试集和训练集样本之间的类似度问题。类似度越高,评价的可信度就越低。举一个错误的例子:随机地分配来自同一个题材多篇文章的句子来组建测试集和训练集。代码以下:spa
>>> import random >>> from nltk.corpus import brown >>> tagged_sents = list(brown.tagged_sents(categories='news')) >>> random.shuffle(tagged_sents) >>> size = int(len(tagged_sents) * 0.1) >>> train_set, test_set = tagged_sents[size:], tagged_sents[:size]
这是很是愚蠢的作法,由于不一样的文章,做者不一样,句子的特征就会不一样,来自不一样文章的句子能够认为具备不一样的特征,这对于模型测试是有利的。可是使用random.shuffle()将所用句子的顺序打乱,来自同一篇文章的句子就同时分布在测试集和训练集中,二者的类似度更高了,使原有的优点消失。一个改进的作法是保证测试集和训练集来自不一样的文章,以下:code
>>> file_ids = brown.fileids(categories='news') >>> size = int(len(file_ids) * 0.1) >>> train_set = brown.tagged_sents(file_ids[size:]) >>> test_set = brown.tagged_sents(file_ids[:size])
若是想进一步改进,则可使测试集和训练集来自不一样的题材:orm
>>> train_set = brown.tagged_sents(categories='news') >>> test_set = brown.tagged_sents(categories='fiction')
2、评价方法/指标blog
一、accuracyci
这是最经常使用的指标,就是用测试集中分类器正确分类的样本数除以测试集的总样本数。用nltk.classify.accuracy(classifier,test_set)方法能够获得,其中test_set是测试集,classifier是分类器。文档
使用这个指标时必定要考虑测试集中样本的频率分布。缘由在percision&recall中会解释
二、precision&recall
在搜索任务中accuracy一般不适用。好比在文献检索(information retrieval)中不相关的文档远远多于相关的文档,这样若是分类器将全部文档都标记为不相关,那它的准确率也将近100%。
为了构建适用于搜索任务的指标,咱们先来定义几个概念:
Ture positive:TP,相关的被标记为相关
Ture negative:TN,不相关的被标记为不相关
False positive:FP,不相关的错标记为相关(第一类错误)
False negative:FN,相关的被错标为不想关(第二类错误)
而后基于以上概念,就能够构建一下指标:
precision=TP/(TP+FP)
recall=TP/(TP+NF)
F-Measure=(2*precision*recall)/(precision+recall)
三、confusion matrices(混淆矩阵)
混淆矩阵的意思是,其中的元素[i,j]表示当正确的分类是i时,样本被分红j类的比例(相对于总样本数),即对角线上为正确分类的比例。代码以下:
>>> def tag_list(tagged_sents): ... return [tag for sent in tagged_sents for (word, tag) in sent] >>> def apply_tagger(tagger, corpus): ... return [tagger.tag(nltk.tag.untag(sent)) for sent in corpus] >>> gold = tag_list(brown.tagged_sents(categories='editorial')) >>> test = tag_list(apply_tagger(t2, brown.tagged_sents(categories='editorial'))) >>> cm = nltk.ConfusionMatrix(gold, test) >>> print(cm.pretty_format(sort_by_count=True, show_percents=True, truncate=9)) | N | | N I A J N V N | | N N T J . S , B P | ----+----------------------------------------------------------------+ NN | <11.8%> 0.0% . 0.2% . 0.0% . 0.3% 0.0% | IN | 0.0% <9.0%> . . . 0.0% . . . | AT | . . <8.6%> . . . . . . | JJ | 1.7% . . <3.9%> . . . 0.0% 0.0% | . | . . . . <4.8%> . . . . | NNS | 1.5% . . . . <3.2%> . . 0.0% | , | . . . . . . <4.4%> . . | VB | 0.9% . . 0.0% . . . <2.4%> . | NP | 1.0% . . 0.0% . . . . <1.8%>| ----+----------------------------------------------------------------+ (row = reference; col = test)
代码是从参考书上copy的,第六行的t2不明白是什么?在pythonwin上也没法正确运行,以后弄明白再修改。
四、cross-validation(交叉验证)
所谓交叉验证,就是讲整个数据集等分红N份,其中一份用做测试,N-1份用做训练,测试集不断的改变,总共进行N次,再取N次测试所得指标的平均值做为最后的评价结果。交叉验证的优势在于它使咱们可以看到模型在不一样的训练集上的稳定性,若是评价结果变化不大,则能够认为结果是准确的。