持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第20天,点击查看活动详情
在这篇文章里你可以看到使用Matlab自带的knn模型进行一个简单的机器学习分类任务。
数据
因为是需要数据集的,所以我在这里提供一个数据集。你们只要复制下面的文本,粘贴到一个txt文件中即可。
【腾讯文档】features docs.qq.com/doc/DQWR1bE…
我是把它放到了一个features.txt
中。
复制到你本地之后数据应该长,这样里边有470条。
使用 readtable("文件名")
可以将文本文件读取到MATLAB中并存储一个表格。
letter = readtable("features.txt")
复制代码
读取进来之后,我们可以看到了这个数据有三列。前两列就类似于我们xy轴,然后第三列是对其的分类。
现在我们对于数据进行可视化。使用xy轴对其做出图像。
scatter(features.AspectRatio,features.Duration)
复制代码
我们发现这样根本看不出他们的分类来,所有的数据都糊在一起。其实matlab提供了一个gscatter
,它可以对应三个参数,而第三个参数就是类别。按照第三个参数进行分类。
gscatter(features.AspectRatio,features.Duration,features.Character)
复制代码
模型
Matlab提供了一个内置的knn模型。
mdl = fitcknn(data,"ResponseVariable");
我们可是使用fitknn
直接调用,第一个参数是待分类的数据,第二个参数你的待分类数据是按照表中什么指标进行分类的。
knnmodel = fitcknn(features,"Character")
复制代码
之后它会显示这么个东西:告诉你待预测的两个变量是什么、需要响应的变量是什么、要分的类有什么。这里使用knn设置的临近数值默认是1。
都说matlab是白痴软件,我看了一下确实有一点,因为上面那一句是你把它搞进模型之后就自动训练了,那句话执行完之后就是一个用你的数据训练完的KNN了,离谱不。
现在你就可以用训练完的数据进行预测了。
predict(model,newdata)
,直接使用predict函数,第一个参数是你要用哪个模型进行预测,第二个参数是你要预测的数值,多个变量需要用中括号包裹起来。
我们简单测试一下刚才那个KNN:
predicted = predict(knnmodel,[4,1.2])
复制代码
aspect ratio = 4, duration = 1.2时候,看一下子结果显示:
predicted = V
干巴巴的画图能不能可视化一下子?
其实本来不想讲这个的,因为我是菜鸡,我也刚开始学这玩意儿,我还没弄懂怎么可视化这个图,就是显示散点+背景。比如人家讲的时候长这样,但是没有画图的代码。
我自己画的话使用
hold on
,后边的图会 覆盖在前边的图上边嘛,就看不到点了。我自己查了半天也妹搜到gscatter怎么可视化为半透明的样子,所以我怀疑这个是P的。后来我一拍脑门,为什么不能先画区域再画散点呢。我是傻子。
因为要可视化分类之后的背景区域,我们搞一下子横纵坐标的分布范围:
xrange = min(features.AspectRatio):.01:max(features.AspectRatio);
yrange = min(features.Duration):.01:max(features.Duration);
[x,y] = meshgrid(xrange,yrange);
复制代码
先把x,y轴的分布区域搞出来。然后把他们用meshgrid
生成网络采样点,简单来说比如:
bg = gscatter(x(:),y(:),predict(knnmodel,[x(:),y(:)]))
bg(1).Color = '#7C8870';
bg(2).Color = '#945357';
bg(3).Color = '#8794A7';
hold on
point = gscatter(features.AspectRatio,features.Duration,features.Character)
point(1).Color = '#B7C4B3';
point(2).Color = '#A2797D';
point(3).Color = '#BECAD6';
复制代码
第一句是把背景画出来,xy用的是前边我们搞的那个网络采样点,分类用的是训练之后的knn模型。出于个人爱好还给他们挑了个莫兰迪色系,但是一点都不显眼。
因为我们之前预测分类使用的是KNN的NumNeighbors = 1,这样设定的范围比较小,所以对类别很敏感,我们也可以看出分类的结果背景比较破碎。
我们也可以调节NumNeighbors让KNN变得不再那么敏感。分别测试一下NumNeighbors等于其他值的时候:
评价
在我们能够进行分类之后,那我们怎么知道我们这个knn效果到底好不好,所以我们就要想办法对其进行评价。
AspectRatio Duration Character
5.7308 0.401 J
1.6596 0.455 M
2.4063 0.275 V
3.7568 0.856 J
2.32 1.36 M
3.6774 0.706 V
6.2692 0.991 J
7.0417 0.754 J
1.7222 0.583 M
1.525 0.57 M
复制代码
搞一组测试数据到txt里,和之前那个数据集一样读取到程序中。
testdata = readtable("test.txt")
复制代码
读取进来之后数据是这样一个三行十列的表格。
predictions = predict(knnmodel,[testdata.AspectRatio,testdata.Duration])
复制代码
使用NumNeighbors = 5的knn预测之后的答案是这个样子的:
iscorrect = predictions == testdata.Character
accuracy = sum(iscorrect) / numel(iscorrect)
复制代码
对于上面得到了预测数主动进行一下准确度的计算。
先是看一下我们的预测结果和测试数据的分类是否一致,将其结果存到iscorrect
中。
再使用sum
求出预测对的数量,用numel
求出总数量,二者相除将准确率放到accuracy
中。
最后结果是
accuracy = 0.8000
同理我们也可以求出预测的错误率:
ismis = predictions ~= testdata.Character
misclassrate = sum(ismis) / numel(ismis)
复制代码
嗯。傻瓜软件Matlab还自带了一个可视化正确率的工具。 confusionchart(test,predict)
,第一个参数是正确的结果数据,第二个参数是预测的数据。它会自动生成一个可视化矩阵。
predictions = confusionchart(testdata.Character,predictions)
复制代码
因为一共就只有三类,所以这里是一个3×3的表格。蓝色的部分是预测对的,而橙色的部分是预测错的。颜色深浅会像热图一样因数量不同而产生变化。