基于PCA+SVM的MINIST数据集分类

1. MINIST数据集下载地址:http://yann.lecun.com/exdb/mnist/.

2. MINIST数据图像读取MATLAB代码(参考斯坦福大学Andrew Ng教授的课件):

function images = loadMNISTImages(filename)
%loadMNISTImages returns a 28x28x[number of MNIST images] matrix containing
%the raw MNIST images

fp = fopen(filename, 'rb');
assert(fp ~= -1, ['Could not open ', filename, '']);

magic = fread(fp, 1, 'int32', 0, 'ieee-be');
assert(magic == 2051, ['Bad magic number in ', filename, '']);

numImages = fread(fp, 1, 'int32', 0, 'ieee-be');
numRows = fread(fp, 1, 'int32', 0, 'ieee-be');
numCols = fread(fp, 1, 'int32', 0, 'ieee-be');

images = fread(fp, inf, 'unsigned char');
images = reshape(images, numCols, numRows, numImages);
images = permute(images,[2 1 3]);

fclose(fp);

% Reshape to #pixels x #examples
images = reshape(images, size(images, 1) * size(images, 2), size(images, 3));
% Convert to double and rescale to [0,1]
images = double(images) / 255;
end

3. MINIST数据label读取MATLAB代码(参考斯坦福大学AndrewNg教授的课件):

function labels = loadMNISTLabels(filename)
%loadMNISTLabels returns a [number of MNIST images]x1 matrix containing
%the labels for the MNIST images

fp = fopen(filename, 'rb');
assert(fp ~= -1, ['Could not open ', filename, '']);

magic = fread(fp, 1, 'int32', 0, 'ieee-be');
assert(magic == 2049, ['Bad magic number in ', filename, '']);
numLabels = fread(fp, 1, 'int32', 0, 'ieee-be');
labels = fread(fp, inf, 'unsigned char');
assert(size(labels,1) == numLabels, 'Mismatch in label count');

fclose(fp);
end

4. PCA介绍:PCA主要通过对高维数据进行投影得到子空间向量来进行降维。具体地,就是求样本的协方差矩阵及其特征值、特征值向量,通过选取一定阈值内的特征值及其对应的特征向量,构成投影矩阵,这个投影矩阵中的向量之间都相互正交,在尽量降低特征维数的同时也尽量减少信息损失。降维后的特征向量具有低相关性,具有样本的本质属性,也使得后续分类不易陷入过拟合。

5. PCA具体步骤:

基于PCA+SVM的MINIST数据集分类_第1张图片

6. 常用降维方法:PCA(无监督),LDA(有监督),LLE(非线性),ISOMAP(非线性);

7. 常用分类方法:PCA+SVM,SRC(稀疏表征+字典),LRC;

8. 注意1:对于非线性降维方法,在求取投影矩阵P时,只需利用训练数据即可,不需要用到测试数据,P一旦求取后可认为是固定的,直接对测试数据进行降维即可;而非线性降维方法是需要保持局部结构不变,没有显式的映射,所以需要测试数据的参与;目前将非线性方法线性化是一个趋势。

9. 注意2: MATLAB中的eig函数求取的特征值一般是按照从小到达的顺序给出的,但是某些情况下相反,因此需要采用sort函数进行固定方向排序;

10. 注意3:实验发现在minist数据集上采用Chi-square距离没有欧氏距离的分类效果好;

11. PCA降维后再恢复的公式:;

12. SVM方法的两种实现:

     a. 采用MATLAB自带的svmtrain和svmclassify函数;

     b. 采用libSVM工具箱;

13. MATLAB自带SVM函数和libSVM工具箱中函数的区别:

     a. libSVM工具箱使用方便,参数调节也方便;

     b. MATLAB自带的SVM只能用于二分类,且不能用于回归(regression);

     c. libSVM中有多种如c-SVM,nu-SVM模型可选,而MATLAB自带SVM只有c-SVM;

     d. libSVM可实现多分类,有1对多的方法,也有1对1的方法,还有层次法,MATLAB中采用的是1对1的方法,1对多的方法是训练样本不平衡,如果对负样本进行去掉,则没有充分利用全部数据;1对1的方法是设计(k-1)*k/2个二分类器,对每个测试样本进行输出,输出最多的那个类别就是最终的判别类。

14. 注意:SVM实现的核心是采用SMO算法,SMO:Sequentialminimal optimization, 微软研究员提出,是一种快速的二次规划算法,针对线性和数据稀疏时性能更优;

15. 注意: libSVM中的数据有时可能需要用libsvmread函数进行格式转换;

16. libSVM基本用法:

     model = svmtrain(label, data, ‘option’);

     参数option选项:

            -s:表示SVM的类型,0:c-SVC, 1:nu- SVC, 2: one-class SVR; 3:epsilon-SVR, 4: nu-SVR;

            -t: 表示核函数类型,0: 线性,1:多项式,2:径向基函数,3:sigmoid, 4: precomputed的核;

           -d: 多项书的阶数;

           -c: 损失函数系数;

           -g: 核函数gamma参数,针对rbf,多项式核,sigmoid核。

     例子: model = sumtrain(label, data,’-s 0 -t 2-c 0.5 -g 0.1’);

18. 有关SVM核函数的选取:

    a.当特征数和样本数差不多时,可以采用线性或多项式核;

    b. 当特征数小于样本数时,一般采用高斯核;

    c.当特征数远小于样本数时,需要手动添加特征满足上面两个的要求;

17. PCA+SVM用于MINIST数据集分类代码:

function minist_svmcls()

clc;
% 读取minist数据集
train_data_name = 'F:\train-images.idx3-ubyte';
train_label_name = 'F:\train-labels.idx1-ubyte';
test_data_name = 'F:\t10k-images.idx3-ubyte';
test_label_name = 'F:\t10k-labels.idx1-ubyte';

train_data = loadMNISTImages(train_data_name);
train_label = loadMNISTLabels(train_label_name);
test_data = loadMNISTImages(test_data_name);
test_label = loadMNISTLabels(test_label_name);

% 下面采用SVM进行分类,特征向量都一样,只是分类器在变化
%训练模型,x_train每一行代表一个样本,列数等于样本特征维度,y_train为一列向量,每一个元素代表一个标签
test_N = 500;
trains = train_reduced_feat';
tests = test_reduced_feat(:,1:test_N)';
trainClassIDs = train_label;
testClassIDs = test_label(1:test_N);
model = svmtrain(trainClassIDs, trains,'-s 0 -t 2');
%测试模型,x_test每一行代表一个样本,列数等于样本特征维度,y_test为一列向量,每一个元素代表一个标签
[pred, acc, ~] = svmpredict(testClassIDs, tests, model);

你可能感兴趣的:(SVM,PCA,机器学习)