模式识别

实验一

源程序

% 首先载入数据txt格式,分为标签即种类标号和数据(属性:值)
[diabetes_label, diabetes_inst] =libsvmread('diabetes_scale.txt');
 data= [diabetes_inst(:,1), diabetes_inst(:,2)]; 

 %利用交叉耦合函数进行分组,80%的数据用来训练,剩下的数据进行预测
 [train, test] =crossvalind('holdOut',diabetes_label,0.8);

 train_diabetes = data(train,:);  %获取train对应的训练数据
 train_diabetes_labels = diabetes_label(train,:);%获取train对应的标签
 train_diabetes_labels = double(train_diabetes_labels );%将参数转为双精度浮点类型

 test_diabetes = data(test,:); %获取test对应的训练数据
 test_diabetes_labels = diabetes_label(test,:);  %获取test对应的标签                   
 test_diabetes_labels =double(test_diabetes_labels); %将参数转为双精度浮点类型

%训练
 model = svmtrain(train_diabetes_labels,train_diabetes, '-s 0 -t 2 -c 1 -g 2');
%预测
 [predict_label, accuracy, dec_values] =svmpredict(test_diabetes_labels, test_diabetes, model);

参数

Libsvm中用到的参数详解:

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

0:线性核函数 u’v

1:多项式核函数(r *u’v + coef0)^degree

2:RBF 核函数 exp( -r|u - v|^2)

3:sigmiod核函数 tanh(r * u’v + coef0)

- c cost:设置 C - SVC,epsilon - SVR 和 nu - SVR的参数(默认值为1)

- g r(gama):核函数中的gama参数设置(针对多项式/sigmoid 核函数/RBF/,默认值为属性数目的倒数)

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

实验二

源程序

KNN函数:

function relustLabel = KNN(inx,data,labels,k)
%% 
%   inx 为输入测试数据,data为样本数据,labels为样本标签
%%

[datarow , ~] = size(data);%返回矩阵的大小
%计算已知类别数据集合汇总的点与当前点的距离
diffMat = repmat(inx,[datarow,1]) - data ;%将inx复制datarow*1块
distanceMat = sqrt(sum(diffMat.^2,2));%距离度量使用欧式度量(P=2)
%按照距离递增次序排序
[B , IX] = sort(distanceMat,'ascend');%IX为排序后备元素在原矩阵中的行位置或列位置的索引
%确保k的值不会比B的长度大
len = min(k,length(B));
%选取与当前点距离最近的K个点
%返回距离最近的前K个点中频率最高的类别作为当前点的预测分类
relustLabel = mode(labels(IX(1:len)));%mode返回向量、数组或数据域中出现频率最多的数值。
End

测试样例:

tic
[labels, inst] =libsvmread('breast-cancer_scale.txt');
dataMat= [inst(:,1), inst(:,2)]; 
len = size(dataMat,1);%返回的是矩阵A的行数
k = 1;
error = 0;
% 设置测试数据比例
Ratio = 0.1;
numTest = floor(Ratio * len);%向小取整
% 归一化处理
maxV = max(dataMat);
minV = min(dataMat);
range = maxV-minV;
newdataMat = (dataMat-repmat(minV,[len,1]))./(repmat(range,[len,1]));

% 测试
for i = 1:numTest
    classifyresult = KNN(newdataMat(i,:),newdataMat(numTest:len,:),labels(numTest:len,:),k);
    fprintf('测试结果为:%d  真实结果为:%d\n',[classifyresult labels(i)])
    if(classifyresult~=labels(i))
        error = error+1;
    end
end
  fprintf('k值为:k=%d\n',k)
  fprintf('测试数据比例为:%d%%\n',Ratio*100)
  fprintf('准确率为:%f\n',1-error/(numTest))
  fprintf('错误率为:%f\n',error/(numTest))
  toc
  disp(['运行时间: ',num2str(toc)]);
end

实验三

源程序

K-means

%% 构造随机数据 
%第一类数据
mu1=[0 0];  
S1=[0.23 0;0 0.87]; %协方差
data1=mvnrnd(mu1,S1,100);   %围绕mun1产生高斯分布数据

%第二类数据
mu2=[1.25 1.25];
S2=[0.23 0;0 0.87];
data2=mvnrnd(mu2,S2,100);

%第三个类数据
mu3=[-1.25 1.25];
S3=[0.23 0;0 0.87];
data3=mvnrnd(mu3,S3,100);

%第四个类数据
mu4=[1.5 1.5];
S4=[0.23 0;0 0.87];
data4 =mvnrnd(mu4,S4,100);

%第5个类数据
mu5=[0 4];
S5=[0.23 0;0 0.87];
data5 =mvnrnd(mu5,S5,100);

X=[data1;data2;data3;data4;data5]; 
%显示数据
figure;
plot(X(:,1),X(:,2),'+');
title('原始数据');

%%K-means聚类
tic;
load X.mat;

[x,y]=size(X);
opts = statset('Display','final');
K=3; %将X划分为K类
repN=50; %迭代次数
%K-mean聚类
[Idx,Ctrs,SumD,D] = kmeans(X,K,'Replicates',repN,'Options',opts);
%Idx N*1的向量,存储的是每个点的聚类标号
figure;
%画出聚类为1的点。X(Idx==1,1),为第一类的样本的第一个坐标;X(Idx==1,2)为第二类的样本的第二个坐标
plot(X(Idx==1,1),X(Idx==1,2),'r.','MarkerSize',14)
hold on
plot(X(Idx==2,1),X(Idx==2,2),'b.','MarkerSize',14)
hold on
plot(X(Idx==3,1),X(Idx==3,2),'g.','MarkerSize',14)

%绘出聚类中心点,kx表示是圆形
plot(Ctrs(:,1),Ctrs(:,2),'kx','MarkerSize',14,'LineWidth',4)
legend('Cluster 1','Cluster 2','Cluster 3','Centroids','Location','NW')
grid on;
%打印结果
fprintf('划分成%d类的结果如下:\n',K)
for i=1:K
tm=find(Idx==i); %求第i类的对象
tm=reshape(tm,1,length(tm)); %变成行向量
fprintf('第%d类共%d个分别是%s\n',i,length(tm),int2str(tm)); %显示分类结果
end
toc
disp(['运行时间: ',num2str(toc)]);
%在上述生成随机数据的基础上增加标签来检验正确率
Y = ones(100,1);
X=[data1 Y;data2 2*Y;data3 3*Y];
save X;

%%K-means聚类
clear;
tic;
load X.mat;

[a,b]=size(X);
r = floor(0.1 * a);%随机取百分之的数据
data=X(randi(a,1,r),:);%从数据集的前x行抽取r行的随机样本
X=data(:,1:2);
Labels = data(:,3);
[x,y]=size(X);
opts = statset('Display','final');
K=3; %将X划分为K类
repN=50; %迭代次数
%K-mean聚类
[Idx,Ctrs,SumD,D] = kmeans(X,K,'Replicates',repN,'Options',opts);
%Idx N*1的向量,存储的是每个点的聚类标号
figure;
%画出聚类为1的点。X(Idx==1,1),为第一类的样本的第一个坐标;X(Idx==1,2)为第二类的样本的第二个坐标
plot(X(Idx==1,1),X(Idx==1,2),'ro','MarkerSize',14)
hold on
plot(X(Idx==2,1),X(Idx==2,2),'b.','MarkerSize',14)
hold on
plot(X(Idx==3,1),X(Idx==3,2),'gx','MarkerSize',14)
hold on

%绘出聚类中心点,kx表示是圆形
plot(Ctrs(:,1),Ctrs(:,2),'kx','MarkerSize',14,'LineWidth',4)
title('聚类样本个数比例为:10%');

legend('Cluster 1','Cluster 2','Cluster 3','Cluster 4','Cluster 5','Cluster 6','Centroids','Location','NW')
grid on;
%打印结果
fprintf('划分成%d类的结果如下:\n',K)
for i=1:K
tm=find(Idx==i); %求第i类的对象
tm=reshape(tm,1,length(tm)); %变成行向量
fprintf('第%d类共%d个分别是%s\n',i,length(tm),int2str(tm)); %显示分类结果
end
toc
disp(['运行时间: ',num2str(toc)]);
right = [0,0,0,0,0];
for i = 1:x
    if(Idx(i)+Labels(i)==3 || Idx(i)+Labels(i)==6)
        right(1) = right(1)+1;
    end
    if(Idx(i)+Labels(i)==2 || Idx(i)+Labels(i)==5)
        right(2) = right(2)+1;
    end
    if(Idx(i)+Labels(i)==4)
        right(3) = right(3)+1;
    end
    if(Idx(i)+Labels(i)==3 || Idx(i)+Labels(i)==4 || Idx(i)+Labels(i)==5)
        right(4) = right(4)+1;
    end
    if(Idx(i)+Labels(i)==2 || Idx(i)+Labels(i)==4 || Idx(i)+Labels(i)==6)
        right(5) = right(5)+1;
    end
end
  fprintf('聚类样本个数比例为:%d%%\n',r/a*100);
  fprintf('准确率为:%f\n',max(max(right))/x);

模式识别     

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!