分类和回归(二)-SVMs(支持向量机)

来源:互联网 发布:怎么做网络课程 编辑:程序博客网 时间:2024/05/16 12:02
线性支持向量机

1 介绍

线性支持向量机是一个用于大规模分类任务的标准方法。它的目标函数线性模型中的公式(1)。它的损失函数是海格损失,如下所示:

702976.png
默认情况下,线性支持向量机训练时使用L2正则化。线性支持向量机输出一个SVM模型。给定一个新的数据点x,模型通过w^Tx的值预测,当这个值大于0时,输出为正,否则输出为负。

线性支持向量机并不需要该函数,要详细了解支持向量机,请参考文献【1】

2  代码解析

2.1  实例

importorg.apache.spark.mllib.classification.{SVMModel, SVMWithSGD}importorg.apache.spark.mllib.evaluation.BinaryClassificationMetricsimportorg.apache.spark.mllib.util.MLUtils// Load training data in LIBSVM format.valdata=MLUtils.loadLibSVMFile(sc, "data/mllib/sample_libsvm_data.txt")// Split data into training (60%) and test (40%).valsplits= data.randomSplit(Array(0.6, 0.4), seed =11L)valtraining= splits(0).cache()valtest= splits(1)// Run training algorithm to build the modelvalnumIterations=100valmodel=SVMWithSGD.train(training, numIterations)// Clear the default threshold.model.clearThreshold()// Compute raw scores on the test set.valscoreAndLabels= test.map { point =>valscore= model.predict(point.features)  (score, point.label)}// Get evaluation metrics.valmetrics=newBinaryClassificationMetrics(scoreAndLabels)valauROC= metrics.areaUnderROC()println("Area under ROC = "+ auROC)

2.2  训练

和逻辑回归一样,训练过程均使用GeneralizedLinearModel中的run训练,只是训练使用的Gradient和Updater不同。在线性支持向量机中,使用HingeGradient计算梯度,使用SquaredL2Updater进行更新。 它的实现过程分为4步。参加逻辑回归了解这五步的详细情况。我们只需要了解HingeGradient和SquaredL2Updater的实现。

classHingeGradientextendsGradient {  overridedefcompute(data: Vector, label: Double, weights: Vector): (Vector, Double) = {    valdotProduct= dot(data, weights)    // 我们的损失函数是 max(0, 1 - (2y - 1) (f_w(x)))// 所以梯度是 -(2y - 1)*xvallabelScaled=2* label -1.0if (1.0> labelScaled * dotProduct) {      valgradient= data.copy      scal(-labelScaled, gradient)      (gradient, 1.0- labelScaled * dotProduct)    } else {      (Vectors.sparse(weights.size, Array.empty, Array.empty), 0.0)    }  }  overridedefcompute(      data: Vector,      label: Double,      weights: Vector,      cumGradient: Vector):Double= {    valdotProduct= dot(data, weights)    // 我们的损失函数是 max(0, 1 - (2y - 1) (f_w(x)))// 所以梯度是 -(2y - 1)*xvallabelScaled=2* label -1.0if (1.0> labelScaled * dotProduct) {      //cumGradient -= labelScaled * data      axpy(-labelScaled, data, cumGradient)      //损失值1.0- labelScaled * dotProduct    } else {      0.0    }  }}

线性支持向量机的训练使用L2正则化方法。

classSquaredL2UpdaterextendsUpdater {  overridedefcompute(      weightsOld: Vector,      gradient: Vector,      stepSize: Double,      iter: Int,      regParam: Double): (Vector, Double) = {    // w' = w - thisIterStepSize * (gradient + regParam * w)// w' = (1 - thisIterStepSize * regParam) * w - thisIterStepSize * gradient//表示步长,即负梯度方向的大小valthisIterStepSize= stepSize / math.sqrt(iter)    valbrzWeights:BV[Double] = weightsOld.toBreeze.toDenseVector    //正则化,brzWeights每行数据均乘以(1.0 - thisIterStepSize * regParam)    brzWeights :*= (1.0- thisIterStepSize * regParam)    //y += x * a,即brzWeights -= gradient * thisInterStepSize    brzAxpy(-thisIterStepSize, gradient.toBreeze, brzWeights)    //正则化||w||_2valnorm= brzNorm(brzWeights, 2.0)    (Vectors.fromBreeze(brzWeights), 0.5* regParam * norm * norm)  }}

该函数的实现规则是:
w' = w - thisIterStepSize * (gradient + regParam * w)w'= (1- thisIterStepSize * regParam) * w - thisIterStepSize * gradient

2.3  预测

overrideprotecteddefpredictPoint(      dataMatrix: Vector,      weightMatrix: Vector,      intercept: Double) = {    //w^Txvalmargin= weightMatrix.toBreeze.dot(dataMatrix.toBreeze) + intercept    threshold match {      caseSome(t) =>if (margin > t) 1.0else0.0caseNone=> margin    }  }


参考文献

【1】支持向量机通俗导论(理解SVM的三层境界)
原创粉丝点击