對模型的評價是在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次測試所得指標的平均值做爲最後的評價結果。交叉驗證的優勢在於它使咱們可以看到模型在不一樣的訓練集上的穩定性,若是評價結果變化不大,則能夠認爲結果是準確的。