libsvm
LIBSVM是台湾大学林智仁(Lin Chih-Jen)教授等开发设计的一个简单、易于使用和快速有效的SVM分类与回归的软件包。LIBSVM软件包拥有目前各种常用编程语言的版本,如Python、Java、Matlab等。
SVM使用流程
· 转换数据格式;
· 缩放数据,例如将其变换到[0,1]或者[-1,1]的范围;
· 使用RBF核函数;
· 使用交叉验证寻找最优参数C和r;
· 使用最优参数训练整个数据集;
· 测试。
读取数据
使用svm_read_problem(data_file_name)读取数据,读取的数据格式必须为:
label index1:value1 index2:value2 ...
eg:
from svmutil import *
y, x = svm_read_problem('/heart_scale')
heart_scale是官方给的数据集,大致为
随机生成数据
这里我们使用sklearn随机生成数据,三种类型,用于测试SVM分类效果。
# 使用sklearn随机生成数据
# make_classification生成三元分类模型数据
from sklearn.datasets import make_classification
import matplotlib.pyplot as plt
# 关键参数有n_samples(生成样本数), n_features(样本特征数), n_redundant(冗余特征数)和n_classes(输出的类别数)
# X1为样本特征,Y1为样本类别输出, 共400个样本,每个样本2个特征,输出有2个类别,没有冗余特征,每个类别一个簇
X1,Y1 = make_classification(n_samples=400, n_features=2, n_redundant=0, n_clusters_per_class=1, n_classes=3)
plt.scatter(X1[:,0], X1[:,1], c=Y1, s=3, marker='o')
plt.show()
训练模型
使用svm_train(arg1, arg2=None, arg3=None)训练模型
# 使用libsvm训练模型
from svmutil import *
# 取前360数据作为训练集, 后40数据作为测试集
m = svm_train(Y1[:360], X1[:360], '') # 这里X1, Y1为列表 也可用np数组,或上面文件读取的数据类型
上面第三个参数为模型配置有以下选项:
-
-s SVM的类型,默认值为0
0 – C-SVC
1 – nu-SVC
2 – one-class SVM
3 – epsilon-SVR
4 – nu-SVR -
–t 核函数的类型,默认值为2
0 – 线性: u’v
1 – 多项式: (gammau’v + coef0)^degree
2 – 径向基: exp(-gamma|u-v|^2)
3 – sigmoid: tanh(gamma*u’*v + coef0)
4 – precomputed kernel,核函数值存储于training_set_file中 -
–d degree的值,默认为3;
-
-g gamma的值,默认1/num_features;
-
-r coef0的值,默认为0;
-
-c C-SVC, epsilon-SVR, and nu-SVR的cost,默认值为1;
-
-n nu-SVC, one-class SVM, and nu-SVR中的nu,默认值为0.5;
-
-p epsilon-SVR的loss function中的epsilon参数,默认值0.1;
-
-m 缓冲内存大小,单位MB,默认值100;
-
-e 终止判据的容忍值,默认值0.001;
-
-h 是否使用收缩启发式算法(shrinking heuristics),取值0或1,默认值为0;
-
-b 是否估算正确概率,取值0或1,默认值为0;
-
-wi C-SVC中第i个特征的Cost参数;
-
-v 交叉验证;
-
-q 静默方式,无输出。
(参考:忆霜晨)
测试模型
p_label, p_acc, p_val = svm_predict(Y1[360:], X1[360:], m)
输出:
Accuracy = 95% (38/40) (classification)
绘制分类彩图
绘制图片如下:
生成若干预测点,使用matplotlib函数绘制出网格线(参考:鹏大大大 )
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
x_np = np.asarray(X1)
y_np = np.asarray(Y1)
N, M = 200, 200 # 横纵各采样多少个值
x1_min, x2_min = x_np.min(axis = 0) # 列最小值
x1_max, x2_max = x_np.max(axis = 0) # 列最大值
t1 = np.linspace(x1_min, x1_max, N) # 在min-max间线性采样
t2 = np.linspace(x2_min, x2_max, M)
x1, x2 = np.meshgrid(t1, t2) # 生成网格采样点
x_show = np.stack((x1.flat, x2.flat), axis = 1) # 测试点
y_fake = np.zeros((40000,))
y_predict, _, _ = svm_predict(y_fake, x_show, m)
# 绘制分类图
cm_light = mpl.colors.ListedColormap(['#A0FFA0', '#FFA0A0', '#A0A0FF'])
cm_dark = mpl.colors.ListedColormap(['g', 'r', 'b'])
plt.pcolormesh(x1, x2, np.array(y_predict).reshape(x1.shape), cmap = cm_light)
plt.scatter(X1[:,0], X1[:,1], c=Y1, s=3, marker='o')
plt.show()