Fisher线性判别在ORL人脸数据集上的应用
数据集简介
本数据集共有40个人的人脸图像,每个人有10张图片,已经按顺序排好。由于pinv函数计算很慢,因此只选用前10个人,共100张照片进行本次训练和测试。其中每个人的前8张照片做训练集,后2张照片做测试集。
one-versus-one方法
概述
由于一共需要分10类,然而fisher线性判别法适用于二分类问题。因此,需要采用one-versus-one分类方法。
训练过程中,对于任意两个类别都训练一个分类器(每个分类器都会对应一个不同的w值),最终需要计算C(10,2)个w值。
测试过程中,对于一个测试数据,分别过一遍每一个分类器,每个分类器都会得到一个结果,便给这个结果投一票,最后选择票数最多的 类别就是测试数据的预测类别
程序简介
函数 | 概述 |
---|---|
w_compute.m | 函数,输入两个训练数据组,计算在这两个训练数据组上最佳的w |
compute_all_w.m | 脚本,计算45个w向量,结果存在w.mat中 |
predict.m | 函数,输入一个测试数据,knn参数k,45个w向量,训练数据集,得到预测的人脸编号 |
knn_predict_all.m | 脚本,直接运行(运行前载入w.mat),修改k值可以看到测试集上(20个)的准确率。 |
运行结果
k | 准确率 |
---|---|
1 | 55% |
3 | 60% |
5 | 55% |
可以看出,用fisher降维之后使用knn分类,准确率总体较高(随机分配概率应为10%),当k=3时的准确率最高,印证了k需要不高不低效果最好。
一个想法,直接用KNN分类呢?以下是直接分类的结果
k | 准确率 |
---|---|
1 | 75% |
3 | 75% |
5 | 75% |
可以看出,这个结果更好。这就是一个trade-off,KNN的在维数很高的地方计算速度很慢,fisher一下计算速度增加,但是准确率却有所降低。
多重判别方法
概述
一个c-类问题,fisher可以将n维向量映射到c-1维(而不是1维)
在使用分类器做判别时,先把测试数据和训练数据都降低到c-1维,然后该干嘛干嘛。
程序简介
函数 | 概述 |
---|---|
eigvector_compute.m | 脚本,用来计算9个特征值,计算结果存在eigvector.mat里 |
predict2.m | 函数,输入一个变换后的测试用例和一个变换后的训练集,返回预测的label |
multi_classify.m | 脚本,用来计算准确率,需要导入数据eigvector.mat |
附注:
在计算特征值和特征向量时, S−1wSB 是一个秩为9的矩阵,求出特征值的前9个是实数(由大到小排列好的),后便会出现复数。复数的特征值会对应复数的特征向量。庆幸的是,我们只取前9个。
运行结果
k | 准确率 |
---|---|
1 | 85% |
3 | 75% |
5 | 80% |
结论
从结果来看,one-vs-one判别方法准确率没有多重fisher高。并且one-vs-one方法会出现不同类别拿到相同的最高投票数的缺点,导致无法分出类别。不过令人惊奇的是,多重fisher的准确率竟然比不经过降维的准确率更高!因为fisher后提取了重要的特征,排除了很多无关的影响。