package libsvm;
import java.io.*;
import java.util.*;
//
// Kernel Cache
//
// l is the number of total data items
// size is the cache size limit in bytes
//
class Cache {
private final int l;
private long size;
private final class head_t
{
head_t prev, next; // a cicular list
float[] data;
int len; // data[0,len) is cached in this entry
}
private final head_t[] head;
private head_t lru_head;
Cache(int l_, long size_)
{
l = l_;
size = size_;
head = new head_t[l];
for(int i=0;i<l;i++) head[i] = new head_t();
size /= 4;
size -= l * (16/4); // sizeof(head_t) == 16
size = Math.max(size, 2* (long) l); // cache must be large enough for two columns
lru_head = new head_t();
lru_head.next = lru_head.prev = lru_head;
}
private void lru_delete(head_t h)
{
// delete from current location
h.prev.next = h.next;
h.next.prev = h.prev;
}
private void lru_insert(head_t h)
{
// insert to last position
h.next = lru_head;
h.prev = lru_head.prev;
h.prev.next = h;
h.next.prev = h;
}
// request data [0,len)
// return some position p where [p,len) need to be filled
// (p >= len if nothing needs to be filled)
// java: simulate pointer using single-element array
int get_data(int index, float[][] data, int len)
{
head_t h = head[index];
if(h.len > 0) lru_delete(h);
int more = len - h.len;
if(more > 0)
{
// free old space
while(size < more)
{
head_t old = lru_head.next;
lru_delete(old);
size += old.len;
old.data = null;
old.len = 0;
}
// allocate new space
float[] new_data = new float[len];
if(h.data != null) System.arraycopy(h.data,0,new_data,0,h.len);
h.data = new_data;
size -= more;
do {int tmp=h.len; h.len=len; len=tmp;} while(false);
}
lru_insert(h);
data[0] = h.data;
return len;
}
void swap_index(int i, int j)
{
if(i==j) return;
if(head[i].len > 0) lru_delete(head[i]);
if(head[j].len > 0) lru_delete(head[j]);
do {float[] tmp=head[i].data; head[i].data=head[j].data; head[j].data=tmp;} while(false);
do {int tmp=head[i].len; head[i].len=head[j].len; head[j].len=tmp;} while(false);
if(head[i].len > 0) lru_insert(head[i]);
if(head[j].len > 0) lru_insert(head[j]);
if(i>j) do {int tmp=i; i=j; j=tmp;} while(false);
for(head_t h = lru_head.next; h!=lru_head; h=h.next)
{
if(h.len > i)
{
if(h.len > j)
do {float tmp=h.data[i]; h.data[i]=h.data[j]; h.data[j]=tmp;} while(false);
else
{
// give up
lru_delete(h);
size += h.len;
h.data = null;
h.len = 0;
}
}
}
}
}
//
// Kernel evaluation
//
// the static method k_function is for doing single kernel evaluation
// the constructor of Kernel prepares to calculate the l*l kernel matrix
// the member function get_Q is for getting one column from the Q Matrix
//
abstract class QMatrix {
abstract float[] get_Q(int column, int len);
abstract double[] get_QD();
abstract void swap_index(int i, int j);
};
abstract class Kernel extends QMatrix {
private svm_node[][] x;
private final double[] x_square;
// svm_parameter
private final int kernel_type;
private final int degree;
private final double gamma;
private final double coef0;
abstract float[] get_Q(int column, int len);
abstract double[] get_QD();
void swap_index(int i, int j)
{
do {svm_node[] tmp=x[i]; x[i]=x[j]; x[j]=tmp;} while(false);
if(x_square != null) do {double tmp=x_square[i]; x_square[i]=x_square[j]; x_square[j]=tmp;} while(false);
}
private static double powi(double base, int times)
{
double tmp = base, ret = 1.0;
for(int t=times; t>0; t/=2)
{
if(t%2==1) ret*=tmp;
tmp = tmp * tmp;
}
return ret;
}
double kernel_function(int i, int j)
{
switch(kernel_type)
{
case svm_parameter.LINEAR:
return dot(x[i],x[j]);
case svm_parameter.POLY:
return powi(gamma*dot(x[i],x[j])+coef0,degree);
case svm_parameter.RBF:
return Math.exp(-gamma*(x_square[i]+x_square[j]-2*dot(x[i],x[j])));
case svm_parameter.SIGMOID:
return Math.tanh(gamma*dot(x[i],x[j])+coef0);
case svm_parameter.PRECOMPUTED:
return x[i][(int)(x[j][0].value)].value;
default:
return 0; // Unreachable
}
}
Kernel(int l, svm_node[][] x_, svm_parameter param)
{
this.kernel_type = param.kernel_type;
this.degree = param.degree;
this.gamma = param.gamma;
this.coef0 = param.coef0;
x = (svm_node[][])x_.clone();
if(kernel_type == svm_parameter.RBF)
{
x_square = new double[l];
for(int i=0;i<l;i++)
x_square[i] = dot(x[i],x[i]);
}
else
x_square = null;
}
static double dot(svm_node[] x, svm_node[] y)
{
double sum = 0;
int xlen = x.length;
int ylen = y.length;
int i = 0;
int j = 0;
while(i < xlen && j < ylen)
{
if(x[i].index == y[j].index)
sum += x[i++].value * y[j++].value;
else
{
if(x[i].index > y[j].index)
++j;
else
++i;
}
}
return sum;
}
static double k_function(svm_node[] x, svm_node[] y,
svm_parameter param)
{
switch(param.kernel_type)
{
case svm_parameter.LINEAR:
return dot(x,y);
case svm_parameter.POLY:
return powi(param.gamma*dot(x,y)+param.coef0,param.degree);
case svm_parameter.RBF:
{
double sum = 0;
int xlen = x.length;
int ylen = y.length;
int i = 0;
int j = 0;
while(i < xlen && j < ylen)
{
if(x[i].index == y[j].index)
{
double d = x[i++].value - y[j++].value;
sum += d*d;
}
else if(x[i].index > y[j].index)
{
sum += y[j].value * y[j].value;
++j;
}
else
{
sum += x[i].value * x[i].value;
++i;
}
}
while(i < xlen)
{
sum += x[i].value * x[i].value;
++i;
}
while(j < ylen)
{
sum += y[j].value * y[j].value;
++j;
}
return Math.exp(-param.gamma*sum);
}
case svm_parameter.SIGMOID:
return Math.tanh(param.gamma*dot(x,y)+param.coef0);
case svm_parameter.PRECOMPUTED: //x: test (validation), y: SV
return x[(int)(y[0].value)].value;
default:
return 0; // Unreachable
}
}
}
// An SMO algorithm in Fan et al., JMLR 6(2005), p. 1889--1918
// Solves:
//
// min 0.5(\alpha^T Q \alpha) + p^T \alpha
//
// y^T \alpha = \delta
// y_i = +1 or -1
// 0 <= alpha_i <= Cp for y_i = 1
// 0 <= alpha_i <= Cn for y_i = -1
//
// Given:
//
// Q, p, y, Cp, Cn, and an initial feasible point \alpha
// l is the size of vectors and matrices
// eps is the stopping tolerance
//
// solution will be put in \alpha, objective value will be put in obj
//
class Solver {
int active_size;
byte[] y;
double[] G; // gradient of objective function
static final byte LOWER_BOUND = 0;
static final byte UPPER_BOUND = 1;
static final byte FREE = 2;
byte[] alpha_status; // LOWER_BOUND, UPPER_BOUND, FREE
double[] alpha;
QMatrix Q;
double[] QD;
double eps;
double Cp,Cn;
double[] p;
int[] active_set;
double[] G_bar; // gradient, if we treat free variables as 0
int l;
boolean unshrink; // XXX
static final double INF = java.lang.Double.POSITIVE_INFINITY;
double get_C(int i)
{
return (y[i] > 0)? Cp : Cn;
}
void update_alpha_status(int i)
{
if(alpha[i] >= get_C(i))
alpha_status[i] = UPPER_BOUND;
else if(alpha[i] <= 0)
alpha_status[i] = LOWER_BOUND;
else alpha_status[i] = FREE;
}
boolean is_upper_bound(int i) { return alpha_status[i] == UPPER_BOUND; }
boolean is_lower_bound(int i) { return alpha_status[i] == LOWER_BOUND; }
boolean is_free(int i) { return alpha_status[i] == FREE; }
// java: information about solution except alpha,
// because we cannot return multiple values otherwise...
static class SolutionInfo {
double obj;
double rho;
double upper_bound_p;
double upper_bound_n;
double r; // for Solver_NU
}
void swap_index(int i, int j)
{
Q.swap_index(i,j);
do {byte tmp=y[i]; y[i]=y[j]; y[j]=tmp;} while(false);
do {double tmp=G[i]; G[i]=G[j]; G[j]=tmp;} while(false);
do {byte tmp=alpha_status[i]; alpha_status[i
libsvm工具箱的压缩包
需积分: 0 13 浏览量
更新于2023-02-16
收藏 906KB ZIP 举报
**libsvm工具箱详解**
LibSVM,全称为“Library for Support Vector Machines”,是由台湾大学的Chih-Chung Chang和Chih-Jen Lin开发的一款开源软件,主要用于支持向量机(SVM)的学习与预测。它不仅适用于MATLAB环境,还提供了C、Java、Python等多种语言的接口,方便在各种平台上进行机器学习任务。
### LibSVM的核心功能
1. **支持向量机算法**: SVM是一种监督学习模型,特别适用于分类和回归问题。LibSVM实现了软间隔和核函数的SVM,如线性核、多项式核、高斯核(RBF)等,能够处理非线性数据。
2. **高效优化**: LibSVM采用内核技巧和 Cutting Plane Algorithm(切平面算法)或Sequential Minimal Optimization(序列最小优化)来求解SVM的对偶问题,保证了训练过程的效率。
3. **多类分类**: LibSVM支持一对一和一对多的多类分类策略,能够处理超过两个类别的分类任务。
4. **网格搜索**: 提供参数调优工具,通过交叉验证和网格搜索方法,自动寻找最佳的参数组合(如C值和γ值),以提高模型性能。
### 使用LibSVM在MATLAB中的操作
在MATLAB环境中,你可以按照以下步骤使用LibSVM:
1. **下载与解压**: 从官方网站下载libsvm的MATLAB接口,解压后得到的`libsvm-master`目录包含了必要的函数文件。
2. **配置路径**: 将`libsvm-master`目录添加到MATLAB的搜索路径中,以便MATLAB能识别相关的.m文件。
3. **加载数据**: 准备训练数据,通常为数值型的二维矩阵,其中每行代表一个样本,每列代表一个特征。对于分类问题,最后一列应为类别标签。
4. **预处理数据**: 对数据进行必要的预处理,如归一化、标准化等,以减少特征之间的尺度差异。
5. **选择参数**: 根据问题类型和数据特性,设置SVM的参数,如惩罚系数C和核函数参数γ。
6. **训练模型**: 使用`svmtrain`函数训练SVM模型。例如:
```matlab
model = svmtrain(trainData, trainLabels, 'Kernel', 'linear', 'BoxConstraint', C);
```
7. **测试模型**: 使用`svmpredict`函数对测试数据进行预测。例如:
```matlab
predictedLabels = svmpredict(testLabels, testData, model);
```
8. **评估性能**: 计算预测结果的准确率、精确率、召回率、F1分数等指标,以评估模型性能。
9. **网格搜索优化**: 可以使用`grid.py`脚本进行参数网格搜索,以找到最优的参数组合。
10. **保存与加载模型**: 通过`save`和`load`函数保存和加载训练好的模型,方便后续使用。
### 应用示例
在实际应用中,LibSVM常用于文本分类、图像识别、生物信息学等领域。例如,在文本分类中,可以将文档转换为TF-IDF向量,然后用LibSVM训练一个分类器,以识别新的文档主题。
LibSVM作为一款强大的SVM工具箱,因其高效和易用性在学术界和工业界得到了广泛应用。了解其核心原理和使用方法,对于理解和实践机器学习具有重要意义。

9595105
- 粉丝: 0
- 资源: 2
最新资源
- 管家婆普及版TOP9.16.zip
- ObjectARX 2025
- 电动汽车动力系统匹配与整车动力经济性计算模型:参数输入一键生成,仿真模型助力项目实践,电动汽车动力系统匹配与整车动力经济性计算模型:一键生成参数,助力高效研发仿真设计,电动汽车动力系统匹配计算模型:输
- 管家婆普及版TOP15.0.zip
- JellySprites
- chap1threading1.py
- 管家婆普及版TOP12.6.zip
- 一个随机随林的演示代码
- Deepseek使用提问公式-全是技巧
- A02114237余瑶开题报告.docx
- GESP 2024年12月认证 Python 1-6级真题和答案.rar
- 计算机软考备战指南-备考攻略详解与成功秘籍
- 管家婆普普版TOP 12.9.zip
- 管家婆普普版TOP 12.71.zip
- 管家婆普普版TOP 12.6.zip
- 【matlab代码】四个模型的IMM(交互式多模型)例程,四模型分别为:CV(匀速)、CA(匀加速)、CS(匀加加速度)、CT(匀速转弯),滤波使用EKF