感謝林智仁教授,轉載請注明出處
(一)准備工作
LibSVM是什么?就我的理解而言,LibSVM是一套工具箱,用來實現SVM的基礎功能。它是開源的,可以深挖,玩轉之后可以借鑒、打散、整合到自己的工程里。同時,它又非常“初學者向”,它將SVM集成化、黑箱化,對於很多不希望深入研究SVM,但是又需要使用SVM的人來說,libSVM能滿足絕大多數要求。
盡管libSVM是初心者向的,但是它還是需要一些知識儲備的。
如果你沒有接觸過機器學習,最好先了解一些基礎知識,以便不至於迷失在一些名詞里,如訓練train,模型model,預測predict,樣本samples,特征feature,標簽label等。當然對大多數需要使用libSVM的人來說,這一步驟可以跳過。
如果你沒有接觸過SVM,可以瀏覽一下SVM Tutorial。這篇引導的好處是中英文雙語的且直接和libSVM對接,劣勢是比較淺顯。個人建議多花點時間了解SVM,這也許會花費幾天,或更久,但對SVM的理解越深刻,在之后使用libSVM時也會更得心應手。反之,如果很多基礎概念混淆的話,在使用中很有可能會犯些愚蠢的錯誤(這些錯誤則可能會花掉更多的時間)。值得注意的是,目前SVM的入門指導大多數是以“最大間隔”的為切入點直接闡述SVM。但同時,另一條路是從logistic的角度,切入SVM。個人認為,從logistic的角度切入更好(如http://blog.csdn.net/sunlylorn/article/details/7885604),尤其是在評價置信度的時候。
如果你對SVM有一定了解了,但還沒有實踐過,或者第一次接觸libSVM。那A Practical Guide to Support Vector Classification值得閱讀,這篇引導也許會花掉你30min或一下午(根據你的英語水平),然而它能給出一個合理的使用libSVM的總綱。再次強調,有條件的話一定要閱讀該指南。
另外,如果閱讀該指南毫無壓力的話,個人建議直接瀏覽林老師的網站http://www.csie.ntu.edu.tw/~cjlin/libsvm/ 來學習libSVM,如果讀英文實在捉急的話,可以先閱讀本文或其他文章,最后再去讀英文。
最后,libSVM提供了很多平台的版本和功能。本文基於windows 32-bit操作系統,利用libSVM做分類,語言上使用matlab+C混編。文中會零星總結、分享一些和libSVM無關,和matlab+C混編的內容,希望有所幫助。
(二)第一次使用libSVM
首先,libSVM的下載地址是zip file ,下載后解壓就可以得到工具包。解壓后的工具包內有一些文件夾和一些文件。之前說過,本文作者在windows下使用matlab+C,所以以后會用到windows文件夾和matlab文件夾里的內容。
我們先使用windows的exe執行程序來做個小例子。
(1)首先,我們來自己編譯一下exe程序。當然,你可以用已經編譯好的exe程序,但是,如果已編譯好的程序是64位的,而我們的系統是32位的,那我們就不得不重新編譯了(注:最新版本的liblinear1.96就是64位的)。編譯方法:a)打開dos命令行窗口,定位到liblinear目錄下。如果VC++的環境變量還沒設置,敲入以下命令來實現: "C:\Program Files\Microsoft VisualStudio 10.0\VC\bin\vcvars32.bat" (根據具體的安裝路徑調整命令);b)輸入nmake -f Makefile.win clean all。方法來源http://blog.csdn.net/zouxy09/article/details/10947323。
編譯好了exe程序,再確保你明白了一些機器學習的基礎名詞,然后我們可以開始了。
(2)訓練階段。例子中的訓練是利用windows文件夾下的svm-train.exe,訓練一個分類器。可以把這個exe看做一個函數,輸入是我們標記好類別的特征文件,輸出就是分類器模型文件。請用記事本打開libsvm根目錄下的heart_scale文件,如果你閱讀了SVM Tutorial,下面的東西應該很熟悉了。
我們仔細看看,這個文件是這樣的結構 :
"+1”或"-1” 1:一個數 2:一個數 3:一個數 … 13:一個數
有些時候,1~13之間會有幾個數沒有,比如第一個輪回:
+1 1:0.708333 2:1 3:1 4:-0.320755 5:-0.105023 6:-1 7:1 8:-0.419847 9:-1 10:-0.225806 12:1 13:-1
它沒有11:一個數,這等價於11后面的數是0,即11:0。之所以這樣是為了讓稀疏的特征少占點空間。
從這個例子出發,我們可以更好地理解特征文件的結構:
[label] [index1]:[value1] [index2]:[value2] …
[label] [index1]:[value1] [index2]:[value2] …
Label 就是說class(屬於哪一類,剛才的+1或-1), 就是你要分類的種類,通常是一些整數。
index 是有順序的索引,通常是連續的整數。就是指特征編號(剛才的1~13),必須按照升序排列
value 就是特征值(剛才的冒號后面的小數),用來 train 的數據。
訓練前我們要做的無非是選一個好特征,然后把特征按格式寫好。
(3)訓練。比較簡便的做法是寫一個bat來調用exe(因為我們要輸入一些參數)。進入windows文件夾,新建一個txt,在txt里寫如下內容:
svm-train.exe ../heart_scale ../heart_scale_model
pause
保存關閉txt后把txt后綴名改為bat,雙擊就可以使用了。
由於bat用的人不多,這里啰嗦一下它的意義。 第一行svm-train.exe是調用本目錄(bat所在目錄)下的svm-train.exe, ‘../’代表本目錄的上級目錄,heart_scale就是剛才看的那個亂糟糟的特征文件,’../heart_ scale _model’就是輸出到上級目錄的heart_scale_model文件,最后第二行的pause是運行完svm-train.exe,命令行暫停(沒有這個命令的話,命令行會一閃而逝,很多東西就看不見鳥)。
至於為什么格式是svm-train.exe + 特征文件 + 保存文件, 請閱讀SVM Tutorial。
(4)預測。和訓練類似,我們也是寫一個bat,不過此時的內容改為:
svm-predict.exe ../heart_scale ../heart_scale_model ../heart_scale_model_rst
pause
這個bat就是用剛才的 model,預測heart_scale,並將結果輸入到heart_scale_model_rst。你發現了,我們用的是heart_sacle訓練的模型,再用模型檢測它自己,理論上結果應該棒棒噠,不過看一下命令行,預測程序給出的Accuracy = 86.6667% (234/270)。同時,更具體的輸出結果保存為heart_scale_model_rst,用記事本打開可以看到每一行有一個數,這個數代表了預測的類別。順便一提,這里我們預測heart_scale,就是用heart_scale里每一個樣本的特征帶入model,得到的預測結果heart_scale_model_rst和heart_sacle里特征對應的label作比較,看是否一致。
總結一下,libSVM的訓練其實就是,搜集樣本->標記label->提取特征->寫特征文件->調用train.exe->得到model,這個model可以用來判斷新的未知label的特征到底應該屬於哪一個label。
最后,這個分類效果並不理想,至於原因和解決方法我們之后再說。