国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

libsvm的使用

2019-11-09 17:36:07
字體:
來源:轉載
供稿:網友

本來學習LibSVM是想編寫cpp文件調用其中的接口函數的。

讀readme時,使用了一下。zip文件中自帶的windows系統下的。exe,發現無法運行,后來才發現自己電腦是win32,而包中的exe是64位的。

將。zip中的。cpp 。h文件用vs2010重新編譯一下就可以得到可以運行的。exe文件了。

我創建的工程文件名稱為SVMteset,最后得到的。exe文件也位于SVMteset 目錄下的Debug中。

下一步打算繼續嘗試調用函數接口做下實驗。

LibSVM學習詳細說明

代碼文件主要針對Matlab進行說明,但個人仍覺得講解的支持向量機內容非常棒,可以做為理解這一統計方法的輔助資料;

      LibSVM是臺灣林智仁(Chih-Jen Lin)教授2001年開發的一套支持向量機的庫,這套庫運算速度還是挺快的,可以很方便的對數據做分類或回歸。由于libSVM程序小,運用靈活,輸入參數少,并且是開源的,易于擴展,因此成為目前國內應用最多的SVM的庫。

這套庫可以從http://www.csie.ntu.edu.tw/~cjlin/免費獲得,目前已經發展到2.89版。下載.zip格式的版本,解壓后可以看到,主要有5個文件夾和一些c++源碼文件。

java——主要是應用于java平臺;

Python——是用來參數優選的工具,稍后介紹;

svm-toy——一個可視化的工具,用來展示訓練數據和分類界面,里面是源碼,其編譯后的程序在windows文件夾下;

tools——主要包含四個python文件,用來數據集抽樣(subset),參數優選(grid),集成測試(easy),數據檢查(checkdata);

windows——包含libSVM四個exe程序包,我們所用的庫就是他們,里面還有個heart_scale,是一個樣本文件,可以用記事本打開,用來測試用的。

其他.h和.cpp文件都是程序的源碼,可以編譯出相應的.exe文件。其中,最重要的是svm.h和svm.cpp文件,svm-PRedict.c、svm-scale.c和svm-train.c(還有一個svm-toy.c在svm-toy文件夾中)都是調用的這個文件中的接口函數,編譯后就是windows下相應的四個exe程序。另外,里面的 README 跟 FAQ也是很好的文件,對于初學者如果E文過得去,可以看一下。

下面以svm-train為例,簡單的介紹下,怎么編譯:(這步很簡單,也沒必要,對于僅僅使用libsvm庫的人來說,windows下的4個exe包已經足夠了,之所以加這步,是為了那些做深入研究的人,可以按照自己的思路改變一下svm.cpp,然后編譯驗證)

我用的是VC 6.0,新建一個控制臺(win32 console application)程序,程序名叫svm-train(這個可以隨意),點擊OK后,選擇empty。

進入程序框架后,里面什么都沒有,然后找到你的程序目錄,把svm-train.c、svm.h和svm.cpp拷貝過去(.c文件是c語言的,要是你習慣了c++,你盡可以改成.cpp),然后把這3個文件添加到工程,編譯。。。如果沒錯誤,到debug下面看看,是不是有個svm-train.exe。其實windows下的svm-train.exe就是這樣編譯出來的。

哈哈,怎么樣是不是很簡單。但是,這樣的程序直接運行沒意義,他要在dos下運行,接收參數才行。下面開始我們的libsvm的體驗之旅。

 

第一次體驗LibSvm

        1.把LibSVM包解壓到相應的目錄(因為我只需要里面windows文件夾中的東東,我們也可以只把windows文件夾拷到相應的目錄),比如D:/libsvm。

        2.在電腦“開始”的“運行”中輸入cmd,進入DOS環境。定位到d:/ libsvm下,具體命令如下:

              d: (回車)

            cd /libsvm/windows (回車)

              (上面第一行是先定位到盤符d,第二行cd是定位到相應盤符下的目錄)

        3.進行libsvm訓練,輸入命令:(這里要注意文件的名字,2.89以前版本都是svmtrain.exe)

        svm-train heart_scale train.model

        heart_scale——是目錄下的已經存在的樣本文件,要換成自己的文件,只需改成自己的文件名就可以了

        train.model——是創建的結果文件,保存了訓練后的結果

可以看到結果:

*

optimization finished, #iter = 162

nu = 0.431029

obj = -100.877288, rho = 0.424462

nSV = 132, nBSV = 107

      Total nSV = 132

其中,#iter為迭代次數,nu是你選擇的核函數類型的參數,obj為SVM文件轉換為的二次規劃求解得到的最小值,rho為判決函數的偏置項b,nSV為標準支持向量個數(0<a[i]<c),nBSV為邊界上的支持向量個數(a[i]=c),Total nSV為支持向量總個數(對于兩類來說,因為只有一個分類模型Total nSV = nSV,但是對于多類,這個是各個分類模型的nSV之和)。

  

在目錄下,還可以看到產生了一個train.model文件,可以用記事本打開,記錄了訓練后的結果。

svm_type c_svc//所選擇的svm類型,默認為c_svc

      kernel_type rbf//訓練采用的核函數類型,此處為RBF核

gamma 0.0769231//RBF核的參數γ

      nr_class 2//類別數,此處為兩分類問題

total_sv 132//支持向量總個數

rho 0.424462//判決函數的偏置項b

label 1 -1//原始文件中的類別標識

nr_sv 64 68//每個類的支持向量機的個數

SV//以下為各個類的權系數及相應的支持向量

1 1:0.166667 2:1 3:-0.333333 … 10:-0.903226 11:-1 12:-1 13:1

0.5104832128985164 1:0.125 2:1 3:0.333333 … 10:-0.806452 12:-0.333333 13:0.5

………..

-1 1:-0.375 2:1 3:-0.333333…. 10:-1 11:-1 12:-1 13:1

-1 1:0.166667 2:1 3:1 …. 10:-0.870968 12:-1 13:0.5

 

到現在,第一次體驗libsvm到這就基本結束了,其他的兩個(svm-predict、svm-scale)的使用過程類似。怎么樣,挺爽的吧。對于個別參數你還不理解,沒關系,下面我們會具體講到。

LibSvm使用規范:

其實,這部分寫也是多余,google一下“libsvm使用”,就會N多的資源,但是,為了讓你少費點心,在這里就簡單的介紹一下,有不清楚的只有動動你的mouse了。需要說明的是,2.89版本以前,都是svmscale、svmtrain和svmpredict,最新的是svm-scale、svm-train和svm-predict,要是用不習慣,只需要把那四個exe文件名去掉中間的短橫線,改成svmscale、svmtrain和svmpredict就可以了,我們還是按原來函數名的講。

1. libSVM的數據格式

Label 1:value 2:value ….

Label:是類別的標識,比如上節train.model中提到的1 -1,你可以自己隨意定,比如-10,0,15。當然,如果是回歸,這是目標值,就要實事求是了。

Value:就是要訓練的數據,從分類的角度來說就是特征值,數據之間用空格隔開

比如: -15 1:0.708 2:1056 3:-0.3333

需要注意的是,如果特征值為0,特征冒號前面的(姑且稱做序號)可以不連續。如:

-15 1:0.708 3:-0.3333

表明第2個特征值為0,從編程的角度來說,這樣做可以減少內存的使用,并提高做矩陣內積時的運算速度。我們平時在matlab中產生的數據都是沒有序號的常規矩陣,所以為了方便最好編一個程序進行轉化。

 

2. svmscale的用法

svmscale是用來對原始樣本進行縮放的,范圍可以自己定,一般是[0,1]或[-1,1]。縮放的目的主要是

1)防止某個特征過大或過小,從而在訓練中起的作用不平衡;

2)為了計算速度。因為在核計算中,會用到內積運算或exp運算,不平衡的數據可能造成計算困難。

用法:svmscale [-l lower] [-u upper]

[-y y_lower y_upper]

[-s save_filename]

[-r restore_filename] filename

其中,[]中都是可選項:

      -l:設定數據下限;lower:設定的數據下限值,缺省為-1

     -u:設定數據上限;upper:設定的數據上限值,缺省為 1

     -y:是否對目標值同時進行縮放;y_lower為下限值,y_upper為上限值;

     -s save_filename:表示將縮放的規則保存為文件save_filename;

     -r restore_filename:表示將按照已經存在的規則文件restore_filename進行縮放;

      filename:待縮放的數據文件,文件格式按照libsvm格式。

默認情況下,只需要輸入要縮放的文件名就可以了:比如(已經存在的文件為test.txt)

svmscale test.txt

這時,test.txt中的數據已經變成[-1,1]之間的數據了。但是,這樣原來的數據就被覆蓋了,為了讓規劃好的數據另存為其他的文件,我們用一個dos的重定向符 > 來另存為(假設為out.txt):

      svmscale test.txt > out.txt

運行后,我們就可以看到目錄下多了一個out.txt文件,那就是規范后的數據。假如,我們想設定數據范圍[0,1],并把規則保存為test.range文件:

svmscale –l 0 –u 1 –s test.range test.txt > out.txt

這時,目錄下又多了一個test.range文件,可以用記事本打開,下次就可以用-r test.range來載入了。

3. svmtrain的用法

svmtrain我們在前面已經接觸過,他主要實現對訓練數據集的訓練,并可以獲得SVM模型。

用法: svmtrain [options] training_set_file [model_file]

其中,options為操作參數,可用的選項即表示的涵義如下所示:

-s設置svm類型:

0 – C-SVC

1 – v-SVC

2 – one-class-SVM

3 –ε-SVR

4 – n - SVR

-t設置核函數類型,默認值為2

0 --線性核:u'*v

1 --多項式核:(g*u'*v+coef0)degree

2 -- RBF核:exp(-γ*||u-v||2)

3 -- sigmoid核:tanh(γ*u'*v+coef0)

-d degree:設置多項式核中degree的值,默認為3

-gγ:設置核函數中γ的值,默認為1/k,k為特征(或者說是屬性)數;

-r coef 0:設置核函數中的coef 0,默認值為0;

-c cost:設置C-SVC、ε-SVR、n - SVR中從懲罰系數C,默認值為1;

-n v:設置v-SVC、one-class-SVM與n - SVR中參數n,默認值0.5;

-pε:設置v-SVR的損失函數中的e,默認值為0.1;

-m cachesize:設置cache內存大小,以MB為單位,默認值為40;

-eε:設置終止準則中的可容忍偏差,默認值為0.001;

-h shrinking:是否使用啟發式,可選值為0或1,默認值為1;

-b概率估計:是否計算SVC或SVR的概率估計,可選值0或1,默認0;

-wi weight:對各類樣本的懲罰系數C加權,默認值為1;

-v n:n折交叉驗證模式;

model_file:可選項,為要保存的結果文件,稱為模型文件,以便在預測時使用。

默認情況下,只需要給函數提供一個樣本文件名就可以了,但為了能保存結果,還是要提供一個結果文件名,比如:test.model,則命令為:

svmtrain test.txt test.model

 

結果說明見LibSVM學習(二).

4. svmpredict的用法

svmpredict是根據訓練獲得的模型,對數據集合進行預測。

用法:svmpredict [options] test_file model_file output_file

其中,options為操作參數,可用的選項即表示的涵義如下所示:

-b probability_estimates——是否需要進行概率估計預測,可選值為0或者1,默認值為0。

model_file ——是由svmtrain產生的模型文件;

test_file——是要進行預測的數據文件,格式也要符合libsvm格式,即使不知道label的值,也要任意填一個,svmpredict會在output_file中給出正確的label結果,如果知道label的值,就會輸出正確率;

output_file ——是svmpredict的輸出文件,表示預測的結果值。

 

至此,主要的幾個接口已經講完了,滿足一般的應用不成問題。對于要做研究的,還需要深入到svm.cpp文件內部,看看都做了什么。

 

逐步深入LibSVM(個人認為最精彩部分)

 

其實,在之前上海交大模式分析與機器智能實驗室對2.6版本的svm.cpp做了部分注解,(在哪里?google一下你就知道)。但是,這個注釋只是針對代碼而注釋,整篇看下來,你會發現除了理解幾個參數的含義,還是會對libsvm一頭霧水。當然作為理解程序的輔助材料,還是有很大用處的。特別是,對幾個結構體的說明,比較清楚。但是要清楚程序具體做了什么,還是要追蹤程序中去。

       由于svm涉及的數學知識比較多,我們這篇只是講一些基本的思路,所以就從最基本的C-SVC型svm,核函數采用常用的RBF函數。LibSVM就采用2.6版本的好了,因為后續的版本作者又加了很多內容,不易理解作者最初的思路。我是做模式識別,主要從分類的角度來解析函數的調用過程,我們從svmtrain.c看起,其調用的函數過程如下:4.1

   4.2

    上圖是整個C-SVC的計算過程,下面對一些重要的內容進行具體說明:

1. svm_group_class

      在2.6版中沒有此函數的,其功能直接在svm_train實現,為了增強可讀性,2.89版中設置了這個函數,其實所作的工作都是一樣的。需要說明的是其重新排列后perm中只存儲的是各個樣本在原始位置的序號,而非數據。這樣做的好處有兩個:

       1)不必破壞原始數據(也就是讀進來的x的數據);

       2)檢索起來方便,只需要L維的數據檢索,得到序號后,然后定位到原始數據中相應的位置就可以。

                                     4.3

       perm是中各類的排列順序是按照原始樣本中各類出現的先后順序排列的,不一定是按照你原始樣本的label序號排列,假如原始樣本的label是{-1,0,1},而最先出現的label為1的樣本,那么perm中就把label為1的作為類0最先排列。而start中記錄的是各類的起始序號,而這個序號是在perm中的序號。

2. 多類判別的one-against-one

      svm做判別是用的分界線(面),兩類之間只有一個分界線(面),因此分類器也只有1種,要么是1類要么是2類。但是對于多類,分類方式就有多種。目前,存在的方法主要有:

       1)1-V-R方式

       對于k類問題把其中某一類的n個訓練樣本視為一類,所有其他類別歸為另一類,因此共有k個分類器。最后預測時,判別式使用競爭方式,也就是哪個類得票多就屬于那個類。

       2)1-V-1方式

       也就是我們所說的one-against-one方式。這種方法把其中的任意兩類構造一個分類器,共有(k-1)×k/2個分類器。最后預測也采用競爭方式。

       3)有向無環圖(DAG-SVM)

       該方法在訓練階段采用1-V-1方式,而判別階段采用一種兩向有向無環圖的方式。

       LibSVM采用的是1-V-1方式,因為這種方式思路簡單,并且許多實踐證實效果比1-V-R方式要好。 

                                                    4.4   

       上圖是一個5類1-V-1組合的示意圖,紅色是0類和其他類的組合,紫色是1類和剩余類的組合,綠色是2類與右端兩類的組合,藍色只有3和4的組合。因此,對于nr_class個類的組合方式為:

                                                        for(i = 0; i < nr_class; i ++)

                                                        {

                                                               for(j = i+1; i < nr_class; j ++)     

                                                               { 類 i –V – 類 j }

                                                        }

3. hessian矩陣的內存處理        

      因為svm是基于結構風險最小的,因此在分類識別方式具有較傳統的基于經驗風險最小的方式有優勢。但是svm也有一個致命的缺陷,因為要計算hessian矩陣Qij所耗的內存巨大,不利于實踐中應用。目前,怎么減小內存的使用依舊是SVM的研究的課題。LibSVM對hessian矩陣處理的策略是定義了一個內存處理類Cache類,預先認為分配一定的內存,存儲計算好的Qij,其序號的檢索采用雙向鏈表的方式,加快了檢索速度。其最重要的函數為:

       int Cache::get_data(const int index,Qfloat **data,int len)

      //len 是 data 的長度,data為返回的內存首地址,index為Qij的行。

       每次都要查找鏈表中行為index的Qi,假如已經計算過了,就返回計算過的內存地址,并把儲存首地址的鏈表節點插入到鏈表尾部。假如沒計算過,就分配內存并進行計算,當剩余的內存不夠時,就要回收鏈表頭指向的內存。這里,可能有人會問,難道以前計算的就沒有用了嗎??其實,是因為Qij是稀疏矩陣,在訓練過程中只要其對應的alpha[i]不再變動(這時alpha[i]=0或者alpha[i]=C),其對應的Qi就不會被選到來訓練,因此原來計算的Qi就沒有用了。其實,鏈表的順序代表了別選到的頻率,最頭部的是最不可能被選到,因為這時alpha[i]=0或者alpha[i]=C,而最尾部的最容易被選到。

4. 數據選擇select_working_set(i,j)     

     對于樣本數量比較多的時候(幾千個),SVM所需要的內存是計算機所不能承受的。目前,對于這個問題的解決方法主要有兩種:塊算法和分解算法。這里,libSVM采用的是分解算法中的SMO(串行最小化)方法,其每次訓練都只選擇兩個樣本。我們不對SMO做具體的討論,要想深入了解可以查閱相關的資料,這里只談談和程序有關的知識。

      一般SVM的對偶問題為:                      

                                       4.5              (4.1)                                                              

S.t.        

                                                        4.6                                                                                          

     SVM收斂的充分必要條件是KKT條件,其中:

           4.7           (4.2)

     由4.1式求導可得:                          4.8       (4.3)

     進一步推導可知:

                       4.9                              (4.4)

    也就是說,只要所有的樣本都滿足4.4式,那么得到解就是最優值。因此,在每輪訓練中,每次只要選擇兩個樣本(序號為i和j),是最違反KKT條件(也就是4.4式)的樣本,就能保證其他樣本也滿足KKT條件。序號i和j的選擇方式 :            4.10                         (4.5)

5. 停止準則

    LibSVM程序中,停止準則蘊含在了函數select_working_set(i,j)返回值中。也就是,當找不到符合4.5式的樣本時,那么理論上就達到了最優解。但是,實際編程時,由于KKT條件還是蠻苛刻的,要進行適當的放松。令:

                                                              4.11                                 (4.6)

     由4.4式可知,當所有樣本都滿足KKT條件時,gi ≤ -gj

       加一個適當的寬松范圍ε,也就是程序中的eps,默認為0.001,那么最終的停止準則為:

                                                                           gi ≤ -gj+ε  →    gi + gj≤ε                                    (4.7)

6. 因子α的更新

    由于SMO每次都只選擇2個樣本,那么4.1式的等式約束可以轉化為直線約束:

              4.12                                             (4.8)

   轉化為圖形表示為:

       4.13                            

      把4.8式中α1由α2 表示,即:4.14,結合上圖由解析幾何可得α2的取值范圍:

      4.15           (4.9)

     經過一系列變換,可以得到的α2更新值α2new

  4.16                                               (4.10)

    結合4.9和4.10式得到α2new最終表達式:

      4.17                                                            (4.11)

      得到α2new后,就可以由4.8式求α1new

      這里,具體操作的時候,把選擇后的序號i和j代替這里的1和2就可以了。當然,編程時,這些公式還是太抽象。對于4.9式,還需要具體細分。比如,對于y1 y2 = -1時的L = max(0,α2 - α1),是0大還α2 - α1是大的問題。總共需要分8種情況。

7. 數據縮放do_shrinking()

     上面說到SVM用到的內存巨大,另一個缺陷就是計算速度,因為數據大了,計算量也就大,很顯然計算速度就會下降。因此,一個好的方式就是在計算過程中逐步去掉不參與計算的數據。因為,實踐證明,在訓練過程中,alpha[i]一旦達到邊界(alpha[i]=0或者alpha[i]=C),alpha[i]值就不會變,隨著訓練的進行,參與運算的樣本會越來越少,SVM最終結果的支持向量(0<alpha[i]<C)往往占很少部分。

       LibSVM采用的策略是在計算過程中,檢測active_size中的alpha[i]值,如果alpha[i]到了邊界,那么就應該把相應的樣本去掉(變成inactived),并放到棧的尾部,從而逐步縮小active_size的大小。

8. 截距b的計算

    b計算的基本公式為:

     4.18                                                                       (4.12)

     理論上,b的值是不定的。當程序達到最優后,只要用任意一個標準支持向量機(0<alpha[i]<C)的樣本帶入4.12式,得到的b值都是可以的。目前,求b的方法也有很多種。在libSVM中,分別對y=+1和y=-1的兩類所有支持向量求b,然后取平均值:

     4.19                                                                     (4.13)

    至此,libSVM的整個思路我們簡單的過了一遍,里面涉及到很到理論知識,許多細節需要查看相關的SVM的書籍。說實話,筆者也是新手,有些理論也沒弄很清楚,我只能把我知道的盡量的講出來。希望對一些想要了解SVM的有所幫助。

 

分界線的輸出

對于學習SVM人來說,要判斷SVM效果,以圖形的方式輸出的分解線是最直觀的。LibSVM自帶了一個可視化的程序svm-toy,用來輸出類之間的分界線。他是先把樣本文件載入,然后進行訓練,通過對每個像素點的坐標進行判斷,看屬于哪一類,就附上那類的顏色,從而使類與類之間形成分割線。我們這一節不討論svm-toy怎么使用,因為這個是“傻瓜”式的,沒什么好討論的。這一節我們主要探討怎么結合訓練結果文件,自己編程輸出分界線。

       為什么說是分界線呢,其實嚴格說來是分解超平面,但是我們為了能直觀用繪圖工具繪(比如matlab)出圖來只能輸出具有二維(也就是特征數是2)的樣本分界,因此也就成了線了。好了,閑話少說,進入正題。要繪分界線,就要用到訓練結果,我們在第二節和第三節都討論了,訓練結果(或訓練模型)文件怎么輸出,但是,沒怎么詳細說明怎么使用訓練結果,現在具體說明。下面是兩個模型文件:

                  5.1              5.2

                          圖5.1 兩類模型文件                                 圖5.2 三類模型文件

     從圖5.1和5.2比較可以看出,兩類只存在一個分類器,因此每個支持向量對應的系數α(也就是SV的第一排),也只有 1個(當然,截距rho也只有一個)。這種情況最簡單,只要把相應的支持向量和α的值帶入方程:

5.3                                (5.1)

     找到為0的解,就是分界點了。(式中,有些文獻是+b,libSVM采用的是-b)

    對于三類或多類時,情況就比較復雜。我們原來討論過,對于類數k>2的情況,分類器個數為k×(k-1)/2個,那么對應的b值(也就是rho)應該也是k×(k-1)/2個。那么每個支持向量對應的系數α是多少呢?是k-1個,因為每個支持向量(sv)與其他每個類都有一個系數相對應。當然,和有的類對應時可能不是標準支持向量(0<alpha[i]<C),但是至少和其中一個類對應是標準的。我們先看一下圖5.2的SV的數據結構:

 

各nSV對應的αiyi

特征1

特征2

類0(label為-1)

前13個

類0 - V -類1

類0 - V -類2

1:0.297595

2:1.197805

0.4800095239454689

0.2016577869168293

類1(label為0)

中間9個

類1 - V -類0

類1 - V -類2

1:3.621706

2:1.263636

-0.6580578158072528

0.7036762846823739

類2(label為1)

后8個

類2 - V -類0

類2 - V -類1

1:8.296066

2:7.225341

-0.7056286598529473

-0.6494097661702236

    從表中,可以看出,每個支持向量(SV)都有相應的k-1(這里的k為3)個α,后面就是向量的數據。因此,輸出分界線時,只要認清系數的位置就可以了。如要輸出類0和類2之間的分界線,就要帶入類0的第二列和類2的第1列中的α。

   這里需要重點說明的是:文件輸出的不是單純的α,實際上是αiyi(這里的yi是在訓練時的+1或-1,而不是原始樣本的label),因此在帶入5.1式時,不需要判斷yi的值了。

      了解了數據結構以后,就是求解方程。5.1式是個多元方程(這和x的維數有關,這里討論的是2維的,因此是二元方程),而只有一個等式,因此要對其中一個參數做定常處理。先求出其中一個參數的范圍,不妨設為x[0](在繪圖時相當于x坐標軸)x_max和x_min,然后分成100等分,對每一個節點處

      x[0]= i×(x_max- x_min)/100+ x_min

      這樣,x[0]就相當于固定了,然后代入5.1式求x[1](也就是y)。這就轉化成了一元方程,可以采用傳統的數學解法,這里,我采用的是網絡遍歷法。也就是對x[1]也分成100分進行遍歷,把節點處的x[1]:

       x[1]= j×(y_max- y_min)/100+ y_min

     代入5.1式,看是否接近于0,如果接近0,說明此點是邊界點,然后輸出坐標就可以了。

                                                 for(i = 0; i < 100; i ++)

                                                        for(j = 0; j < 100; j ++)

                                                        {

                                                               X[0] = x[0]i;

                                                               X[1] = x[1]j;

                                                             if(5.4)

                                                              cout << X[0] << “ “ <<  X[1] <<endl;

                                                        }

    分界點坐標輸出以后,就可以用matlab把分界線繪制出來了。

 

easy.py和grid.py的使用

 

我們在“LibSVM學習(一)”中,講到libSVM有一個tools文件夾,里面包含有四個python文件,是用來對參數優選的。其中,常用到的是easy.py和grid.py兩個文件。其實,網上也有相應的說明,但很不系統,下面結合本人的經驗,對使用方法做個說明。

       這兩個文件都要用python(可以在http://www.python.org上下載到,需要安裝)和繪圖工具gnuplot(可以在ftp://ftp.gnuplot.info/pub/gnuplot/上下載,不需要安裝)。假設python安裝在d:/libsvm/tools/python26下,而gnuplot解壓到d:/libsvm/tools/gnuplot,libsvm放在了d:/libsvm/program中(這時easy.py和grid.py文件的目錄為d:/libsvm/program/tools)。另外,需要注意的是版本,我的是python 2.6、gnuplot 4.2 和libsvm 2.89,操作系統是WINXP。

1. grid.py使用方法

        文件grid.py是對C-SVC的參數c和γ做優選的,原理也是網格遍歷,假設我們要對目錄d:/libsvm/program/tools下的樣本文件heart_scale做優選,其具體用法為:

      

       第一步:打開d:/libsvm/program下的tools文件夾,找到grid.py文件。用python打開(不能雙擊,而要右鍵選擇“Edit with IDLE”),修改svmtrain_exe和gnuplot_exe的路徑。

                              svmtrain_exe = r"D:/libSVM/program/svm-train.exe"

                              gnuplot_exe = r"D:/libSVM/gnuplot/pgnuplot.exe"

       (這里面有一個是對非win32的,可以不用改,只改# example for windows下的就可以了)

      第二步:運行cmd,進入dos環境,定位到d:/libsvm/program/tools文件夾,這里是放置grid.py的地方。怎么定位可以參看第一節。

      第三步:輸入以下命令:

                                          d:/libsvm/python26/python grid.py heart_scale

       你就會看到dos窗口中飛速亂串的[local]數據,以及一個gnuplot的動態繪圖窗口。大約過10秒鐘,就會停止。Dos窗口中的[local]數據時局部最優值,這個不用管,直接看最后一行:

                                          2048.0 0.0001220703125 84.0741

       其意義表示:C = 2048.0;γ=0.0001220703125(γ是哪個參數?參看LibSVM學習(三)中svmtrain的參數說明);交叉驗證精度CV Rate = 84.0741%,這就是最優結果。

      第四步:打開目錄d:/libsvm/program/tools,我們可以看到新生成了兩個文件:heart_scale.out和heart_scale.png,第一個文件就是搜索過程中的[local]和最優數據,第二文件就是gnuplot圖像。

       現在,grid.py已經運行完了,你可以把最優參數輸入到svmtrain中進行訓練了。當然了,你在當中某一步很可能出現問題,不過不要緊,我也不是一下子成功的,摸索了半天才成功。下面就需要注意的問題說明一下:

        1)grid.py和svm-train的版本要統一,也就是說你不能用2.6的grid.py去調用2.89的svm-train。

        2)你的目錄中如果有空格,比如d:/program files/ libsvm/...,那么無論是在第一步還是第二步,請把目錄改成d:/progra~1/ libsvm/...

        3) 第三步的命令問題。首先要看你定位到哪個目錄,那么其下的文件就不需要帶路徑,否則就要帶。像我們上面的命令,我當前的目錄是d:/libsvm/program/tools,那么其下的easy.py和heart_scale文件就不需要加路徑,而python.exe是在d:/libsvm/python26/下,因此不在當前目錄下,所以要加路徑。比如,當我首先用dos定位到d:/libsvm/python26時,其命令就可以改成:

                     python  d:/libsvm/program/tools/grid.py  d:/libsvm/program/tools/heart_scale

       總起來說,命令為python 目標文件 樣本文件,其原則是要讓系統找得到文件。假如系統提示你“不是內部或外部命令”,說明你python的路徑錯誤,而如果是‘not found file’的提示,很可能是其他兩個文件路徑錯誤。

        4)假如,你仍舊出現問題,那么請換一下python或者gnuplot的版本,目前python最新版本是3.1,但是好像會出問題,老一點的版本2.4或2.5的兼容性會更好。

2. easy.py使用方法

    文件easy.py對樣本文件做了“一條龍服務”,從參數優選,到文件預測。因此,其對grid.py、svm-train、svm-scale和svm-predict都進行了調用(當然還有必須的python和gnuplot)。因此,運行easy.py需要保證這些文件的路徑都要正確。當然還需要樣本文件和預測文件,這里樣本文件還是用heart_scale,預測文件我們復制一份然后改名heart_test,下面說一下使用方法:

    第一步:打開easy.py,修改# example for windows下的幾個路徑: 

6.1

   第二步:運行cmd,進入dos環境,定位到放置easy.py的目錄d:/libsvm/program/tools。

   第三步:輸入命令:

                    d:/libsvm/python26/python easy.py heart_scale heat_test

           你就會看到一個gnuplot的動態繪圖窗口。大約20s以后停止,dos窗口顯示為:

                                   Scaling training data...

                                   Cross validation...

                                   Best c=2048.0, g=0.0001220703125 CV rate=84.0741

                                   Training...

                                   Output model: heart_scale.model

                                   Scaling testing data...

                                   Testing...

                                   Accuracy = 85.1852% (230/270) (classification)

                                   Output prediction: heart_test.predict

    這就是最終預測結果,可以看到第三行就是調用grid.py的結果。在d:/libsvm/program/tools下你會看到又多了7個文件,都是以前我們碰到的過程文件,都可以用記事本打開。

3. 常見的問題解析:

    1)

            Scaling training data...              Cross validation...              Traceback (most recent call last):              File "easy.py", line 61, in ?              c,g,rate = map(float,last_line.split())              ValueError: need more than 0 values to unpack

       [解析] 說明你的grid.py運行出現錯誤,你可以參照第一部分“grid.py使用方法”運行一下就會發現問題。另外,有的說是相對路徑的問題,建議找到easy.py的以下部分:

       cmd = "%s -svmtrain %s -gnuplot %s %s" % (grid_py, svmtrain_exe, gnuplot_exe, scaled_file)改成          cmd = "%s %s -svmtrain %s -gnuplot %s %s" % (python_path, grid_py, svmtrain_exe, gnuplot_exe, scaled_file)

     2)

            Traceback (most recent call last)              File "grid.py", line 349, in ?              main()              File "grid.py", line 344, in main              redraw(db)              File "grid.py", line 132, in redraw              gnuplot.write("set term windows/n")              IOError [Errno 22] Invalid argument       [解析]說明你的gnuplot.exe在調用過程中出現問題,要么是你的路徑不對,要么是你的版本不對,請檢查。

    3)

            Traceback (most recent call last):              File "C:/Python24/lib/threading.py", line 442, in __bootstrap               self.run()               File "c:/libsvm/tools/gridregression.py", line 212, in run               self.job_queue.put((cexp,gexp,pexp))               File "C:/Python24/lib/Queue.py", line 88, in put               self._put(item)               File "c:/libsvm/tools/gridregression.py", line 268, in _put               self.queue.insert(0,item)               AttributeError: 'collections.deque' object has no attribute 'insert

       [解析] 很顯然,你調用的是gridregression.py,其是用來做回歸用的。如果你調用easy.py也出現這種問題按照原作者的說法,這里是因為你的python調用出現錯誤,很可能是版本不對,如果是2.4的版本,請把easy.py中的

      self.queue.insert(0,item)改成      if sys.hexversion >= 0x020400A1:              self.queue.appendleft(item)       else              self.queue.insert(0,item)

頂 8 踩 0    上一篇特征選擇簡介下一篇Is it OK to mix categorical and continuous data for SVM (Support Vector Machines)?

我的同類文章

http://blog.csdn.net?新浪微博的JSON解析2015-10-07?數據處理之標準化/歸一化方法2015-04-04
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 武隆县| 紫阳县| 宣武区| 东丽区| 苗栗市| 衡山县| 蓝田县| 东海县| 浦县| 正宁县| 托克逊县| 容城县| 阿拉善左旗| 道真| 鲜城| 冷水江市| 建宁县| 竹北市| 和平县| 瑞安市| 惠水县| 常州市| 龙口市| 舟山市| 万全县| 齐齐哈尔市| 资中县| 乐东| 衡南县| 滦南县| 祥云县| 万载县| 邢台县| 阳谷县| 镇安县| 九寨沟县| 平昌县| 平和县| 郓城县| 库尔勒市| 彭山县|