大数据进阶必修课!Spark实战支持向量机SVM算法

4.SparkMLlib 支持向量机SVM算法

4.1 支持向量机算法

支持向量机是数据挖掘中一个很经典的算法,因为其推导过程涉及很多数学概念且其核函数的变化,在此将用尽量通俗的语言来描述这一算法,从其功能性出发进行讲解。支持向量机不仅对分类问题有良好的处理效果,对回归问题也有很好的解决方案。
SVM分类器可以在样本空间中对属于不同类别的样本进行区分,用来作为区分的分隔面就是分隔超平面。对于一个SVM算法,输入带有标签的训练样本,输出的是一个最好的分隔超平面。如下图所示:

在这里插入图片描述

这是一个二维平面上属于两个类别上的点,我们试图寻找一条直线进行分隔,可以发现有很多条直线满足要求。但是一条直线如果距离样本太近,会对数据中的噪声敏感性高,就会导致泛化能力下降,所以我们的目标是找到一条尽可能远离所有样本点的直线。
支持向量机的实质就是找出一个分隔超平面使得该超平面距离所有训练样本(这里的点可以简化为是离超平面最近的点)的最小距离在所有分隔面中是最大的,这个最小距离叫做间隔margin,这些距离超平面最近的点叫做支持向量,该超平面也就是最优超平面。

在这里插入图片描述

如上图所示,我们的目标就是在超平面将所有样本正确分类的前提下,求出这个最优超平面的margin,然后最大化这个margin。这个问题可以转化为一个拉格朗日优化问题,可以使用拉格朗日乘数法得到最优超平面的相关参数。这里就不再赘述正面过程。此外svm还可以通过改变核函数,将原始空间线性不可分的数据映射到高维空间变成线性可分的。

4.2 算法源码分析

在MLlib中,实现了线性SVM分类模型,使用随机梯度下降算法来优化目标函数。其实现过程如下:
(1)SVMWtihSGD:SVM线性分类伴生对象:基于随机梯度下降,含有train静态方法,设置SVM分类参数创建SVM分类,执行run方法训练模型,train方法主要参数如下:

  • input——训练样本格式为RDD(label,features)
  • numIterations——运行的迭代次数,默认100
  • stepSize——每次迭代的步长,默认1
  • miniBatchFraction——每次迭代参与计算的样本比例,默认1
  • initialWeights——初始化权重

(2)SVMWithSGD类:SVM线性分类,包含run方法,先对样本加偏置再初始化权重,最后用optimizer.optimize方法计算优化权重从而获取最优权重;
(3)runMiniBatchSGD:优化计算权重:根据训练样本迭代计算随机梯度从而得到最优权重,每次迭代计算样本梯度并更新,分别使用gradient.compute和updater.compute方法;
(4)SVMModel:SVM线性分类模型,含有predict方法,根据分类模型计算样本预测值,返回RDD[double]。

4.3 应用实战

4.3.1 数据说明

此次实战使用sample_libsvm_data样本数据。

4.3.2 代码详解

//导入需要的包文件
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.mllib.classification.{SVMModel, SVMWithSGD}
import org.apache.spark.mllib.evaluation.BinaryClassificationMetrics
import org.apache.spark.mllib.util.MLUtils

//构建Spark对象
val conf = new SparkConf().setAppName("SVM")
val sc = new SparkContext(conf)

//读取样本数据
val data = MLUtils.loadLibSVMFile(sc, "/mnt/hgfs/thunder-
download/MLlib_rep/data/sample_libsvm_data.txt")

//对样本数据划分为训练与测试样本,比例为6:4
val splits = data.randomSplit(Array(0.6, 0.4), seed = 11L)

//训练样本
val training = splits(0).cache()
输出结果:
training: org.apache.spark.rdd.RDD[org.apache.spark.mllib.regression.LabeledPoint] = MapPartitionsRDD[112] at randomSplit at <console>:37

//测试样本
val test = splits(1)

输出结果:

test: org.apache.spark.rdd.RDD[org.apache.spark.mllib.regression.LabeledPoint] = MapPartitionsRDD[113] at randomSplit at <console>:37
//配置训练参数
val numIterations = 100
输出结果:numIterations: Int = 100

//训练模型
val model = SVMWithSGD.train(training, numIterations)

输出结果:

model: org.apache.spark.mllib.classification.SVMModel = 
org.apache.spark.mllib.classification.SVMModel: intercept = 0.0, numFeatures = 692, numClasses = 2, threshold = 0.0

//对测试样本进行预测
val scoreAndLabels = test.map { point =>
     | val score = model.predict(point.features)
     | (score, point.label)
     | }

输出结果:

scoreAndLabels: org.apache.spark.rdd.RDD[(Double, Double)] = 
MapPartitionsRDD[317] at map at <console>:47

返回数据类型RDD

//计算误差
val metrics = new BinaryClassificationMetrics(scoreAndLabels)
val auROC = metrics.areaUnderROC()
println("Area under ROC = " + auROC)

输出结果:

Area under ROC = 1.0

分类精度1.0

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值