1. SVM基本知識 SVM(Support Vector Machine)是一個類分類器,能夠將不同類的樣本在樣本空間中進行分隔,分隔使用的面叫做分隔超平面。 比如對於二維樣本,分佈在二維平面上,此時超平面實際上是一條直線,直線上面是一類,下麵是另一類。定義超平面為: f(x)=w0+wTx 可以 ...
1. SVM基本知識
SVM(Support Vector Machine)是一個類分類器,能夠將不同類的樣本在樣本空間中進行分隔,分隔使用的面叫做分隔超平面。
比如對於二維樣本,分佈在二維平面上,此時超平面實際上是一條直線,直線上面是一類,下麵是另一類。定義超平面為:
f(x)=w0+wTx
可以想象出,這樣的直線可以有很多條,到底哪一條是超平面呢?規定超平面應該是距離兩類的最近距離之和最大,因為只有這樣才是最優的分類。
假設超平面是w0+wTx=0,那麼經過上面這一類距離超平面最近點的直線是w0+wTx=1,下麵的直線是w0+wTx=-1。其中一類到超平面的距離是
然後採用拉格朗日函數,經過一系列運算以後,得到
這也意味著,只用計算新點x與訓練數據點的內積就可以對新點進行預測。
2. MLlib的SVM
MLlib只實現了線性SVM,採用分散式隨機梯度下降演算法。將SVM二分類的1和-1轉化為1和0,因此y變成了(2y-1),梯度為g=-(2y-1)x,梯度更新公式
直接上代碼:
import org.apache.log4j.{ Level, Logger } import org.apache.spark.{ SparkConf, SparkContext } import org.apache.spark.mllib.classification.SVMWithSGD import org.apache.spark.mllib.util.MLUtils object SVMTest { def main(args: Array[String]): Unit = { // 設置運行環境 val conf = new SparkConf().setAppName("SVM Test") .setMaster("spark://master:7077").setJars(Seq("E:\\Intellij\\Projects\\MachineLearning\\MachineLearning.jar")) val sc = new SparkContext(conf) Logger.getRootLogger.setLevel(Level.WARN) // 讀取樣本數據並解析 val dataRDD = MLUtils.loadLibSVMFile(sc, "hdfs://master:9000/ml/data/sample_svm_data.txt") // 樣本數據劃分,訓練樣本占0.8,測試樣本占0.2 val dataParts = dataRDD.randomSplit(Array(0.8, 0.2)) val trainRDD = dataParts(0) val testRDD = dataParts(1) // 建立模型並訓練 val numIterations = 100 val model = SVMWithSGD.train(trainRDD, numIterations) // 對測試樣本進行測試 val predictionAndLabel = testRDD.map { point => val score = model.predict(point.features) (score, point.label, point.features) } val showPredict = predictionAndLabel.take(50) println("Prediction" + "\t" + "Label" + "\t" + "Data") for (i <- 0 to showPredict.length - 1) { println(showPredict(i)._1 + "\t" + showPredict(i)._2 + "\t" + showPredict(i)._3) } // 誤差計算 val accuracy = 1.0 * predictionAndLabel.filter(x => x._1 == x._2).count() / testRDD.count() println("Accuracy = " + accuracy) } }
運行結果: