容易理解的视觉词袋模型的matlab编程实现

学习了视觉词袋模型以后,希望自己能真正运用BOW进行分类,所以就自己变了一个比较简单易懂的BOW的程序,上一篇提到的BOW中的matlab程序十分的复杂,对于初学BOW的人来说很不容易理解,而且提的是sift特征,并且模块之间环环相扣,不易拆分开来自己使用。这篇文章我用的数据是已经提取好了的特征,每个图像是用1*19维的特征表示的,当然这么小的数据实际上是不适合用BOW的,因为,本身就不需要太大的降维,而且BOW十分的吃提取的特征,是一个力度非常大的降维方式。但是这里主要是为了进行对比,我之前用遗传算法加svm的方式进行了特征选择,从19维的特征中选择了8维特征就能够达到非常好的分类精度,而且分类的准确率比之前有所提高,所以这里我也将19维的特征用8维的特征去表示。对BOW不了解的同学可以看这里BOW

下面是我的matlab程序,里面的注释也很详细,这里面的输入时已经提取好了的特征,如果大家想用BOW的话,需要自己先提取特征,方便变换用不同的特征提取方式,这样就可以稍微改变一下程序就可以了。

clear all;
close all;
clc;
load D:\硕士学习资料3\硕士毕设资料\区域生长等分割算法程序\遗传分割\MYGAseg\特征选择\traindata.mat
load D:\硕士学习资料3\硕士毕设资料\区域生长等分割算法程序\遗传分割\MYGAseg\特征选择\testdata.mat
load D:\硕士学习资料3\硕士毕设资料\区域生长等分割算法程序\遗传分割\MYGAseg\特征选择\trainlabel.mat
load D:\硕士学习资料3\硕士毕设资料\区域生长等分割算法程序\遗传分割\MYGAseg\特征选择\testlabel.mat
%注意这里我的traindata和testdata存储的时候都是一张图片变成了19维的特征向量,traindata是166*19的,也就是有
%166张图片,所以我这里要做一下预处理,一张图片是1*19,因为聚类时是一行代表一个中心的维数,所以要变成19*1,最后的聚类中心应该是8个,也就是一张图片
%1*8,变成8*1%注意这里要聚类的是将19个特征变成8个聚类中心
traindata1=traindata';%reshape函数是按照列优先进行重组的
traindata1=reshape(traindata1,1,size(traindata1,1)*size(traindata1,2));
traindata1=traindata1';%这样就把所有的训练样本变成了每一张图片的特征都按照列进行排列了
    
[trainL,trainC]= kmeanspp(traindata1,8);%这个函数使用的是Kmeans++,返回的C是对应的数据聚类中心,返回的L是对应的数据点所归属的
%标号,注意标号与返回的数据聚类中心是相对应的,之所以选择8是因为特征选择的结果是8
%trainC也就是聚类中心的坐标就是它所代表的标号
%上面的聚类只是为了找聚类中心
% A=hist(trainL);%统计直方图
% dictionary=A(find(A~=0));%将那些是0的去掉,hist的结果里有一些是0,统计的是中心点的频数
% dictionary=dictionary./mtrain;%归一化变成词频
[m1,n1]=size(trainC);
[m,n]=size(traindata);
mindis1=zeros(m,m1);%这个只是为了记录中间结果
dictionarytrain=zeros(m,m1);%统计词频
for i=1:m
    for j=1:n
        for k=1:m1
       mindis1(i,k)=abs(traindata(i,j)-trainC(k,:));%求距离哪个中心点最小
        end
       [y,mink] =min(mindis1(i,:));
       dictionarytrain(i,mink)=dictionarytrain(i,mink)+1;%训练样本的词频数,可以不用归一化
    end
end
%词频归一化
for i=1:m
   dictionarytrain(i,:)= dictionarytrain(i,:)./size(traindata,2);
end
    
[m2,n2]=size(testdata);
dictionarytest=zeros(m2,m1);
mindis2=zeros(m2,m1);
for i=1:m2
    for j=1:n2
        for k=1:m1
       mindis2(i,k)=abs(testdata(i,j)-trainC(k,:));%求距离哪个中心点最小
        end
       [y,mink] =min(mindis2(i,:));
       dictionarytest(i,mink)=dictionarytest(i,mink)+1;%测试样本的词频数
    end
end
%词频归一化
for i=1:m2
   dictionarytest(i,:)= dictionarytest(i,:)./size(testdata,2);
end
%%%%%%%%%%%进行分类训练
[bestacc2,bestc2,bestg2] = SVMcgForClass(trainlabel,dictionarytrain);%加1来标识不是svc的
n=15;%保留15位有效数字
cmd = [ '-s ',num2str(0),' -t ',num2str(2),' -c ',num2str(bestc2),' -g ',num2str(bestg2)];%-s,-t,使用的都是默认参数
model2=svmtrain(trainlabel,dictionarytrain,cmd);%默认参数-s=0,-t=2,但是一定要注意-g等参数前面及后面的空格,否则会导致参数连在一起,改变训练模型
[predict_label2,accuracy2,decisionvalue2] = svmpredict(testlabel,dictionarytest,model2);%这里的决策值是84*3的矩阵,代表什么意思???
type = 2;%输入的是测试集数据
CR2=ClassResult(testlabel, dictionarytest, model2, type);    


最后的分类结果:

#class is 3
类别标签为 1 2 3 
支持向量数目 82
===各种分类准确率===
整体分类准确率 = 82.1429% (69/84)
第 1 类分类准确率 = 94.1176% (16/17)
第 2 类分类准确率 = 17.6471% (3/17)
第 3 类分类准确率 = 100% (50/50)


当然这只是主程序,里面有用到Kmean++的程序,也就是kmeans聚类的改进版程序,对kmeans不了解的同学点Kmeans算法及matlab实现。我将把我的主程序和kmeans++的完整版放在资源里,下载点这里:代码完整版


本demo实现的是基于bow原理对图片进行分类,并实现对选取得测试集进行查找 BoW(Bag of Words)词袋模型最初被用在文本分类中,将文档表示成特征矢量。它的基本思想是假定对于一个文本,忽略其词序和语法、句法,仅仅将其看做是一些词汇的集合,而文本中的每个词汇都是独立的。简单说就是讲每篇文档都看成一个袋子(因为里面装的都是词汇,所以称为词袋,Bag of words即因此而来),然后看这个袋子里装的都是些什么词汇,将其分类。如果文档中猪、马、牛、羊、山谷、土地、拖拉机这样的词汇多些,而银行、大厦、汽车、公园这样的词汇少些,我们就倾向于判断它是一篇描绘乡村的文档,而不是描述城镇的。 serachFeatures.py中,前面主要是一些通过parse使得可以在敲命令行的时候可以向里面传递参数,后面就是提取SIFT特征,然后聚类,计算TF和IDF,得到单词直方图后再做一下L2归一化。一般在一幅图像中提取的到SIFT特征点是非常多的,而如果图像库很大的话,SIFT特征点会非常非常的多,直接聚类是非常困难的(内存不够,计算速度非常慢),所以,为了解决这个问题,可以以牺牲检索精度为代价,在聚类的时候先对SIFT做降采样处理。最后对一些在在线查询时会用到的变量保存下来。对于某个图像库,我们可以在命令行里通过下面命令生成BoF。 query.py只能每次查找一张图片,并返回与之匹配度(递减)最接近的6张图片
要构建词袋模型并使用MATLAB实现,可以按照以下步骤进行: 1. 数据预处理:首先,将所有评论文本进行预处理,包括去除特殊字符和标点符号、转换为小写字母,并进行词干化或词形还原等操作。 2. 构建词汇表:根据所有评论文本中出现的词语,构建一个词汇表。可以使用MATLAB的`unique`函数获取唯一的词语。 3. 构建词袋模型:根据构建的词汇表,对每个评论文本进行编码,统计每个词在每个评论中的出现频率。可以使用MATLAB的`histcounts`函数或`bagOfWords`对象来计算每个词在每个评论中的频率。 4. 生成词袋特征矩阵:将每个评论文本的词频向量组成一个特征矩阵。每一行表示一个评论文本,每一列表示一个词的频率。 以下是一个用MATLAB实现词袋模型的示例代码: ```matlab % 假设有一个包含所有评论文本的cell数组,名为'comments' % 假设已经对评论文本进行了预处理,并得到了词汇表'vocabulary' % 构建词袋模型 numDocs = numel(comments); % 评论文本数量 numWords = numel(vocabulary); % 词汇表大小 bagOfWordsMatrix = zeros(numDocs, numWords); % 词袋特征矩阵 for i = 1:numDocs % 统计每个词在当前评论中的频率 wordCounts = histcounts(comments{i}, [1:numWords+1]); % 将词频向量添加到词袋特征矩阵中 bagOfWordsMatrix(i, :) = wordCounts; end % 可以使用生成的词袋特征矩阵进行进一步的分析和建模 ``` 通过上述代码,你可以得到一个包含词频信息的词袋特征矩阵,并且可以在MATLAB中使用这个特征矩阵进行数据分析和建模,例如聚类、分类等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值