机器学习实验七—— 标题线性判别分析实验

本周的机器学习实验课上,老师布置的作业是需要做一个线性判别分析的实验,但是上课的时候听着部分内容的时候走了神,需要重新学习巩固一下该部分.先来看看题目的数据以及要求:

题目内容:

(1)根据训练数据,学习投影矩阵。

(2)将LDA在训练样本上的低维表示结果可视化。

(3)使用距离最短对测试样本进行分类。

题目的数据:

LDA线性判别分析的拓展方法 lda线性判别分析例题_机器学习


根据上面的数据内容可以大致清楚:数据基本上分为四个维度——出生时预期寿命(岁),预期受教育年限(年),平均受教育年限(岁),人均国民总收入(国际元/人),等级分为1,2,3等.要进行分类的测试样本即日本和中国两个国家的等级.

1.什么是线性判别分析(LDA)?

LDA是一种分类算法,但是在训练过程中,它会学习各类之间最有判别力的轴,然后可以使用这些轴来定义要在其上投影数据的超平面.这种方法的好处是投影将使类保持尽可能远的距离,因此LDA是在运行其他分类算法(例如SVM分类器)之前降维的好技术.

在西瓜书中说到:LDA的思想非常朴素:给定训练样例集,设法将样例投影到一条直线上,使得同类样例的投影点尽可能近、异类样例的投影点尽可能远离;在对新样本进行分类时,将其投影到同样的这条直线上,再根据投影点的位置来确定新样本的类别.二维的示意图如下.

LDA线性判别分析的拓展方法 lda线性判别分析例题_特征向量_02


如果将二分类任务推广到多分类任务,就体现了LDA的降维的功能,将N维数据投影到N-1维的空间.

LDA线性判别分析的拓展方法 lda线性判别分析例题_线性判别分析_03

2.LDA算法的计算步骤

(1)对n维数据进行标准化处理(n为特征数量)

(2)对于每个类别,计算n维数据的均值向量

(3)构造类内散度矩阵Sw和类间散度矩阵Sb

(4)计算矩阵的特征值和对应的特征向量

(5)选取前k个特征值对应的特征向量,构造一个n×k维的转换矩阵W,特征向量以列的形式排列

(6)使用转换矩阵W将样本映射到新的特征子空间上

3.代码实现

在后来在学习的过程中,突然发现在matlab上有一个降维工具箱。然后赶紧从github上把它下下来,下面是下载地址。

下载地址 是一个叫drtoolbox的压缩包,解压后可以看到里面的内容:

LDA线性判别分析的拓展方法 lda线性判别分析例题_LDA线性判别分析的拓展方法_04


这里需要将他放到matlab\toolbox目录下,我的存放目录如下:

LDA线性判别分析的拓展方法 lda线性判别分析例题_机器学习_05


打开matlab,点击设置路径-添加并包含子文件夹。如下图

LDA线性判别分析的拓展方法 lda线性判别分析例题_特征向量_06


然后点击预设-更新工具箱路径缓存-应用-确定

LDA线性判别分析的拓展方法 lda线性判别分析例题_LDA线性判别分析的拓展方法_07


在命令行窗口输入命令:what drtoolbox,如果看到了如下的内容,说明已经安装配置好了drtoolbox

LDA线性判别分析的拓展方法 lda线性判别分析例题_线性判别分析_08


LDA模型的函数就已经可以直接去直接使用了。

所以可以开始直接写主函数main了。

1.首先需要导入数据和处理数据

由于csvread()函数只能读取仅数字的数据,用csvread()这个函数并不好用,所以在这里直接使用matlab主页上的导入数据的功能:

LDA线性判别分析的拓展方法 lda线性判别分析例题_特征向量_09


选择序号1-20的数据(日本和中国作为测试集),然后导入数据。

LDA线性判别分析的拓展方法 lda线性判别分析例题_特征向量_10


然后存储数据save LDA如果是直接用LDA数据的话,会发现一直会有表头(即下图的VarName),这样的话如果直接调用lda.m函数的话是没有办法直接使用的。

LDA线性判别分析的拓展方法 lda线性判别分析例题_线性判别分析_11


所以需要先用一个函数table2array 来将table类型的数据转换为array类型。

2.结果可视化

可视化的内容就可以直接使用plot来解决。首先用find()函数来分别找到训练标签为1,2,3的样本,然后根据索引标记每个样本在降维后的低维结果的坐标。

LDA线性判别分析的拓展方法 lda线性判别分析例题_数据_12

3.对测试样本进行分类(用最短距离法)

用最短距离

clear,clc;
load LDA.mat
data=table2array(LDA);
train_data=data(1:20,1:4);%训练集数据
train_label=data(1:20,5);%训练集标签
test_data=data(21:22,1:4);%测试集数据
test_label=zeros(1,2);%测试集标签
%找到标签为1,2,3的序号
train1=find(train_label==1);
train2=find(train_label==2);
train3=find(train_label==3);
%将三类训练数据分开
train_data1=train_data(train1,1:4);
train_data2=train_data(train2,1:4);
train_data3=train_data(train3,1:4);
%求出三类样本的平均向量
m1=mean(train_data1);
m2=mean(train_data2);
m3=mean(train_data3);

%利用距离最小来分类测试样本
for ii=1:size(test_data,1)
    %计算与第1、2、3类的欧几里得距离
    d(1)=norm(test_data(ii,:)-m1);
    d(2)=norm(test_data(ii,:)-m2);
    d(3)=norm(test_data(ii,:)-m3);
    %计算最小距离并将样本最短的类别标签给test_label
    [minVal test_label(ii)]=min(d);
end