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
附:公衆號
順便測試下讚揚碼