目录

  • 一.概述
  • 二.数据集描述
  • 三.方法
    • 数据预处理
    • SMOTE算法
    • Feed-forward网络
  • 四.结果
    • 后记(2021年5月)

一.概述

近日,有位同学因为搞不懂matlab中的神经网络来问我怎么做,我说你把数据集发来给我看看,我稍微一看好像没啥毛病,他跟我说是UCI上面找的一个wilt数据集,而且已经划分好了训练集和测试集,我粗粗一看没啥毛病就把它直接放进了matlab的神经网络工具箱中进行训练,没想到训练出来的网络在测试集上表现如此糟糕,全都分类成了正常,此时再回去看数据集发现原来这涉及到了机器学习中的类不平衡问题,于是采用了SMOTE(过采样)方法先对少数类进行扩充,扩充成了原来的4倍,再进行训练,此时的表现已经好了很多,在测试集上达到了88%的准确率。要知道提供该数据集的论文运用了SMOTE+SVM,可惜在测试集上的准确率才70%多,可见科技发展是迅速的。
此处matlab版本为 R2018a。

二.数据集描述

数据集来源:https://archive.ics.uci.edu/ml/datasets/Wilt
这个数据集通俗的说是遥感领域对树进行拍照,然后把照片中的像素多少和生病的树这二者结合做成了这个数据集,通过5项属性来预测树是否枯萎(生病)。实际上就是个2分类问题。下载该数据集后得到了一个training.csv和testing.csv文件,让我们先来看看里面具体长啥样。首先是training.csv文件。

左边第一列是分类,类有2类,w类(枯萎)和n(正常)类,作为我们的输出变量,右边5列5个属性,也就是我们需要的输入变量。

这里我们可以很明显的看到只有74个样本属于w类,剩下还有4264个样本均属于n类,这里出现了类别不平衡问题,w类的样本太少,提供的信息也太少,模型得不到足够的信息就会把少数类给忽视,这显然不是我们想看到的。

对于测试集的信息此处省略。总共500个样本,其中313个属于n类,187个属于w类。与训练集不同的地方在于它的排序是乱的,需要自己处理,不像训练集给你按class排好了。

三.方法

数据预处理

拿到数据集第一步,不是急急忙忙去套模型,是先分析数据特征,不然就会犯和我一样的错,前文中也提到了,这个数据集最特殊的就是类别不平衡问题,这个用SMOTE解决,在接下来的部分中详细阐述。这里对数据并不进行归一化,原文献提供的数据集已经经过了一定的处理,且归一化后实际效果要比归一前差很多。

SMOTE算法

http://freesourcecode.net/matlabprojects/64007/smote-(synthetic-minority-over-sampling-technique)-in-matlab#.XLfieKR5uUl
这个链接提供了简单易行的smote算法,把它下载下来后得到两个主要函数SMOTE.m和nearestneighbour.m。把它放进你的工程目录。smote算法简单来说就是对少数样本进行插值生成,而这其中涉及到一个k值(近邻大小),该k值在SMOTE.m中通过函数nearestneighbour.m自动选择,默认将样本放大4倍。

我们在这里先打开training.csv,为了方便matlab处理,我们先在excel中多加一个label列,1表示生病,0表示正常。

接下来让我们把前74个样本提取出另保存至一个excel表格。在matlab中选择上方的“导入数据”按钮,可得到以下界面:

选中数值矩阵,选中5列属性,变量名称命名x_train,点击导入。
同理选择数值矩阵输出,导入label列,命名为y_train。
把matlab的工作空间切换到你的工程目录下(放有smote函数的地方)
接下来只要在命令行窗口中输入以下代码

// SMOTE算法扩展样本
[feature,label]= SMOTE (x_train,y_train);

原来的74个样本就变成了296个样本!

把这些新样本复制进训练集的excel中,总共得到4581个训练样本。同理再进行导入,得到以下初始化的工作区:

干干净净,有没有,保存工作区为wilt.mat文件,到此我们的数据处理就结束了,接下来就可以建立模型了。

Feed-forward网络

这是我建立该网络并测试用的wilt.m,代码如下:

clear;
clc;
load wilt.mat;      %装入事先处理好的wilt数据集
inputnum = 5;       %第一层输入神经元为5
hiddennum = 8;      %第二层隐含神经元为8
outputnum = 1;      %第三层输出神经元为1
x_train = x_train'; %输入为500x5 转置为5x500 以下类似
x_test = x_test';
y_train = y_train';
y_test = y_test';
net = newff(minmax(x_train),[inputnum,hiddennum,outputnum],...{'tansig','logsig','purelin'},'trainlm');  %创建feed-forward神经网络
view(net)                     %输出网络图
net.trainParam.epochs = 5000; %设定最大迭代次数
net.trainParam.goal = 0.0000000001; %设定学习目标(最小误差)
[net,tr]=train(net,x_train,y_train);%拟合训练集
outputs = net(x_test);        %输出测试集结果
perf = perform(net,outputs,y_test);  %比较预测和测试集表现
final = round(outputs);      %对测试集结果取整
final = final';             %转置
y_test = y_test';           %转置
k = 0;                      %k为预测(final)和测试集(y_test)相同样本个数
for i = 1:500               %循环 相同则k加一if final(i,1) == y_test(i,1)k = k+1;end
end
fprintf('算法准确率为: %2.2f%%\n', mean(double(k/500)) * 100) %打印算法准确率

这其中要说明的是此处建立了三层神经网络,结果可以在下面看,隐含层神经元选取了8个,网上有不少公式计算选取神经元,但还是自己试试比较好,调参还是要看实际情况的,跑出来结果好,这个参数就好。传递函数的选取也是一样的道理。至于为什么要转置,是因为matlab的神经网络默认是按列选取,当然也可以按行,此处习惯按列了。

还有一个比较重要的点是,一定要用训练集去拟合模型,测试集去测试,不能再用训练集去测试,这反映不出模型对新数据的预测能力,同时还有可能反映不出对原有训练集过度拟合的现象。

四.结果


这个图就是神经网络的预设图,三层,输入层5个神经元,隐含层8个神经元,输出层1个神经元。

运行时会跳出神经网络工具箱,Epoch为迭代次数,PERFORMANCE为误差表现。


差不多在1000次迭代之后误差就很难继续缩小了,拟合已经完毕,这个时候已经可以按stop停止训练了。


这是最后得到的准确率,500个测试样本中测试成功的样本有441个,对于这个数据集来说效果还是可以的。

这是我最后输出的工作区,其中5449个训练样本是我再一次运用SMOTE算法之后得到的训练总样本数,此时已经有1000多个w类样本,可惜如同我预测的一样,再进行新样本的生成已经不能使模型获得更新的信息,模型拟合已然到达极限。

后记(2021年5月)

现在回过头来看这个提供的SMOTE算法,其实最大的问题就是没有提供修改抽样比例的接口,我也不建议大家在源代码上修改,如果还要解决这种不平衡问题请使用python的imblearn库里预设的各类SMOTE算法,支持直接修改抽样比例,适用性也更加广泛。
另外,虽然这种方法能使你的测试集上的表现提高,但并不意味着你在新的数据集上的表现良好!!!!!!
这种方法很容易产生过拟合问题,泛化能力不行,写论文展现一下技巧可以,投入实际解决问题还请慎重。

(新手向)在matlab中运用SMOTE和前馈神经网络对wilt(枯萎)数据集进行机器学习相关推荐

  1. matlab中的神经网络怎么用,matlab如何编写神经网络

    1.matlab中神经网络怎么使用 可以直接用神经网络工具箱,GUI内设置训练的输入.目标.训练方法.迭代次数等. 谷歌人工智能写作项目:小发猫 2.matlab神经网络工具箱怎么使用训练好的神经网络 ...

  2. MATLAB中关于复矩阵的操作,新手易错

    MATLAB中关于复矩阵的操作,新手易错 MATLAB复数操作与实数操作略有不同,尤其是关于共轭转置. 先定义复矩阵: // A code block A = [1+2i 2+3i;3+4i 5+8i ...

  3. tyvector在matlab中代表,MATLAB曲线绘制

    信号源产生的方法 来源:http://www.2cto.com/kf/201401/270494.html  matlab的checkerboard说明,GOOD! 来源:http://www.chi ...

  4. matlab中水平垂直线,关于Matlab:水平-垂直线

    我是Matlab的新手. 我有一个图像块,如下图所示: 白色显示像素的值等于1,黑色显示像素的值等于0, 我想获取vertical only lines. 这意味着应删除水平线,如下所示: 我也想得到 ...

  5. 如何在matlab中表示e,Matlab中表达e的操作方法介绍

    有的新手朋友使用Matlab计算过程里,表示还不会表达e,其实很简单的,今天小编就专门为大家分享Matlab中表达e的操作方法,希望可以帮助到大家. 问题 打开Matlab之后,在命令行窗口中直接输入 ...

  6. matlab 梯度图像,在matlab中快速计算图像的梯度

    感谢您的所有答案和有用的建议.我接受了pseudoDust,Hugues,Dima和High Performance Mark的建议并编写了我自己的代码.我的代码如下: clc;clear all;c ...

  7. matlab 矩阵角标,MATLAB中的矩阵索引

    MATLAB中的矩阵索引 作者:SteveEddins and Loren Shure   译:王茂春 利用矩阵的索引取出原矩阵的子集元素是一种有效的方式.MATLAB的多种索引类型不仅强大.灵活,而 ...

  8. matlab 报错 保留变量,matlab中明明定义了函数变量总是报错

    matlab定义符号函数 functiony=ff(t)t=input('t=');ift>=0y=sym('1');elsey=sym('0');end matlab中如何定义函数 matla ...

  9. 将z的第二列除以根号三MATLAB,matlab中如何用牛顿法求根号2的近似值

    如何用matlab求出图中各条直线的斜率 1.瞬时斜率:求导.方法:d(k)=(u(k)-u(k-1))/T(k);d(0)=0;其中d就是瞬时斜率2.平均斜率:求拟合.方法:p=polyfit(x, ...

最新文章

  1. 欧盟如何运用AI之力推动社会创新
  2. html img 指定旋转角度_ALLEN老师自动化测试小课堂 | 生成HTML可视化报告的两个常见模块...
  3. 我们看到一些知乎大V,开始拍视频了
  4. android通用adapter,Android通用ListViewAdapter的编写。
  5. hadoop中MapReduce多种join实现实例分析
  6. bootstraptable 数字不换行_不知道这些数据录入技巧,你就凹凸了!|Excel093
  7. SQL Server 填充因子
  8. Android 屏幕画笔实现
  9. 360插件化方案RePlugin学习笔记-插件与宿主间的通信方式
  10. 银行购房按揭贷款利息计算
  11. 【C++】学习笔记草稿版系列10(友元)
  12. bbr是什么?有什么用?如何安装使用?
  13. 最近所学的Json以及ajax的应用
  14. Java JNA (三)—— 结构体使用及简单示例
  15. 暗影精灵4适合计算机专业,暗影精灵4什么时候出?今日发布,为专业电竞而生...
  16. 最强的志愿军战俘:炸掉一飞机美军后逃离
  17. micropython教程nucleo-f767zi开发板_NUCLEO-F767ZI开发板评测 - 全文
  18. pci数据捕获和信号处理控制器的驱动安装解决方法(联想T410i隐藏分区故障引起的一系列问题)
  19. OpenERP的淘宝ERP方案
  20. 成都信息工程大学计算机科学与技术考研,【上岸经验】成都信息工程大学计算机考研难度大吗?...

热门文章

  1. uploader.lib php,Lib/Upload.php · 跳跳虎1986/cwj - Gitee.com
  2. 字节也开始缩招了...
  3. java定时开始和关闭_springboot自带定时器实现定时任务的开启关闭以及定时时间可以配置详解...
  4. mp4视频无法播放的解决方法
  5. 编译原理之词法分析、语法分析、语义分析
  6. IB/A-Level/美国+AP三大主流课程有哪些国际学校?
  7. 从程序员到项目经理(5):程序员加油站 -- 不是人人都懂的学习要点--------转自西西吹雪...
  8. pandoc按格式转换md为doc
  9. 经常听别人说安全测试很重要,然鹅你并不了解?一文带你了解全貌
  10. 关于IIC初始化后就进入busy状态的问题