介绍
LibSVM 是一个广泛使用的开源库,用于支持向量机(SVM)的实现。它由台湾大学的 Chih-Chung Chang 和 Chih-Jen Lin 开发。LibSVM 提供了一种简单易用的接口,支持多种 SVM 变体,包括分类、回归和分布估计。以下是一些关键特性和功能:
1.多种 SVM 类型:
- C-支持向量分类 (C-SVC)
- ν-支持向量分类 (ν-SVC)
- 分布估计(One-class SVM)
- ϵ-支持向量回归 (ϵ-SVR)
- ν-支持向量回归 (ν-SVR)
2.多种核函数:线性核、多项式核、径向基函数 (RBF) 核、Sigmoid 核
3.交叉验证:LibSVM 支持交叉验证,用于模型选择和评估。
4.多类别分类:通过一对多 (one-vs-all) 和一对一 (one-vs-one) 方法实现多类别分类。
5.工具和接口:LibSVM 具有命令行工具,并提供了多种编程语言的接口,包括 Python、Java、MATLAB、R 等。
6.可视化:LibSVM 提供了数据和模型的可视化工具,帮助用户理解 SVM 的工作原理和结果。
安装和使用
在 Python 中,可以通过 scikit-learn
或 libsvm
包来使用 LibSVM 的功能。下面是一个简单的安装和使用示例:
安装 scikit-learn
:
pip install scikit-learn
示例代码:
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score# 加载示例数据集
iris = datasets.load_iris()
X, y = iris.data, iris.target# 分割数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)# 创建SVM模型
model = SVC(kernel='linear')# 训练模型
model.fit(X_train, y_train)# 预测
y_pred = model.predict(X_test)# 评估模型
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy}")
LibSVM for Python
LibSVM是开源的SVM实现,支持C, C++, Java,Python , R 和 Matlab 等, 这里选择使用Python版本。
安装LibSVM
将LibSVM仓库的所有内容放入Python的包目录\Lib\site-packages或者工程目录中。
在libsvm根目录和python子目录下中分别新建名为__init__.py
的空文件,这两个空文件将标识所在的目录为python包可以直接导入。
允许草民吐槽一下各种Blog里切换根目录的奇怪的解决方案:这个和这个
因为经常使用svm,所以草民将libsvm包放入\Lib\site-packages目录下。在Python交互环境或在任意脚本中都可以使用import libsvm.python
来使用libsvm的python接口。
使用LibSVM
LibSVM的使用非常简单,只需调用有限的接口。
from libsvm.python.svmutil import *
from libsvm.python.svm import *y, x = [1,-1], [{1:1, 2:1}, {1:-1,2:-1}]
prob = svm_problem(y, x)
param = svm_parameter('-t 0 -c 4 -b 1')
model = svm_train(prob, param)
yt = [1]
xt = [{1:1, 2:1}]
p_label, p_acc, p_val = svm_predict(yt, xt, model)
print(p_label)
输出结果:
optimization finished, #iter = 1
nu = 0.062500
obj = -0.250000, rho = 0.000000
nSV = 2, nBSV = 0
Total nSV = 2
test:
Model supports probability estimates, but disabled in predicton.
Accuracy = 100% (1/1) (classification)
[1.0]
在SVM数据中下载train1.txt和test1.txt。
LibSVM可以在文件中读取训练数据,这样便于大规模数据的使用。
示例:
from libsvm.python.svmutil import *
from libsvm.python.svm import *y, x = svm_read_problem('train1.txt')
yt, xt = svm_read_problem('test1.txt')
model = svm_train(y, x )
print('test:')
p_label, p_acc, p_val = svm_predict(yt[200:202], xt[200:202], model)
print(p_label)
输出:
optimization finished, #iter = 5371
nu = 0.606150
obj = -1061.528918, rho = -0.495266
nSV = 3053, nBSV = 722
Total nSV = 3053
test:
Accuracy = 40.809% (907/2225) (classification)
LibSVM接口
训练数据格式
libsvm的训练数据格式如下:
<label> <index1>:<value1> <index2>:<value2> ...
示例:
1 1:2.927699e+01 2:1.072510e+02 3:1.149632e-01 4:1.077885e+02
主要类型
svm_problem
:保存定义SVM模型的训练数据svm_parameter
:存储训练SVM模型所需的各种参数svm_model
:完成训练的SVM模型svm_node
:模型中一个特征的值,只包含一个整数索引和一个浮点值属性。
主要接口:
-svm_problem(y, x)
:由训练数据y,x创建svm_problem对象
svm_train()
:svm_train有3个重载:
-
model = svm_train(y, x [, 'training_options'])
-
model = svm_train(prob [, 'training_options'])
-
model = svm_train(prob, param)
用于训练svm_model模型
- `svm_parameter(cmd):创建svm_parameter对象,参数为字符串。
示例:
param = svm_parameter('-t 0 -c 4 -b 1')
svm_predict()
调用语法:
p_labs, p_acc, p_vals = svm_predict(y, x, model [,'predicting_options'])
参数:
y
测试数据的标签
x
测试数据的输入向量
model
为训练好的SVM模型。
返回值:
p_labs
是存储预测标签的列表。
p_acc
存储了预测的精确度,均值和回归的平方相关系数。
p_vals
在指定参数'-b 1'时将返回判定系数(判定的可靠程度)。
这个函数不仅是测试用的接口,也是应用状态下进行分类的接口。比较奇葩的是需要输入测试标签y才能进行预测,因为y不影响预测结果可以用0向量代替。
svm_read_problem
读取LibSVM格式的训练数据:
y, x = svm_read_problem('data.txt')
svm_save_model
将训练好的svm_model存储到文件中:
svm_save_model('model_file', model)
model_file的内容:
svm_type c_svc
kernel_type linear
nr_class 2
total_sv 2
rho 0
label 1 -1
probA 0.693147
probB 2.3919e-16
nr_sv 1 1
SV
0.25 1:1 2:1
-0.25 1:-1 2:-1
svm_load_model
读取存储在文件中的svm_model:
model = svm_load_model('model_file')
调整SVM参数
LibSVM在训练和预测过程中需要一系列参数来调整控制。
svm_train的参数:
-
-s
SVM的类型(svm_type)-
0 -- C-SVC(默认)
使用惩罚因子(Cost)的处理噪声的多分类器
-
1 -- nu-SVC(多分类器)
按照错误样本比例处理噪声的多分类器
-
2 -- one-class SVM
一类支持向量机,可参见"SVDD"的相关内容
-
3 -- epsilon-SVR(回归)
epsilon支持向量回归
-
4 -- nu-SVR(回归)
-
-
-t
核函数类型(kernel_type)-
0 -- linear(线性核):
u'*v
-
1 -- polynomial(多项式核):
(gamma*u'*v + coef0)^degree
-
2 -- radial basis function(RBF,径向基核/高斯核):
exp(-gamma*|u-v|^2)
-
3 -- sigmoid(S型核):
tanh(gamma*u'*v + coef0)
-
4 -- precomputed kernel(预计算核):
核矩阵存储在
training_set_file
中
-
下面是调整SVM或核函数中参数的选项:
-
-d
调整核函数的degree参数,默认为3 -
-g
调整核函数的gamma参数,默认为1/num_features
-
-r
调整核函数的coef0参数,默认为0
-
-c
调整C-SVC, epsilon-SVR 和 nu-SVR中的Cost参数,默认为1
-
-n
调整nu-SVC, one-class SVM 和 nu-SVR中的错误率nu参数,默认为0.5
-
-p
调整epsilon-SVR的loss function中的epsilon参数,默认0.1
-
-m
调整内缓冲区大小,以MB为单位,默认100
-
-e
调整终止判据,默认0.001
-
-wi
调整C-SVC中第i个特征的Cost参数
调整算法功能的选项:
-
-b
是否估算正确概率,取值0 - 1,默认为0
-
-h
是否使用收缩启发式算法(shrinking heuristics),取值0 - 1,默认为0
-
-v
交叉校验 -
-q
静默模式
LibSVM for Matlab
LibSVM的Matlab接口用法和上面python接口类似,Matlab丰富的标准工具箱提供了各种方便。在 MATLAB 中使用 LibSVM 需要遵循以下步骤。以下是一个详细的使用过程及一些技巧:
1.下载和安装 LibSVM
首先,从 LibSVM 的官方网站下载最新版本的 LibSVM:
LibSVM 官方下载页面https://www.csie.ntu.edu.tw/~cjlin/libsvm/
页面如下:
找到需要下载的文件下载,解压下载的文件后,进入解压目录。
2.编译 LibSVM 的 MATLAB 接口
在 MATLAB 中,导航到 LibSVM 解压目录,并运行 make
命令来编译 MATLAB 接口:
cd path_to_libsvm_directory/matlab
make
这会编译并生成 svmtrain.mex*
和 svmpredict.mex*
文件,这些是与 MATLAB 交互的接口。
3.加载数据
你可以使用 MATLAB 的内置函数或从文件读取数据。以下是一个简单的示例,使用随机生成的数据:
% 生成一些示例数据
X = rand(100, 2); % 100个样本,每个样本有两个特征
y = randi([0, 1], 100, 1); % 100个标签,0或1
4.训练 SVM 模型
使用 svmtrain
函数训练 SVM 模型:
% 定义SVM参数
% -s 0 : C-SVC分类器
% -t 2 : RBF核
% -c 1 : 惩罚参数C
% -g 0.07 : RBF核的gamma参数
model = svmtrain(y, X, '-s 0 -t 2 -c 1 -g 0.07');
5.预测
使用训练好的模型进行预测:
% 生成一些测试数据
Xt = rand(50, 2); % 50个测试样本
yt = randi([0, 1], 50, 1); % 50个标签,0或1% 使用训练好的模型进行预测
[predicted_label, accuracy, decision_values] = svmpredict(yt, Xt, model);
svmpredict
函数返回三个值:
predicted_label
:预测的标签accuracy
:预测的准确性decision_values
:决策函数值
技巧和注意事项
1.数据预处理:在使用 SVM 之前,确保数据已经过标准化或归一化处理,这有助于提高模型的性能。
2.参数调优:使用交叉验证来选择最佳的 C 和 gamma 参数。你可以使用网格搜索来找到最佳参数组合。
3.内存管理:对大数据集进行操作时,要注意 MATLAB 的内存使用情况。
4.多类别分类:LibSVM 支持多类别分类,使用一对一策略。在多类别分类问题中,确保标签是从 1 开始的整数。
5.自定义核函数:如果内置的核函数不能满足需求,可以自定义核函数,但这需要修改 LibSVM 的源代码并重新编译。
示例代码总结
% 1.加载数据
X = rand(100, 2); % 示例数据
y = randi([0, 1], 100, 1); % 标签% 2.训练 SVM 模型
model = svmtrain(y, X, '-s 0 -t 2 -c 1 -g 0.07');% 3.测试数据
Xt = rand(50, 2); % 测试数据
yt = randi([0, 1], 50, 1); % 测试标签% 4.预测
[predicted_label, accuracy, decision_values] = svmpredict(yt, Xt, model);% 显示结果
disp('Predicted Labels:');
disp(predicted_label);
disp('Accuracy:');
disp(accuracy);
通过上述步骤和技巧,你可以在 MATLAB 中有效地使用 LibSVM 进行各种 SVM 任务,包括分类和回归。确保你根据具体问题调整参数和数据处理方法,以获得最佳性能。除此之外,Statistic Tools工具箱提供了svmtrain和svmclassify函数进行SVM分类。具体的一个简单示例及讲解如下:
traindata = [0 1; -1 0; 2 2; 3 3; -2 -1;-4.5 -4; 2 -1; -1 -3];
group = [1 1 -1 -1 1 1 -1 -1]';
testdata = [5 2;3 1;-4 -3];
svm_struct = svmtrain(traindata,group);
Group = svmclassify(svm_struct,testdata);
代码讲解说明:svmtrain接受traindata和group两个参数,traindata以一行表示一个样本,group是与traindata中样本对应的分类结果,用1和-1表示。svmtrain返回一个存储了训练好的svm所需的参数的结构svm_struct。svmclassify接受svm_struct和以一行表示一个样本的testdata,并以1和-1列向量的形式返回分类结果。