天天看點

使用libsvm進行分類預測

使用libsvm,首先需要将實際待分類的内容或資料(訓練資料,或預測資料)進行量化,然後通過libsvm提供的功能實作分類和預測。下面介紹使用libsvm的基本步驟。

準備訓練資料

資料格式:

<code>1</code>

<code>&lt;label1&gt; &lt;index1&gt;:&lt;value11&gt; &lt;index2&gt;:&lt;value12&gt;...</code>

<code>2</code>

<code>&lt;label2&gt; &lt;index1&gt;:&lt;value21&gt; &lt;index2&gt;:&lt;value22&gt;...</code>

<code>3</code>

<code>&lt;label3&gt; &lt;index1&gt;:&lt;value31&gt; &lt;index2&gt;:&lt;value32&gt;...</code>

<code>4</code>

<code>...</code>

每一行,表示以已定義的類别标簽,以及屬于該标簽的各個屬性值,每個屬性值以“屬性索引編号:屬性值”的格式。一行内容表示一個類别屬性以及與該類别相關的各個屬性的值。屬性的值,一般可以表示為“該屬性隸屬于該類别的程度”,越大,表示該屬性更能決定屬性該類别。

上面的資料必須使用數字類型,例如類别,可以通過不同的整數來表示不同的類别。

準備的原始訓練樣本資料存放在檔案raw_data.txt中,内容如下所示:

<code>1 1:0.4599 2:0.8718 3:0.1987</code>

<code>2 1:0.9765 2:0.2398 3:0.3999</code>

<code>3 1:0.0988 2:0.2432 3:0.7633</code>

歸一化

這一步對應于libsvm的縮放操作,即将量化的資料縮放到某一範圍之内。首先,需要把原始的訓練資料存放到檔案中作為輸入,如果實際應用中不需要從檔案輸入,可以根據需要修改libsvm的代碼,來滿足需要。

上面準備的檔案raw_data.txt定義了三個類别,分别為1,2,3,其中有三個屬性。正常情況下,每個屬性值範圍可能并不一定是在0到1之間,比如實際的溫度資料,銷售額資料,等等。

libsvm通過使用svm_scale來實作歸一化,下面是svm_scale的使用說明:

<code>用法:svmscale [-l lower] [-u upper] [-y y_lower y_upper] [-s save_filename] [-r restore_filename] filename</code>

<code>預設值: lower = -1,upper = 1,沒有對y進行縮放</code>

<code></code><code>-l:資料下限标記;lower:縮放後資料下限;</code>

<code></code><code>-u:資料上限标記;upper:縮放後資料上限;</code>

<code>5</code>

<code></code><code>-y:是否對目标值同時進行縮放;y_lower為下限值,y_upper為上限值;(回歸需要對目标進行縮放,是以該參數可以設定為 –y -1 1 )</code>

<code>6</code>

<code></code><code>-s save_filename:表示将縮放的規則儲存為檔案save_filename;</code>

<code>7</code>

<code></code><code>-r restore_filename:表示将縮放規則檔案restore_filename載入後按此縮放;</code>

<code>8</code>

<code></code><code>filename:待縮放的資料檔案(要求滿足前面所述的格式)</code>

我們輸入如下參數,來執行資料的縮放操作:

<code>-l 0 -u 1 -s src/s_rules.txt src/raw_data.txt</code>

資料縮放的區間為[0, 1],生成的縮放規則的檔案存放到檔案src/s_rules.txt中,最後面的檔案src/raw_data.txt就是我們進行分類的訓練資料檔案。

輸入上面參數執行後,可以看到歸一化的資料,如下所示:

<code>1.0 1:0.4114162014355702 2:1.0</code>

<code>2.0 1:1.0 3:0.3563584838823946</code>

<code>3.0 2:0.005379746835443016 3:1.0</code>

使用Eclipse的話,控制台輸出的就是上面的内容,也就是我們可以直接用來訓練的訓練資料,将其存為檔案train.txt。執行svm_scale指令,還輸出一個規則檔案(src/s_rules.txt):

<code>x</code>

<code>0.000000000000000 1.000000000000000</code>

<code>1 0.09880000000000000 0.9765000000000000</code>

<code>2 0.2398000000000000 0.8718000000000000</code>

<code>3 0.1987000000000000 0.7633000000000000</code>

訓練分類模型

訓練分類模型的過程,就是夠呢局前面歸一化的樣本資料,建立一個分類模型,然後根據這個分類模型就能夠進行分類的預測,這也是最終的目的。

我們看一下libsvm提供的訓練模型的指令:

<code>01</code>

<code>用法: svmtrain [options] training_set_file [model_file]</code>

<code>02</code>

<code>其中, options(操作參數):可用的選項即表示的涵義如下所示</code>

<code>03</code>

<code></code><code>-s svm類型:設定SVM 類型,預設值為0,可選類型有(對于回歸隻能選3或4):</code>

<code>04</code>

<code></code><code>0 -- C- SVC</code>

<code>05</code>

<code></code><code>1 -- n - SVC</code>

<code>06</code>

<code></code><code>2 -- one-class-SVM</code>

<code>07</code>

<code></code><code>3 -- e - SVR</code>

<code>08</code>

<code></code><code>4 -- n - SVR</code>

<code>09</code>

<code></code><code>-t 核函數類型:設定核函數類型,預設值為2,可選類型有:</code>

<code>10</code>

<code></code><code>0 -- 線性核:u'*v</code>

<code>11</code>

<code></code><code>1 -- 多項式核: (g*u'*v+ coef 0)deg ree</code>

<code>12</code>

<code></code><code>2 -- RBF 核:e( u v 2) g -</code>

<code>13</code>

<code></code><code>3 -- sigmoid 核:tanh(g*u'*v+ coef 0)</code>

<code>14</code>

<code></code><code>-d degree:核函數中的degree設定,預設值為3;</code>

<code>15</code>

<code></code><code>-g g :設定核函數中的g,預設值為1/k,其中k是指輸入資料中的屬性數;</code>

<code>16</code>

<code></code><code>-r coef 0:設定核函數中的coef 0,預設值為0;</code>

<code>17</code>

<code></code><code>-c cost:設定C- SVC、e - SVR、n - SVR中從懲罰系數C,預設值為1;</code>

<code>18</code>

<code></code><code>-n n :設定n - SVC、one-class-SVM 與n - SVR 中參數n ,預設值0.5;</code>

<code>19</code>

<code></code><code>-p e :設定n - SVR的損失函數中的e ,預設值為0.1;</code>

<code>20</code>

<code></code><code>-m cachesize:設定cache記憶體大小,以MB為機關,預設值為40;</code>

<code>21</code>

<code></code><code>-e e :設定終止準則中的可容忍偏差,預設值為0.001;</code>

<code>22</code>

<code></code><code>-h shrinking:是否使用啟發式,可選值為0 或1,預設值為1;</code>

<code>23</code>

<code></code><code>-b 機率估計:是否計算SVC或SVR的機率估計,可選值0 或1,預設0;</code>

<code>24</code>

<code></code><code>-wi weight:對各類樣本的懲罰系數C權重,預設值為1;</code>

<code>25</code>

<code></code><code>-v n:n折交叉驗證模式,随機地将資料剖分為n部分并計算交叉檢驗準确度和均方根誤差。</code>

以上這些參數設定可以按照SVM的類型和核函數所支援的參數進行任意組合,如果設定的參數在函數或SVM 類型中沒有也不會産生影響,程式不會接受該參數;如果應有的參數設定不正确,參數将采用預設值。

training_set_file是要進行訓練的資料集;model_file是訓練結束後産生的模型檔案,該參數如果不設定将采用預設的檔案名,也可以設定成自己慣用的檔案名。

針對上面歸一化操作得到的訓練資料,我們通過輸入如下參數并執行svmtrain指令進行訓練:

<code>src/train.txt src/model.txt</code>

輸入出的src/model.txt就是分類模型,模型資料的内容,如下所示:

<code>svm_type c_svc</code>

<code>kernel_type rbf</code>

<code>gamma 0.3333333333333333</code>

<code>nr_class 3</code>

<code>total_sv 3</code>

<code>rho 0.0 0.0 0.0</code>

<code>label 1 2 3</code>

<code>nr_sv 1 1 1</code>

<code>SV</code>

<code>1.0 1.0 1:0.4114162014355702 2:1.0</code>

<code>-1.0 1.0 1:1.0 3:0.3563584838823946</code>

<code>-1.0 -1.0 2:0.005379746835443016 3:1.0</code>

根據得出的分類模型,就可以進行分類預測了。

有關訓練分類模型的優化,從參考連結中引用一段,有興趣可以實際操作一下:

本實驗中的參數-s取3,-t取2(預設)還需确定的參數是-c,-g,-p。 另外,實驗中所需調整的重要參數是-c 和 –g,-c和-g的調整除了自己根據經驗試之外,還可以使用gridregression.py對這兩個參數進行優化。 該優化過程需要用到Python(2.5),Gnuplot(4.2),gridregression.py(該檔案需要修改路徑)。然後在指令行下面運作: python.exe gridregression.py -log2c -10,10,1 -log2g -10,10,1 -log2p -10,10,1 -s 3 –t 2 -v 5 -svmtrain E:/libsvm/libsvm-2.86/windows/svm-train.exe -gnuplot E:/libsvm/libsvm-2.86/gnuplot/bin/pgnuplot.exe E:/libsvm/libsvm-2.86/windows/train.txt &gt; gridregression_feature.parameter 以上三個路徑根據實際安裝情況進行修改。 -log2c是給出參數c的範圍和步長 -log2g是給出參數g的範圍和步長 -log2p是給出參數p的範圍和步長 上面三個參數可以用預設範圍和步長。 -s選擇SVM類型,也是隻能選3或者4 -t是選擇核函數 -v 10 将訓練資料分成10份做交叉驗證,預設為5 為了友善将gridregression.py是存放在python.exe安裝目錄下,trian.txt為訓練資料,參數存放在gridregression_feature.parameter中,可以自己命名。 搜尋結束後可以在gridregression_feature.parameter中最後一行看到最優參數。其中,最後一行的第一個參數即為-c,第二個為-g,第三個為-p,最後一個參數為均方誤差。前三個參數可以直接用于模型的訓練。然後,根據搜尋得到的參數,重新訓練,得到模型。

驗證分類模型

預測分類的指令,說明如下所示:

<code>用法:svmpredict [options] test_file model_file output_file</code>

<code>options(操作參數):</code>

<code></code><code>-b probability_estimates:是否需要進行機率估計預測,可選值為0 或者1,預設值為0。</code>

<code></code><code>model_file 是由svmtrain 産生的模型檔案;</code>

<code></code><code>test_file 是要進行預測的資料檔案;</code>

<code></code><code>output_file 是svmpredict 的輸出檔案,表示預測的結果值。</code>

這個指令有兩個主要的作用:

一個是在得出分類模型後,對分類模型進行驗證評估,來确定分類模型的準确性。這種情況下,到輸入的驗證資料實際上也是已經知道分類結果的,可以通過指定的方式進行選取,最終将模型的精度優化到能夠接受的程度。

另一個是,使用經過驗證後的模型,對實際中未知的資料進行分類,得到分類結果,這也是分類預測的最終目的和結果。

這裡,隻有通過一組已經知道類别的資料來做驗證,才能知道分類器(基于分類模型資料)的精度如何。如果分類器精度腳底,完全可以進行額外的參數尋優來調整模型。

準備驗證分類器的資料(已知類标簽,存為檔案test.txt),如下所示:

<code>1 1:0.0599 2:0.2718 3:0.1987</code>

<code>3 1:0.6765 2:0.1398 3:0.6999</code>

<code>2 1:0.0988 2:0.9432 3:0.7633</code>

上面的資料是和訓練資料屬于同一類型的,即已經知道類别,通過将其作為模拟的待預測資料來驗證分類模型的準确度。

輸入如下參數,進行模拟預測:

<code>src/test.txt src/model.txt src/predict.txt</code>

結果會輸出分類預測的精度:

<code>Accuracy = 33.33333333333333% (1/3) (classification)</code>

使用Eclipse的話會直接輸出到控制台。然後看一下預測的結果,儲存在檔案src/predict.txt中,内容如下所示:

<code>1.0</code>

<code>2.0</code>

可見,模型的精度不是很高,隻有一個預測與實際分類相符。我們這裡隻是舉個例子,資料又很少。實際分類過程中,如果出現這種精度特别低的情況,需要對分類模型進行調整,達到一個滿意的分類精度。

預測分類

實際上預測分類的資料是類别未知的,我們通過訓練得出的分類器要做的事情就是确定待預測資料的類别。使用libsvm預設是以檔案的方式輸入資料,而且預測要求的資料格式必須和訓練時相同,是以資料檔案中第一列的類标簽可以是随便給出的,分類器會處理資料,得出類别,然後輸出到指定的檔案中。

預測分類和前面的“驗證分類模型”中的執行過程是一樣的。

如果有其他需要,可以适當修改libsvm程式,使其支援你想要的輸入輸出方式。

繼續閱讀