:::

大家一起來預測吧!使用Weka指令列實作預測功能 / Making Predictions with Weka in Command Line

image

Weka除了用Explorer來預測未知之外,還能透過指令列直接操作,以便跟其他程式,像是AutoIT的Run()進行整合。這篇就是要示範如何使用指令列來操作Weka進行SMOLibSVM兩種分類器的預測。


預測的指令列使用方法 / Prediction Command Line Usage

image

Weka作為一個Java的函式庫,就可以用Java的指令列呼叫方式直接使用Weka。然而,由於有時候我們還會用Weka的Package Manger安裝其他套件的關係,呼叫Weka的方式就不能用最單純的引用jar檔來執行預測這麼簡單。

我試了幾種呼叫Weka方式之後,最後找到可以正常運作的Weka預測指令如下:

java -cp "C:\Program Files\Weka-3-8\weka.jar" weka.Run weka.classifiers.functions.SMO -T iris-test-set.arff -l iris-smo.model -p 0

以下個別說明每個部分指令的功用,紅色文字表示可能會需要修改的參數:

  • java:使用Java的JVM來執行後面的指令。如果你能夠正常使用Weka的Explorer,表示你已經正常安裝Java運作環境JRE,這樣就能用這個java指令。
  • -cp "C:\Program Files\Weka-3-8\weka.jar":-cp是指定JVM到後面的路徑底下搜尋Java的類別(請參考「Java基礎教程-運行及配置(一)」),後面的「"C:\Program Files\Weka-3-8\weka.jar"」就是Weka安裝目錄底下的「weka.jar」檔案。注意前後要用雙引號「"」框起來,以免Program Files這個路徑被視為是兩個參數。
  • weka.Run:要Weka執行後面的指令。
  • weka.classifiers.functions.SMO:預測所使用的分類器。
  • -T iris-test-set.arff:-T表示後面指定的是測試集(注意,是大寫T不是小寫t),而「iris-test-set.arff」就是測試集檔案的路徑。
  • -l iris-smo.model:-l表示載入分類模型,而「iris-smo.model」就是分類模型的路徑。分類模型的部分後面我會介紹。
  • -p 0:-p表示指定預測要使用的特徵(attributes)範圍,不過-p 0是特殊用法,會直接輸出預測結果。

上面有幾個紅色文字是我們可以自訂的參數,以下我繼續說明這些參數是怎麼來的。


weka.jar的位置 / Location of weka.jar

image

Weka的所有核心功能都在weka.jar中。預設weka.jar會放在Weka的安裝目錄底下,通常會是以下路徑:

C:\Program Files\Weka-3-8\weka.jar

許多教學會直接引用額外的weka.jar,你也可以從「Download weka-stable-3.8.0.jar file」直接下載3.8版純weka.jar檔案並放在你的伺服器上。不過這種方法只能使用Weka的基本功能,如果會用到Pacakge Manager安裝的其他功能時就很容易發生錯誤。也許「Problem evaluating classifier: libsvm classes not in CLASSPATH」這篇可以解決這個問題,不過最簡單的方式還是在指令列直接呼叫你在Explorer使用的Weka,這樣通常比較不會有問題。

分類器 / Classifier

image

在預測之前,我們要先決定好要使用的分類器與分類模型。分類器可以在進行預測建模時的結果輸出Classifier output最上面的Scheme中找到它的全名。以SMO來說,它的全名是「weka.classifiers.functions.SMO」。而使用Package Manager額外安裝的外掛LibSVM,它的全名則是「weka.classifiers.functions.LibSVM」。

一般來說,我們要評估正確率最高、又不會過擬合(overfitting)的分類器。分類器的選擇有很多考量,這就不是本篇要討論的重點。總之,要選擇一種分類器就是了。

關於分類器的操作方式,請參考「用Weka分類模型來預測未知案例」這篇。

在這個例子中,我以IRIS資料集作為訓練樣本,各別使用兩種實作支持向量機SVM的「weka.classifiers.functions.SMO」跟「weka.classifiers.functions.LibSVM」分類器。不同的分類器會對應到不同的分類模型,請看下面的說明。

分類模型的位置 / Location of stored classifier model

image

在決定好要使用的分類器之後,我們要把分類結果儲存成模型檔案(Model)。請在左下角的「Result list」按右鍵,選擇「Save model」。Weka不會為分類模型加上任何副檔名,為了方便識別,我建議將檔案命名為資料集與分類器的名稱,而副檔名則加上.model。

在這個例子中,我準備了兩個分類模型供大家直接下載練習:

待預測的測試集 / Test set for prediction

image

接著我們要準備一個需要預測的測試集檔案。實際使用時,我們可以用任何程式來將需要預測的案例組合成測試集檔案,以便用Weka來進行預測。測試集的資料格式(@attribute的部分)必須與上面建立分類模型時使用的訓練集一樣,只是class特徵為「?」表示待預測,這樣才能用建立好的分類模型進行預測。測試集的內容請用Weka的ARFF格式來撰寫,省下轉換的額外手續。

我從IRIS資料集中挑選了一筆案例,將class特徵改為「?」,簡單地完成了一筆案例的IRIS測試集。你可以從下面網址下載該測試集來練習:

ARFF檔案內容 / ARFF format

該測試集的檔案內容如下:

@relation iris

@attribute sepallength numeric
@attribute sepalwidth numeric
@attribute petallength numeric
@attribute petalwidth numeric
@attribute class {Iris-setosa,Iris-versicolor,Iris-virginica}

@data
5.9,3,5.1,1.8,?

在此順便說明一下Weka的ARFF格式。@relation後面寫的是資料集的名稱,分類預測時不使用。@attribute後面接的是特徵名稱跟資料類型,numeric資料類型表示是連續資料,而class特徵後面以{}框起來的三種不同的類別資料,表示class是一個類別資料。@data換行後,下面每一行都是一筆案例,而案例的特徵使用逗號隔開。@data後面的格式就跟CSV的格式一樣。


進行預測 / Prediction

image

一旦準備好Weka的預測指令之後,我們就可以用該指令來預測了。跟上圖一樣的,我們使用的預測指令如下:

java -cp "C:\Program Files\Weka-3-8\weka.jar" weka.Run weka.classifiers.functions.SMO -T iris-test-set.arff -l iris-smo.model -p 0

執行後,如果參數中的路徑都沒寫錯,那就可以得到如下的預測結果:

=== Predictions on test data ===

    inst#     actual  predicted error prediction
        1        1:? 3:Iris-virginica       0.667

因為我們輸入的測試集只有一筆案例,所以這裡只輸出一筆案例的預測結果。在?後面的「3:Iris-virginica」表示是第三個類別「Iris-virginica」。而後面的「0.667」表示分類模型預測該結果的可能機率。分類模型會選擇可能機率最大的分類結果作為該案例的預測結果,這個意思就是分類模型預測該測試集的案例有「66.7%」的機率會是「Iris-virginica」。

這樣子就完成用指令列操作Weka進行預測囉。


小結 / In closing

Weka_(software)_logo

圖 / 維基百科

雖然Weka可以用Java程式碼來呼叫,但現在寫Java的機會越來越少,還是指令列比較容易跟其他的程式一起搭配,包括AutoIT。現在這篇整理好Weka用指令列來進行預測的方式後,我們就能用AutoIT來使用Weka囉。

總共6 則留言 ( 我要發問 , 隱藏留言 顯示留言 )

  1. 請問版主,libsvm與SMO的差異在哪呢?

    回覆刪除
    回覆
    1. 好問題。

      StackOverflow也有人問類似的問題
      https://stackoverflow.com/questions/23674411/weka-smo-vs-libsvm

      或是在ResearchGate上的提問
      https://www.researchgate.net/post/Comparison_between_SMO_and_libsvm_and_choice_of_metrics

      根據Samer Sarsam的說法
      SMO在訓練向量分類器時實作的是John Platt的序列最小最佳化演算法(sequential minimal optimization algorithm)
      LibSVM是libsvm函式庫的包裝,包括了單一結果(one-class)的SVM分類器
      因此,這兩個演算法結果不太一樣。

      個人使用經驗上,SMO很多時候的正確率比LibSVM還高
      所以久而久之我就直接使用SMO而已了。

      刪除
    2. 在使用這兩種方法後,確實像版主說的SMO正確率高很多,因此有這個疑問,感謝版主的回答。

      刪除
  2. 请问一下,可以直接在weka上进行预测而不是在cmd里吗?

    回覆刪除
    回覆
    1. 這真是一個困難的問題。也許可以看一看這人寫的其他文章,或許可以得到一些啟發:

      分類與預測:貝氏網路
      http://blog.pulipuli.info/2017/10/classification-and-prediction-bayesnet.html

      M5P:預測非線性連續資料的樹狀迴歸演算法
      http://blog.pulipuli.info/2017/11/m5p-m5p-trees-with-linear-models-in-weka.html

      不深度學習也不用寫程式的圖片辨識:用Weka實作MNIST手寫數字辨識
      http://blog.pulipuli.info/2017/06/wekamnist-mnist-digits-classification.html

      幫你選擇分類器的分類器:Auto-WEKA
      http://blog.pulipuli.info/2017/04/auto-weka-automatic-model-selection-and.html

      刪除