参考资料:http://www.cppblog.com/sunrise/archive/2012/08/06/186474.html                       http://blog.csdn.net/sunanger_wang/article/details/7887218

我的数据挖掘算法代码:https://github.com/linyiqun/DataMiningAlgorithm

介绍

svm(support vector machine)是一种用来进行模式识别,模式分类的机器学习算法。svm的主要思想可以概括为2点:(1)、针对线性可分情况进行分析。(2)、对于线性不可分的情况,通过使用核函数,将低维线性不可分空间转化为高维线性可分的情况,然后在进行分析。目前已经有实现好的svm的算法包,在本文的后半部分会给出我实现好的基于libsvm包的svm分类代码。

SVM算法原理

svm算法的具体原理得要分成2部分,一个是线性可分的情况,一个是线性不可分的情况,下面说说线性可分的情况:

线性可分的情况

下面是一个二维空间的形式:

中间的那条线就是划分的分割线,我们可以用f(X)=w*x+b,  w,x在这里都是向量的形式。向这样的分割线,只要稍稍移动一下,又会有一个正确的目标线,因此我们要找的一个目标解,当然是找出分割的临界条件。

比如上面所示的情况,最佳的分类情况,应该是上面的margin的大小最大的时候,保证了分类的最准确。这里省去了一些数学的推理证明。要使用下面这个最大化:

反过来说,就是要使分母位置最小:

就是让||w||最小,当然这里会有个限制条件,就是这个线的应该有分类的作用,也就是说,样本数据代入公式,至少会有分类,于是限制条件就来了:

s.t的意思是subject to,也就是在后面这个限制条件。这就是问题的最终表达形式。后面这个式子会经过一系列的转换,最终变成这个样子:

这个就是我们需要最终优化的式子。至此,得到了线性可分问题的优化式子。如果此时你问我如何去解这个问题,很抱歉的告诉你,我也不知道(悔恨当初高数没学好....)

线性不可分的情况

同样给出一张图:

我们只能找出这样的条曲线将ab这个条线段进行分割。这时,就用到了在开始部分介绍的4个核函数。

选择不同的核函数,可以生成不同的SVM,常用的核函数有以下4种:
⑴线性核函数K(x,y)=x·y;
⑵多项式核函数K(x,y)=[(x·y)+1]^d;
⑶径向基函数K(x,y)=exp(-|x-y|^2/d^2)
⑷二层神经网络核函数K(x,y)=tanh(a(x·y)+b)

但是在有的时候为了数据的容错性和准确性,我们会加入惩罚因子C和ε阈值(保证容错性)

限制条件为:

上面为线性可分的情况,不可分的情况可通过核函数自动转为线性可分情况。在整个过程中,省去了主要的推理过程,详细的可以点击最上方提供的2个链接。

svm的算法实现

这里提供我利用libsvm库做一个模式分类。主要的过程为:

1、输入训练集数据。

2、提供训练集数据构建svm_problem参数。

3、设定svm_param参数中的svm类型和核函数类型。

4、通过svm_problem和svm_param构建分类模型model。

5、最后通过模型和测试数据输出预测值。

SVMTool工具类代码:

package DataMining_SVM;import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;import DataMining_SVM.libsvm.svm;
import DataMining_SVM.libsvm.svm_model;
import DataMining_SVM.libsvm.svm_node;
import DataMining_SVM.libsvm.svm_parameter;
import DataMining_SVM.libsvm.svm_problem;/*** SVM支持向量机工具类* * @author lyq* */
public class SVMTool {// 训练集数据文件路径private String trainDataPath;// svm_problem对象,用于构造svm model模型private svm_problem sProblem;// svm参数,里面有svm支持向量机的类型和不同 的svm的核函数类型private svm_parameter sParam;public SVMTool(String trainDataPath) {this.trainDataPath = trainDataPath;// 初始化svm相关变量sProblem = initSvmProblem();sParam = initSvmParam();}/*** 初始化操作,根据训练集数据构造分类模型*/private void initOperation(){}/*** svm_problem对象,训练集数据的相关信息配置* * @return*/private svm_problem initSvmProblem() {List<Double> label = new ArrayList<Double>();List<svm_node[]> nodeSet = new ArrayList<svm_node[]>();getData(nodeSet, label, trainDataPath);int dataRange = nodeSet.get(0).length;svm_node[][] datas = new svm_node[nodeSet.size()][dataRange]; // 训练集的向量表for (int i = 0; i < datas.length; i++) {for (int j = 0; j < dataRange; j++) {datas[i][j] = nodeSet.get(i)[j];}}double[] lables = new double[label.size()]; // a,b 对应的lablefor (int i = 0; i < lables.length; i++) {lables[i] = label.get(i);}// 定义svm_problem对象svm_problem problem = new svm_problem();problem.l = nodeSet.size(); // 向量个数problem.x = datas; // 训练集向量表problem.y = lables; // 对应的lable数组return problem;}/*** 初始化svm支持向量机的参数,包括svm的类型和核函数的类型* * @return*/private svm_parameter initSvmParam() {// 定义svm_parameter对象svm_parameter param = new svm_parameter();param.svm_type = svm_parameter.EPSILON_SVR;// 设置svm的核函数类型为线型param.kernel_type = svm_parameter.LINEAR;// 后面的参数配置只针对训练集的数据param.cache_size = 100;param.eps = 0.00001;param.C = 1.9;return param;}/*** 通过svm方式预测数据的类型* * @param testDataPath*/public void svmPredictData(String testDataPath) {// 获取测试数据List<Double> testlabel = new ArrayList<Double>();List<svm_node[]> testnodeSet = new ArrayList<svm_node[]>();getData(testnodeSet, testlabel, testDataPath);int dataRange = testnodeSet.get(0).length;svm_node[][] testdatas = new svm_node[testnodeSet.size()][dataRange]; // 训练集的向量表for (int i = 0; i < testdatas.length; i++) {for (int j = 0; j < dataRange; j++) {testdatas[i][j] = testnodeSet.get(i)[j];}}// 测试数据的真实值,在后面将会与svm的预测值做比较double[] testlables = new double[testlabel.size()]; // a,b 对应的lablefor (int i = 0; i < testlables.length; i++) {testlables[i] = testlabel.get(i);}// 如果参数没有问题,则svm.svm_check_parameter()函数返回null,否则返回error描述。// 对svm的配置参数叫验证,因为有些参数只针对部分的支持向量机的类型System.out.println(svm.svm_check_parameter(sProblem, sParam));System.out.println("------------检验参数-----------");// 训练SVM分类模型svm_model model = svm.svm_train(sProblem, sParam);// 预测测试数据的labledouble err = 0.0;for (int i = 0; i < testdatas.length; i++) {double truevalue = testlables[i];// 测试数据真实值System.out.print(truevalue + " ");double predictValue = svm.svm_predict(model, testdatas[i]);// 测试数据预测值System.out.println(predictValue);}}/*** 从文件中获取数据* * @param nodeSet*            向量节点* @param label*            节点值类型值* @param filename*            数据文件地址*/private void getData(List<svm_node[]> nodeSet, List<Double> label,String filename) {try {FileReader fr = new FileReader(new File(filename));BufferedReader br = new BufferedReader(fr);String line = null;while ((line = br.readLine()) != null) {String[] datas = line.split(",");svm_node[] vector = new svm_node[datas.length - 1];for (int i = 0; i < datas.length - 1; i++) {svm_node node = new svm_node();node.index = i + 1;node.value = Double.parseDouble(datas[i]);vector[i] = node;}nodeSet.add(vector);double lablevalue = Double.parseDouble(datas[datas.length - 1]);label.add(lablevalue);}} catch (Exception e) {e.printStackTrace();}}}

调用类:

/*** SVM支持向量机场景调用类* @author lyq**/
public class Client {public static void main(String[] args){//训练集数据文件路径String trainDataPath = "C:\\Users\\lyq\\Desktop\\icon\\trainInput.txt";//测试数据文件路径String testDataPath = "C:\\Users\\lyq\\Desktop\\icon\\testInput.txt";SVMTool tool = new SVMTool(trainDataPath);//对测试数据进行svm支持向量机分类tool.svmPredictData(testDataPath);}}

输入文件的内容:

训练集数据trainInput.txt:

17.6,17.7,17.7,17.7,17.8
17.7,17.7,17.7,17.8,17.8
17.7,17.7,17.8,17.8,17.9
17.7,17.8,17.8,17.9,18
17.8,17.8,17.9,18,18.1
17.8,17.9,18,18.1,18.2
17.9,18,18.1,18.2,18.4
18,18.1,18.2,18.4,18.6
18.1,18.2,18.4,18.6,18.7
18.2,18.4,18.6,18.7,18.9
18.4,18.6,18.7,18.9,19.1
18.6,18.7,18.9,19.1,19.3

测试数据集testInput.txt:

18.7,18.9,19.1,19.3,19.6
18.9,19.1,19.3,19.6,19.9
19.1,19.3,19.6,19.9,20.2
19.3,19.6,19.9,20.2,20.6
19.6,19.9,20.2,20.6,21
19.9,20.2,20.6,21,21.5
20.2,20.6,21,21.5,22

输出为:

null
------------检验参数-----------
..................*
optimization finished, #iter = 452
nu = 0.8563102916247203
obj = -0.8743284941628513, rho = 3.4446523008525705
nSV = 12, nBSV = 9
19.6 19.55027201691905
19.9 19.8455473606175
20.2 20.175593628188604
20.6 20.54041081963737
21.0 20.955769858833488
21.5 21.405899821905447
22.0 21.94590866154817

SVM支持向量机算法相关推荐

  1. SVM支持向量机算法做预测,matlab,预测精度非常高

    SVM支持向量机算法做预测,matlab,预测精度非常高! 预测结果评价指标: RMSE = 179.6986 MSE = 32291.5755 MAE = 108.5571 MAPE = 0.035 ...

  2. SVM 支持向量机算法(Support Vector Machine )【Python机器学习系列(十四)】

    SVM 支持向量机算法(Support Vector Machine )[Python机器学习系列(十四)] 文章目录 1.SVM简介 2. SVM 逻辑推导 2.1 Part1 化简限制条件 2.2 ...

  3. 【Python机器学习】之 SVM 支持向量机算法(二)

    SVM 支持向量机(二) 1.支持向量机 ​ 这样,由于w,x\mathbf{w,x}w,x初始值的不同,最后得到的分割超平面也有可能不同,那么一定存在一个最优的超平面,这种方法就是支持向量机. ​ ...

  4. 支持向量机python代码_Python机器学习SVM支持向量机算法理论 | kTWO-个人博客

    PS:这篇文章讲的是SVM的算法的基础理论知识,因为博主也是刚学习没多久,对SVM的数学思想了解的不是很深,所以这篇文章就简单介绍一下什么是SVM以及SVM是怎么工作的. 1.什么是支持向量机(SVM ...

  5. 详解SVM支持向量机算法(四:坐标上升和SMO算法)

    作者:RayChiu_Labloy 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 目录 背景 坐标上升算法 定义 过程 举个求解的栗子 基于坐标上升的SMO算法 SMO ...

  6. 详解SVM支持向量机算法(一:感知器和SVM的优点)

    作者:RayChiu_Labloy 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 目录 了解线性和非线性 线性分类模型-感知器 感知器的算法思想: 分类超平面 回顾逻辑 ...

  7. SVM支持向量机算法介绍

    如果你是一名模式识别专业的研究生,又或者你是机器学习爱好者,SVM是一个你避不开的问题.如果你只是有一堆数据需要SVM帮你处理一下,那么无论是Matlab的SVM工具箱,LIBSVM还是python框 ...

  8. SVM 支持向量机算法原理(详细总结)和python代码实现

    支持向量机是由Vapnik等人于1995年提出来的,是被公认的比较优秀的分类模型,逐渐受到了各领域研究者的关注. 支持向量机的基本模型是定义在特征空间上的间隔最大的线性分类器,间隔最大化使它有别于感知 ...

  9. SVM SMO算法代码详细剖析

    前言 一:本文要结合SVM理论部分来看即笔者另一篇: SVM原理从头到尾详细推导 二:有了理论部分下面就是直接代码啦,本文用四部分进行介绍:最简版的SMO,改进版platt SMO,核函数,sklea ...

最新文章

  1. linux中sh基本语法
  2. python常用函数-Python小白必备的8个最常用的内置函数(推荐)
  3. Fread 和fwrite的参数不同,返回值不同
  4. apache camel_Apache Camel的性能调整思路
  5. 第三代英特尔至强可扩展处理器,英特尔数据中心的“芯法宝”
  6. PHP_正则_获取图片所有属性
  7. nginx 1.16 配置反向代理,http,https,ssl
  8. hibernate中java类的成员变量类型如何映射到SQL中的数据类型变化
  9. mysql中CONCAT值为空的问题解决办法
  10. js判断字符在另一个字符串中出现次数
  11. resin mysql_nginx+resin+mysql实现session共享
  12. opengl 纹理贴到对应的位置_OpenGL常用命令备忘录(Part B)
  13. 一个学习PCI Express的 不错去处
  14. 卡尔曼滤波算法推导及MATLAB实现
  15. 2021年图扑软件重点事件回顾
  16. 三星 android 调试模式设置,三星galaxy s4 usb调试在哪里 s4 usb调试模式设置方法详解...
  17. T216909 小卡与质数2 (前缀和 欧拉筛
  18. August 16th Thursday (八月 十四日 木曜日)
  19. 图片压缩网址和工具---TinyPNG
  20. 小米 11 ultra旗舰版官方原版ROM系统MIUI13所有固件

热门文章

  1. MySQL基础知识-MySQL概述安装,单表增删改查,函数,约束,多表查询,事物
  2. 小白学GAN系列2——nn.ReLU与nn.LeakyReLU的区别
  3. 修改数据库的名字和表名
  4. 招聘管理系统软件java源码_基于Spring Boot的java开源招聘源码-铭阳招聘管理系统...
  5. npm scripts
  6. C语言中-含义,比如说 p=p-next
  7. rasa.exceptions.ModelNotFound: No NLU or Core data for unpacked model at:
  8. AJAX学习笔记——发送AJAX的POST请求,模拟from表单提交
  9. MySQL修改密码(三种方法示例)
  10. 概率统计-方差与正态分布(高斯分布)