机器学习周志华- 第六章学习笔记6.1-6.4

本周学习了6.1-6.4节

间隔与支持向量

对于二分类学习,假设现在的数据是线性可分的,这时分类学习最基本的想法就是找到一个合适的超平面,该超平面能够将不同类别的样本分开,类似二维平面使用ax+by+c=0来表示,超平面实际上表示的就是高维的平面。

函数间隔就是|w’x+b|,而几何间隔就是点到超平面的距离

函数间隔不适合用来最大化间隔,因此这里我们要找的最大间隔指的是几何间隔,于是最大间隔分类器的目标函数定义为:max y y=2/||w||

image

对偶问题

SVM的基本型本身是一个凸二次规划问题,可直接用优化计算包求解,也可转化为更高效的“对偶问题”。

1.引入拉格朗日乘子 得到拉格朗日函数

image

2.L(w,b,a)对w和b的偏导为零可得

image

3.回代
image

最终模型

image

KKT条件

image

SMO算法

image
image
image

核函数

把训练集的向量点转到高维的非线性映射函数,用核函数取代非线性映射的内积
image

在SVM转化为最优化问题时求解的公式计算大多都是以内积形式出现

如果原始空间是有限维(属性数有限),那么一定存在一个高维特征空间使样本可分

推导

image
image
image

常见的核函数

image

核函数的组合

这三个表达式得到的结果都为核函数
image

软间隔与正则化

引入软间隔,允许在一些样本上不满足约束

软间隔示意图

image

硬间隔
image

软间隔允许有些样本不满足约束

在最大化间隔的同时,不满足约束的样本应尽可能少。
image

使用αn和βn来构造拉格朗日函数
image

软间隔的对偶形式
image

算法步骤
image

三种常见的替代损失函数

image

使用matlab自带的svmtrain函数

% 使用SVM(支持向量机)分割两类点并画出图形
XY1 = 2 + rand(100,2); % 随机产生100行2列在2-3之间的点
XY2 = 3+ rand(100,2);% 随机产生100行2列在3-4之间的点
XY = [XY1;XY2]; % 合并两点
Classify =[zeros(100,1);ones(100,1)]; % 第一类点用0表示,第二类点用1表示
Sample = 2+ 2*rand(100,2); % 测试点
%figure(1);
%plot(XY1(:,1),XY1(:,2),'r*'); % 第一类点用红色表示
%hold on;
%plot(XY2(:,1),XY2(:,2),'b*'); % 第二类点用蓝色表示
% 训练SVM
SVM = svmtrain(XY,Classify,'showplot',true);
% 给测试点分类,并作出最大间隔超平面(一条直线)
svmclassify(SVM,Sample,'showplot',true); 

image

libsvm在MATLAB中的使用

  1. 下载libsvm
  2. 设置路径
  3. mex -setup命令或者直接运行make.m文件编译C++文件

libsvmread(heart_scale)

libsvmread 主要用于读取数据

这里的数据是非matlab下的.mat数据,比如说是.txt,.data等等,这个时候需要使用libsvmread函数进行转化为matlab可识别数据,比如自带的数据是heart_scale数据,那么导入到matlab有两种方式,一种使用libsvmread函数,在matlab下直接libsvmread(heart_scale);第二种方式为点击matlab的‘导入数据’按钮,然后导向heart_scale所在位置,直接选择就可以了

libsvmwrite(‘filename’,label_vector, instance_matrix)

libsvmwrite写函数

libsvmwrite(‘filename’,label_vector, instance_matrix);

label_vector是标签,instance_matrix为数据矩阵(注意这个数据必须是稀疏矩阵,就是里面的数据不包含没用的数据(比如很多0),有这样的数据应该去掉再存)

model=svmtrain(label,data,Libsvm_options);

svmtrain训练函数,训练数据产生模型的
cmd: -t=0时线性核。-t=1多项式核,-t=2,径向基函数(高斯),-t=3,sigmoid核函数
-g为核函数的参数系数,-c为惩罚因子系数,-v为交叉验证的数,默认为5.

Libsvm_options

怎么选择呢?libsvm_options:重要的是-t,以及交叉验证时的-v

-s svm类型:SVM设置类型,一般默认0不用设置

0 -- C-SVC(多类分类)

1 --v-SVC(多类分类)

2 –一类SVM

3 -- e –SVR

4 -- v-SVR

-t 核函数类型:核函数设置类型(默认2)

0 –线性:u'v

1 –多项式:(r*u'v + coef0)^degree

2 – RBF函数:exp(-gamma|u-v|^2)

3 –sigmoid:tanh(r*u'v + coef0)

-d degree:核函数中的degree设置(针对多项式核函数)(默认3)

-g r(gama):核函数中的gamma函数设置(针对多项式/rbf/sigmoid核函数)(默认1/ k)

-r coef0:核函数中的coef0设置(针对多项式/sigmoid核函数)((默认0)

-c cost:设置C-SVC,e -SVR和v-SVR的参数(损失函数)(默认1)

-n nu:设置v-SVC,一类SVM和v- SVR的参数(默认0.5)

-p p:设置e -SVR 中损失函数p的值(默认0.1)

-m cachesize:设置cache内存大小,以MB为单位(默认40)

-e eps:设置允许的终止判据(默认0.001)

-h shrinking:是否使用启发式,0或1(默认1)

-wi weight:设置第几类的参数C为weight*C(C-SVC中的C)(默认1)

-v n: n-fold交互检验模式,n为fold的个数,必须大于等于2


返回的model

-Parameters: 参数。

-nr_class: 类的数目。

-totalSV:总的支持向量数目。

-rho: -判决函数wx+b的b。

-Label: 每个类的标签。

-ProbA: 成对的概率信息,如果b是 0则为空。

-ProbB: 成对的概率信息,如果b是 0则为空。

-nSV: 每个类的支持向量

-sv_coef:判决函数的系数

-SVs:支持向量。

如果指定了'-v',那么就实施了交叉验证,而且返回是交叉验证的正确率。

[predicted_label]=svmpredict(testing_label_vector,testing_instance_matrix, model, ‘libsvm_options’)

或者
[predicted_label,accuracy,decision_values/prob_estimates]= svmpredict(testing_label_vector,testing_instance_matrix,model,’libsvm_options’)
输入为
输出为三个参数,预测的类型,准确率,评估值(非分类问题用着)

%加载数据集 
load  heart_scale.mat
%返回heart_scale_inst(instance_matrix数据矩阵) heart_scale_label是标签
%径向基函数(高斯)训练
model = svmtrain(heart_scale_label,heart_scale_inst,'-t 2');
[predict_label,accuracy,decision_values] = svmpredict(heart_scale_label,heart_scale_inst,model);
%% 加载数据
% * 最终data格式:m*n,m样本数,n维度
% * label:m*1  标签为-1与1这两类
clc
clear
close all
data = load('data_test1.mat');
data = data.data';
%选择训练样本个数
num_train = 80;
%构造随机选择序列
choose = randperm(length(data));
train_data = data(choose(1:num_train),:);
gscatter(train_data(:,1),train_data(:,2),train_data(:,3));
label_train = train_data(:,end);
test_data = data(choose(num_train+1:end),:);
label_test = test_data(:,end);
predict = zeros(length(test_data),1);
%% ----训练模型并预测分类
model = svmtrain(label_train,train_data(:,1:end-1),'-t 2');
% -t = 2 选择径向基函数核 
true_num = 0;
for i = 1:length(test_data)
    % 作为预测,svmpredict第一个参数随便给个就可以
    predict(i) = svmpredict(1,test_data(i,1:end-1),model);
end
%% 显示结果
figure;
index1 = find(predict==1);
data1 = (test_data(index1,:))';
plot(data1(1,:),data1(2,:),'or');
hold on
index2 = find(predict==-1);
data2 = (test_data(index2,:))';
plot(data2(1,:),data2(2,:),'*');
hold on
indexw = find(predict~=(label_test));
dataw = (test_data(indexw,:))';
plot(dataw(1,:),dataw(2,:),'+g','LineWidth',3);
accuracy = length(find(predict==label_test))/length(test_data);
title(['predict the testing data and the accuracy is :',num2str(accuracy)]);

image

补充

Matlab中存储及读取数据 sava load

我们在使用MATLAB过程中,免不了希望将运算过程中的某些数据「储存」起来,以便下次使用再「读取」利 用。「储存」和「读取」的指令分别是save及load

save的数据型态又分为
(1)双位元格式 (binary format) 的 MAT-file

MAT-file 是以双位元字元储存,可让电脑在读出/入(input/output) 速率加快,其格式为test.mat(test为档名),MATLAB将档案的型态预设为MAT-file;

(2) ASCII 格式的 ASCII-file。
ASCII-file则是以可辨识的字元 储存,但会降低电脑在读出/入的速率,其格式为test.dat(test为档名)。

如果你的数据是只在MATLAB中产生 及被使用,那最好使用MAT-file。ASCII-file则必须用在当数据档要为其它不是MATLAB的应用软体读取时

当save成MAT档是储存变数本身,而非直接储存变数的数据;而save成ASCII档则是直接储存变数的数值。

>> A=[1 2 3; 4 5 6];
>> save data.dat A -ascii %是将A阵列的数值存入data这个ASCII-file
>> type data.dat % type 指令可以将 data.dat 的内容列出
>> load data.dat
>> x4=data(:,1); % 令 x4 为 data 的第一列数据
>> y4=data(:,2); % 令 y4 为 data 的第二列数据
>> z4=data(:,3); % 令 z4 为 data 的第三列数据 
% 先产生二个列阵列 (row array} x, y
>> x=1:5; y=11:15;
>> save data1 x y 
% 是将 x,y 二个变数的数值存入 data1 这个MAT-file,
%即data1其实是data1.mat。data1.mat 的内容为变数x, y,而非(1:5, 11:15) 的数据
>> load data1 % 读取 data1.mat 档
posted @ 2017-08-30 00:46  于繁华求淡然  阅读(1247)  评论(0编辑  收藏  举报