Java实现简单版SVM

最近的图像分类工作要用到latent svm,为了更加深入了解svm,自己动手实现一个简单版的。

之所以说是简单版,因为没有用到拉格朗日,对偶,核函数等等。而是用最简单的梯度下降法求解。其中的数学原理我参考了http://blog.csdn.net/lifeitengup/article/details/10951655,文中是用matlab实现的svm。

源代码和数据集下载:https://github.com/linger2012/simpleSvm

其中数据集来自于libsvm,我找了其中一个数据集http://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/binary/breast-cancer_scale。

将她分成两部分,训练集和测试集,对应于train_bc和test_bc。

其中测试结果如下:

package com.linger.svm;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.StringTokenizer;

public class SimpleSvm
{
	private int exampleNum;
	private int exampleDim;
	private double[] w;
	private double lambda;
	private double lr = 0.001;//0.00001
	private double threshold = 0.001;
	private double cost;
	private double[] grad;
	private double[] yp;
	public SimpleSvm(double paramLambda)
	{

		lambda = paramLambda;	

	}

	private void CostAndGrad(double[][] X,double[] y)
	{
		cost =0;
		for(int m=0;m<exampleNum;m++)
		{
			yp[m]=0;
			for(int d=0;d<exampleDim;d++)
			{
				yp[m]+=X[m][d]*w[d];
			}

			if(y[m]*yp[m]-1<0)
			{
				cost += (1-y[m]*yp[m]);
			}

		}

		for(int d=0;d<exampleDim;d++)
		{
			cost += 0.5*lambda*w[d]*w[d];
		}

		for(int d=0;d<exampleDim;d++)
		{
			grad[d] = Math.abs(lambda*w[d]);
			for(int m=0;m<exampleNum;m++)
			{
				if(y[m]*yp[m]-1<0)
				{
					grad[d]-= y[m]*X[m][d];
				}
			}
		}
	}

	private void update()
	{
		for(int d=0;d<exampleDim;d++)
		{
			w[d] -= lr*grad[d];
		}
	}

	public void Train(double[][] X,double[] y,int maxIters)
	{
		exampleNum = X.length;
		if(exampleNum <=0)
		{
			System.out.println("num of example <=0!");
			return;
		}
		exampleDim = X[0].length;
		w = new double[exampleDim];
		grad = new double[exampleDim];
		yp = new double[exampleNum];

		for(int iter=0;iter<maxIters;iter++)
		{

			CostAndGrad(X,y);
			System.out.println("cost:"+cost);
			if(cost< threshold)
			{
				break;
			}
			update();

		}
	}
	private int predict(double[] x)
	{
		double pre=0;
		for(int j=0;j<x.length;j++)
		{
			pre+=x[j]*w[j];
		}
		if(pre >=0)//这个阈值一般位于-1到1
			return 1;
		else return -1;
	}

	public void Test(double[][] testX,double[] testY)
	{
		int error=0;
		for(int i=0;i<testX.length;i++)
		{
			if(predict(testX[i]) != testY[i])
			{
				error++;
			}
		}
		System.out.println("total:"+testX.length);
		System.out.println("error:"+error);
		System.out.println("error rate:"+((double)error/testX.length));
		System.out.println("acc rate:"+((double)(testX.length-error)/testX.length));
	}

	public static void loadData(double[][]X,double[] y,String trainFile) throws IOException
	{

		File file = new File(trainFile);
		RandomAccessFile raf = new RandomAccessFile(file,"r");
		StringTokenizer tokenizer,tokenizer2; 

		int index=0;
		while(true)
		{
			String line = raf.readLine();

			if(line == null) break;
			tokenizer = new StringTokenizer(line," ");
			y[index] = Double.parseDouble(tokenizer.nextToken());
			//System.out.println(y[index]);
			while(tokenizer.hasMoreTokens())
			{
				tokenizer2 = new StringTokenizer(tokenizer.nextToken(),":");
				int k = Integer.parseInt(tokenizer2.nextToken());
				double v = Double.parseDouble(tokenizer2.nextToken());
				X[index][k] = v;
				//System.out.println(k);
				//System.out.println(v);
			}
			X[index][0] =1;
			index++;
		}
	}

	public static void main(String[] args) throws IOException
	{
		// TODO Auto-generated method stub
		double[] y = new double[400];
		double[][] X = new double[400][11];
		String trainFile = "E:\\project\\workspace\\Algorithms\\bin\\train_bc";
		loadData(X,y,trainFile);

		SimpleSvm svm = new SimpleSvm(0.0001);
		svm.Train(X,y,7000);

		double[] test_y = new double[283];
		double[][] test_X = new double[283][11];
		String testFile = "E:\\project\\workspace\\Algorithms\\bin\\test_bc";
		loadData(test_X,test_y,testFile);
		svm.Test(test_X, test_y);

	}

}

本文作者:linger

本文链接:http://blog.csdn.net/lingerlanlan/article/details/38688539

Java实现简单版SVM,布布扣,bubuko.com

时间: 2024-12-30 13:48:06

Java实现简单版SVM的相关文章

基于java语言简单版的学生信息系统

功能简介: a:可以对学生信息增删改查, b:每一种操作都是使用容器进行 c:使用自己写的工具类,可以实现多次调用,实现代码的复用,增加可读性 d:语法使用嵌套循环,一般使用while,swich..case,for 代码实现: //测试类 package com.xinboedu.www.test; public class TestSystem { public static void main(String[] args) { StudentSystem studentSystem = n

基于《仙剑奇侠传柔情版》利用Java的简单实现(一)

基于<仙剑奇侠传柔情版>利用Java的简单实现(一) 2018-12-01 23:55:36   by Louis  一,新建一个类GameFrame.class,具体代码如下: package firstDemo; import javax.swing.JFrame; /** * 本类文件表示游戏案例的窗口类,也就是运行之后会呈现出一个游戏窗口 * 窗口大小1024*768像素:屏幕中间出现 * * @author Louis */ public class GameFrame { //主方

建造者模式(Java与Kotlin版)

前文推送 设计模式 简单工厂模式(Java与Kotlin版) 工厂方法模式(Java与Kotlin版) 抽象工厂模式(Java与Kotlin版) Kotlin基础知识 Kotlin入门第一课:从对比Java开始 Kotlin入门第二课:集合操作 Kotlin入门第三课:数据类型 初次尝试用Kotlin实现Android项目 1. 定义 建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 2. 结构 Product:产品角色:

工厂方法模式(Java与Kotlin版)

前文推送 设计模式 简单工厂模式(Java与Kotlin版) Kotlin基础知识 Kotlin入门第一课:从对比Java开始 Kotlin入门第二课:集合操作 Kotlin入门第三课:数据类型 初次尝试用Kotlin实现Android项目 1. 定义 工厂方法模式(Factory Method Pattern)又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,它属于类创建型模式.在工厂方法模式中,工厂父类负责

抽象工厂模式(Java与Kotlin版)

前文推送 设计模式 简单工厂模式(Java与Kotlin版) 工厂方法模式(Java与Kotlin版) Kotlin基础知识 Kotlin入门第一课:从对比Java开始 Kotlin入门第二课:集合操作 Kotlin入门第三课:数据类型 初次尝试用Kotlin实现Android项目 1. 定义 抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类.抽象工厂模式又称为Kit模式,属于对象创建型模式. 2. 结构 Abs

JavaMail简单版实验测试

前言: 最近由于实现web商城的自动发送邮件功能的需求,故涉猎的邮箱协议的内部原理.现将简单版的Java Mail实例做个代码展示,并附上其中可能出现的bug贴出,方便感兴趣的读者进行测试! 1.载入相关jar包 客户端传输邮件需要用的jar包:activation.jar和mail.jar (下载:https://github.com/SeaSky0606/share) 2.JavaMail代码实现 1 package com.seasky.mail; 2 3 import java.util

寿星天文历Java封装整理版

由于生活和工作的原因,"寿星天文历"我一直没有动,长时间的丢弃后,当重新拾起时,比较费劲.编程就是这样,思维的火花只在当初的那一瞬,一旦熄灭,重新再点燃断掉的思维是很困难的.因为人的"忘记"能力,真的是挺强的,有时回顾或维护以前的代码时,常常会感叹道:这是我写的吗?够牛逼,看不懂!呵呵,这时候注释的作用的凸显出来了,尽管如此有时仅仅靠注释找以前的思路也是很困难. 跑题了,那么,首先对于等着"寿星天文历"封装整理版代码的各位,说声抱歉.这回整理的代

Head First Java(第2版)中文版pdf

下载地址:网盘下载 内容简介  · · · · · · <Head First Java>是本完整的面向对象(object-oriented,OO)程序设计和Java的学习指导.此书是根据学习理论所设计的,让你可以从学习程序语言的基础开始一直到包括线程.网络与分布式程序等项目.最重要的,你会学会如何像个面向对象开发者一样去思考. 而且不只是读死书,你还会玩游戏.拼图.解谜题以及以意想不到的方式与Java交互.在这些活动中,你会写出一堆真正的Java程序,包括了一个船舰炮战游戏和一个网络聊天程序

分享一个近期写的简单版的网页采集器

分享一个近期写的简单版的网页采集器 功能特点: 1.可通过配置,保存采集规则. 2.可通过采集规则,进行数据采集. 3.可分页,分关键字,进行采集. 4.可保存数据至数据库,文本中. ........... 功能还比较简单,喜欢深入的可以继续深入下去,暂时还没有登录的功能,因为登录功能涉及到的范围比较广,待日后慢慢研究后再开发. 我先上个图让大家一睹为快吧: 首先看看页面,我们要采集这个网站的文章 接下来,首先是查找分页,获得分页里面的文章链接,接着查找内容页需要采集的字段,生成规则,进行采集.