首页 > 代码库 > Spark机器学习(5):SVM算法

Spark机器学习(5):SVM算法

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.SVMWithSGDimport org.apache.spark.mllib.util.MLUtilsobject 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)  }}

运行结果:

技术分享

Spark机器学习(5):SVM算法