“著名的鸢尾花(Iris)数据集(由Ronald Fisher于1936年发表)是一种展示机器学习框架API的好方法。从某种程度上说,Iris数据集是机器学习界的”Hello world“。数据集链接:https://archive.ics.uci.edu/ml/datasets/Iris
”
我叫了一学期的兰花分类器。。。竟然是鸢尾花。。。
我要去跟着小甲鱼学英语了
“人们对外界事物的识别,很大部分是把事物按分类来进行的。”比如,依靠分类我们可以区别图像上的景物、声音中的内容、医学上的疾病诊断。在我们的心目中,“房子”、“树木”都是类别概念,而不是具体的某一座房子才是房子、某一棵树才是树。人认知的过程就是对类别的认识,所以学习分类器就是机器学习的基础。
训练Learning Machine的过程:将预测结果与实际结果比较来优化Machine,使结果更逼近于实际结果。
Iris dataset是Fisher先生多年前采集的样本数据,包含了3种鸢尾花、150个样本集,每个样本集包含鸢尾花的四个特征值,分别是:花瓣长度、花瓣宽度、花蕊长度、花蕊宽度。(看到有些地方说是萼片的长宽,我也不知道萼片是什么。。。)我们将它分为两个样本集,前75个dataset(样本集)作为Train_set(训练样本),后75个dataset作为Test_set(测试样本),用来测试我通过训练样本训练得到的分类器好不好用。
01
—
kNN算法原理
(1)我已知三个类别的样本,分别是:小红、小蓝、小绿,现在我有个新样本,想知道它是属于哪一类。(已知:Train_set,Train_label)
(2)将测试样本点与已知的所有样本点求欧式距离。
欧式距离:
马氏距离:
S:样本协方差矩阵
欧氏距离( Euclidean distance)是一个通常采用的距离定义,它是在m维空间中两个点之间的真实距离。 它将样品的不同属性(即各指标或各变量)之间的差别等同看待,这一点有时不能满足实际要求。
马氏距离是由印度统计学家马哈拉诺比斯(P. C. Mahalanobis)提出的,表示数据的协方差距离。马氏距离不受量纲的影响,两点之间的马氏距离与原始数据的测量单位无关;由标准化数据和中心化数据(即原始数据与均值之差)计算出的二点之间的马氏距离相同。马氏距离还可以排除变量之间的相关性的干扰。
这里由于四个特征的单位都是cm,用欧式距离即可。
(3)将距离从小到大排序,记录下距离测试样本最近的k个训练样本的类别。其中在类别个数比较中占优的类别=测试样本的类别。
k的取值:取奇数,避免两个类别“平票”的情况。
02
—
Matlab实现
Matlab Code:
clear all;
close all;
clc
%载入数据
TrainData=load('iris_train.data');
TrainLabel=load('iris_train.labels');
TestData=load('iris_valid.data');
TestLabel=load('iris_valid.labels');
%设定k个最近邻点
k=3;
%计算TestData与TrainData间的欧式距离
fori=1:75
for j=1:75
distance(j,i)=sqrt((TestData(i,1)-TrainData(j,1))^2+(TestData(i,2)-TrainData(j,2))^2+(TestData(i,3)-TrainData(j,3))^2+(TestData(i,4)-TrainData(j,4))^2);
end
end
%将距离按升序排列,order1为原序号
[distance_ascent,order1]=sort(distance);
%选取欧式距离最小的前k个训练样本,统计其在各类别中的频率
num1=0;
num2=0;
num3=0;
error_num=0;
fori=1:75
num1=0;
num2=0;
num3=0;
for m=1:k
if TrainLabel(order1(m,i),1)==1;
num1=num1+1;
elseif TrainLabel(order1(m,i),1)==2;
num2=num2+1;
elseif TrainLabel(order1(m,i),1)==3;
num3=num3+1;
end
end
class=[num1 num2 num3];
classname=find(class(1,:)==max(class));
fprintf('测试点%d属于第%d类',i,classname);
%结果分行
if mod(i,3)==0
fprintf('\n');
end
%计算误判率
if classname~=TestLabel(i)
error_num=error_num+1;
end
end
%输出正确率
accuracy=1-(error_num/75);
fprintf('\n判断分类正确率为:%d',accuracy);
而实际上matlab里有k近邻算法的包,可以直接调用
(图片转自:csdn:Liu_LongPo)
03
—
结果分析
结果:
测试点1属于第1类测试点2属于第1类测试点3属于第1类
测试点4属于第1类测试点5属于第1类测试点6属于第1类
。。。。。
测试点70属于第3类测试点71属于第3类测试点72属于第3类
测试点73属于第3类测试点74属于第3类测试点75属于第3类
判断分类正确率为:9.600000e-01>>
评价:
(1)之前就k值选取的讨论并不完全,当取奇数时,投票结果可能也会出现平票。比如,选择距离测试样本最近的9个样本,其中属于3个不同类别的样本数各为3。其次,由于样本容量不均,比如某一类别样本个数远远大于另两个类别,那么测试样本更可能被分入样本容量大的类别,这样也容易形成误判。
针对这个问题我们用加权平均求距离的方法:
加权平均:w=1/s
将距离的倒数作为权值加入类别投票的考虑中,距离近的权值大,距离远的权值小。
(2)需要始终存储所有的已知样本,并将每一个新样本和所有已知样本比较、排序,计算和存储成本过大。当样本集较大,比如上万个样本点,求距离就要做10的8次方计算,计算量过大。针对这个问题我们可以建立k维树,原理及实现方法见下一篇推送!
04
—
参考文献
1.《模式识别》 清华大学出版社
2. csdn的大神们
今天208喝酒去!
本文来自企鹅号 - 全球大搜罗媒体
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文来自企鹅号 - 全球大搜罗媒体
如有侵权,请联系 cloudcommunity@tencent.com 删除。