精华内容
下载资源
问答
  • 代码分类

    千次阅读 2019-08-17 12:17:03
    代码分类 最近对写代码的思路和逻辑有一些思考,觉得代码需要分类来编写,现在觉得大致可分四类, 第一类是技术功能代码,这种代码与业务,与要实现的系统完全没有依赖,各个编程语言标准库,框架都属于此类,这类...

    代码分类

    最近对写代码的思路和逻辑有一些思考,觉得代码需要分类来编写,现在觉得大致可分四类,

    第一类是技术功能代码,这种代码与业务,与要实现的系统完全没有依赖,各个编程语言标准库,框架都属于此类,这类代码尽量按不同技术进行独立,彼此没有依赖,需要编写较多的测试代码,保证代码的正确性。如实在需要大量类型组合出需要的功能,如Web框架,设计的功能很多,则应该使用接口,尽量隔离不同的功能,技术。

    第二类是业务中功能的实现代码,这种代码需要实现业务逻辑,一般会存取业务数据,转换数据结构,检查数据是否符合要求,调用功能类库等,这类代码关联的东西很多,需要做到尽量简单,等分离出去的尽量分离出去,简单一来不容易出问题,二来只需要少量测试即可保证这部分代码的正确性;

    第三类是针对业务逻辑对功能类库进行封装的类库,有的业务逻辑中一个功能,可能需要某种类库做大量动作,例如业务中需要定制的图像处理功能,可能需要进行数十行至两三百行图像处理类库的调用,然而这些代码实现的功能,在业务逻辑中是不可分割的一个步骤,因此可以独立出来,作为包装类库,也需要编写一定量的测试代码,保证正确性。

    第四类是业务逻辑组合代码,一个系统会有多个业务逻辑,他们的组合规则,也可以被独立出来,以方便扩展和修改业务逻辑。

    展开全文
  • 利用机器学习进行恶意代码分类

    千次阅读 2019-01-25 22:05:49
    偶然看见2015年微软在kaggle上发起的恶意代码分类比赛,并提供超过500G的源码 早期反病毒软件均采用单一的特征匹配方法,利用特征串完成检测。 此次比赛冠军采用三个黄金特征:恶意代码图像,OpCode n-gram, ...

    背景

    偶然看见2015年微软在kaggle上发起的恶意代码分类比赛,并提供超过500G的源码

    早期反病毒软件均采用单一的特征匹配方法,利用特征串完成检测。

    此次比赛冠军采用三个黄金特征:恶意代码图像,OpCode n-gram, Headers个数

    并且使用xgboost和pypy加快训练速度

    转载当年乌云的一篇文章留底

    最近在Kaggle上微软发起了一个恶意代码分类的比赛,并提供了超过500G的数据(解压后)。有意思的是,取得第一名的队伍三个人都不是搞安全出身的,所采用的方法与我们常见的方法存在很大不同,展现了机器学习在安全领域的巨大潜力。在仔细读完他们的代码和相关的论文后,我简单的进行了一些总结与大家分享。

    需要指出的是,(1)比赛的主题是恶意代码的分类,不是病毒查杀(2)比赛采用的方法是纯静态分析的方法,不涉及行为分析等动态分析方法。

    因此这不意味着这个方法能够取代现有的方法,但是了解它能够为安全研究人员提供一个崭新的思路,至于能否在工业界应用仍待进一步研究。

    0x01 总览


    背景

    80年代末期,随着恶意代码的诞生,反恶意代码软件(或称反病毒软件)随之诞生。这个时期的恶意代码所采用的技术较为简单,这使得对应的检测技术也较为容易,早期的反病毒软件大都单一的采用特征匹配的方法,简单的利用特征串完成检测。随着恶意代码技术的发展,恶意代码开始在传播过程中进行变形以躲避查杀,此时同一个恶意代码的变种数量急剧提升,形态较本体也发生了较大的变化,反病毒软件已经很难提取出一段代码作为恶意代码的特征码。在这种情况下,广谱特征码随之诞生,广谱特征码将特征码进行了分段,通过掩码字节对需要进行比较的和不需要进行比较的区段进行划分。然而无论是特征码扫描还是广谱特征,都需要在获得恶意代码样本后,进行特征的提取,随后才能进行检测,这使得对恶意代码的查杀具有一定的滞后性,始终走在恶意代码的后面。为了针对变种病毒和未知病毒,启发式扫描应运而生,启发式扫描利用已有的经验和知识对未知的二进制代码进行检测,这种技术抓住了恶意代码具有普通二进制文件所不具有的恶意行为,例如非常规读写文件,终结自身,非常规切入零环等等。启发式扫描的重点和难点在于如何对恶意代码的恶意行为特征进行提取。特征码扫描、查找广谱特征、启发式扫描,这三种查杀方式均没有实际运行二进制文件,因此均可归为恶意代码静态检测的方法。随着反恶意代码技术的逐步发展,主动防御技术、云查杀技术已越来越多的被安全厂商使用,但恶意代码静态检测的方法仍是效率最高,被运用最广泛的恶意代码查杀技术。

    数据格式

    微软提供的数据包括训练集、测试集和训练集的标注。其中每个恶意代码样本(去除了PE头)包含两个文件,一个是十六进制表示的.bytes文件,另一个是利用IDA反汇编工具生成的.asm文件。如下图所示

    enter image description here

    方法简述

    Kaggle比赛中最重要的环节就是特征工程,特征的好坏直接决定了比赛成绩。在这次Kaggle的比赛中冠军队伍选取了三个“黄金”特征:恶意代码图像、OpCode n-gramHeaders个数,其他一些特征包括ByteCode n-gram,指令频数等。机器学习部分采用了随机森林算法,并用到了xgboostpypy加快训练速度。

    本文主要关注恶意代码图像和OpCode n-gram,以及随机森林算法的应用。

    0x02 恶意代码图像


    这个概念最早是2011年由加利福尼亚大学的NatarajKarthikeyan在他们的论文 Malware Images: Visualization and Automatic Classification 中提出来的,思路非常新颖,把一个二进制文件以灰度图的形式展现出来,利用图像中的纹理特征对恶意代码进行聚类。此后,有许多研究人员在这个思路基础上进行了改进和探索。就目前发表的文章来看,恶意代码图像的形式并不固定,研究人员可根据实际情况进行调整和创新。

    国内这方面的研究较少,去年在通信学报上有一篇《基于纹理指纹的恶意代码变种检测方法研究》,是由北京科技大学的韩晓光博士和北京启明星辰研究院等合作发表的,目测也是仅有的一篇。

    本节介绍最简单的一种恶意代码图像绘制方法。对一个二进制文件,每个字节范围在00~FF之间,刚好对应灰度图0~255(0为黑色,255为白色)。将一个二进制文件转换为一个矩阵(矩阵元素对应文件中的每一个字节,矩阵的大小可根据实际情况进行调整),该矩阵又可以非常方便的转换为一张灰度图。

    python代码如下

    #!python
    import numpy
    from PIL import Image
    import binascii
    def getMatrixfrom_bin(filename,width):
        with open(filename, 'rb') as f:
            content = f.read()
        hexst = binascii.hexlify(content)  #将二进制文件转换为十六进制字符串
        fh = numpy.array([int(hexst[i:i+2],16) for i in range(0, len(hexst), 2)])  #按字节分割
        rn = len(fh)/width
        fh = numpy.reshape(fh[:rn*width],(-1,width))  #根据设定的宽度生成矩阵
        fh = numpy.uint8(fh)
        return fh
    filename = "your_bin_filename"
    im = Image.fromarray(getMatrixfrom_bin(filename,512)) #转换为图像
    im.save("your_img_filename.png")
    

    利用该代码生成的几种病毒样本图像如下所示

    enter image description here

    用肉眼可看出,同一个家族的恶意代码图像在纹理上存在一定的相似性,不同的恶意代码家族是有一定区别的。如何用计算机发现和提取这些纹理的相似特征用以分类呢?这就需要用到计算机视觉里的一些技术了。在NatarajKarthikeyan的论文中采用的是GIST特征GIST特征常用于场景分类任务(如城市、森林、公路和海滩等),用一个五维的感知维度来代表一个场景的主要内容(详情请参考文献[xx])。简单来说,输入图像,输出为对应的GIST描述符,如下图所示

    enter image description here

    matlab实现里面每个图像的GIST描述符都用一个向量表示,最后用SVM完成分类训练。

    enter image description here

    这已经远远超出了场景识别所能做的。不过,国外有学者利用一些类似前文生成那种不规则图像来欺骗深度学习模型,如下图所示

    enter image description here

    详情请参考@王威廉老师的微博。当然,二者并没有什么直接关联,因为基于深度学习的图像识别系统的训练数据是一些有意义的图像。但这是一个非常有意思的巧合,至于基于深度学习的图像识别能否用于恶意代码图像的特征提取和分类,我认为是一个潜在的研究点,所能做的也不局限于此,如果有做深度学习的朋友可以伙同做安全的朋友一起研究交流。

    0x03 OpCode n-gram


    n-gram是自然语言处理领域的概念,早期的语音识别技术和统计语言模型与它密不可分。n-gram基于一个简单的假设,即认为一个词出现的概率仅与它之前的n-1个词有关,这个概率可从大量语料中统计得到。例如“吃”的后面出现“苹果”或“披萨”的概率就会比“公路”的概率大(正常的语料中基本不会出现“吃公路”这种组合),可以看出n-gram在一定程度上包含了部分语言特征。

    n-gram应用于恶意代码识别的想法最早由Tony等人在2004年的论文N-gram-based Detection of New Malicious Code 中提出,不过他们的方法是基于ByteCode的。2008年Moskovitch等人的论文Unknown Malcode Detection Using OPCODE Representation 中提出利用OpCode代替ByteCode更加科学。

    具体来说,一个二进制文件的OpCode n-gram如下图所示

    enter image description here

    针对这次Kaggle比赛提供的数据,用python提取出其n-gram特征

    #!python
    import re
    from collections import *
    # 从.asm文件获取Opcode序列
    def getOpcodeSequence(filename):
        opcode_seq = []
        p = re.compile(r'\s([a-fA-F0-9]{2}\s)+\s*([a-z]+)')
        with open(filename) as f:
            for line in f:
                if line.startswith(".text"):
                    m = re.findall(p,line)
                    if m:
                        opc = m[0][10]
                        if opc != "align":
                            opcode_seq.append(opc)
        return opcode_seq
    # 根据Opcode序列,统计对应的n-gram
    def getOpcodeNgram(ops ,n = 3):
        opngramlist = [tuple(ops[i:i+n]) for i in range(len(ops)-n)]
        opngram = Counter(opngramlist)
        return opngram
    file = "train/0A32eTdBKayjCWhZqDOQ.asm"
    ops = getOpcodeSequence(file)
    opngram = getOpcodeNgram(ops)
    print opngram
    # output
    # Counter({('mov', 'mov', 'mov'): 164, ('xor', 'test', 'setnle'): 155...
    

    0x04 决策树和随机森林


    决策树

    决策树在我们日常生活中无处不在,在众多机器学习的书籍中提到的一个例子(银行预测客户是否有能力偿还贷款)如下图所示

    enter image description here

    在这个在决策树中,非叶子结点如“拥有房产”、“是否结婚”就是所谓的特征,它们是依靠我们的知识人工提取出来的特征。但如果对某个领域不了解,特征数量又较多时,人工提取特征的方法就不可行了,需要依靠算法来寻找合适的特征构造决策树。

    限于篇幅,决策树的构造等过程本文不进行展开,网上相关资源非常多。(只要能够充分理解熵和信息增益的概念,决策树其实非常简单)

    随机森林

    随机森林是一个非常强大的机器学习方法,顾名思义,它是用随机的方式建立一个森林,森林里面有很多的决策树组成,随机森林的每一棵决策树之间是没有关联的。在得到森林之后,当有一个新的输入样本进入的时候,就让森林中的每一棵决策树分别进行一下判断,预测这个样本应该属于哪一类(对于分类算法),然后看看哪一类被选择最多,就预测这个样本为那一类。

    随机森林的思想与Adaboost里面的弱分类器组合成强分类器的思想类似,是一种“集体智慧”的体现。例如,屋子里面有n个人,每个人作出正确判断的概率为p(p略高于0.5,这时每个人可视为一个弱分类器),他们判断的过程独立互不影响,最终以多数人的判断为准。这里我们不从数学上来推导,类比抛硬币,对一枚均匀的硬币,抛n次的结果中,正面和反面的次数是差不多的。而对一枚不均匀的硬币,若出现正面的概率略大于反面,抛n次的结果中出现正面次数比反面次数多的概率就会很大。所以即使每个分类器的准确度不高,但是结合在一起时就可以变成一个强分类器。

    enter image description here

    如图所示,将训练数据有放回的抽样出多个子集(即随机选择矩阵中的行),当然在特征选择上也可以进行随机化(即随机选择矩阵中的列,图中没有体现出来),分别在每个子集上生成对应的决策树

    enter image description here

    决策过程如下图所示(忽略画风不一致的问题...)

    enter image description here

    0x05 冠军队伍的实现细节


    ASM文件图像

    但是在Kaggle比赛中冠军队伍采用的方法并不是从二进制文件生成的图像,也不是从.bytes文件,竟然是从.asm文件生成的图像,他们也没有使用GIST特征,而是使用了前800个像素值作为特征,让人非常费解。

    我专门给队伍里的Jiwei Liu同学发了一封邮件进行咨询,他给我的答复是:GIST特征与其他特征综合使用时影响整体效果,所以他们放弃了GIST特征,另外使用.asm文件生成图像纯属意外发现...

    至于为什么是前800个像素,他的解释是通过反复交叉验证得出的,具体原因不清楚。(在后文的分析中我会谈谈我的一些看法)

    OpCode n-gram

    这部分的实现不复杂,他们选取n=4,在具体的特征选择上通过计算信息增益选取每个分类与其他分类区分度最高的750个特征。

    其他特征

    其他一些特征包括统计Headers,Bytecode n-gram(n=2,3,4),分析指令流(将每个循环固定展开5次)来统计指令频数,这些特征虽然不像前面提到的特征那么有效,但是确实可以在一定程度上提升最终成绩。

    0x06 实验


    冠军队伍的代码是为了参加比赛而写的,时间仓促,又是多人合作完成,导致组织结构很乱,且基本没有注释,可读性较差。更重要的是自己想动手实践一下,所以按照他们的思路写了几个简单的程序,忽略了一些处理起来比较复杂或者难以理解的过程,代码可以在我的github上下载

    由于只是做一些简单的试验,不需要太多的数据(否则速度会非常慢),我从微软提供的训练数据中抽取了大概1/10左右的训练子集,其中从每个分类的中都随机抽取了100个样本(9个分类,每个样本2个文件,共1800个文件),这样也不需要用到pypyxgboost,只需要用到numpypandasPILscikit-learn这些库即可

    友情提示:要进行这个实验,首先确保有一个比较大的硬盘,推荐使用Linux系统。

    训练子集

    这一步需要提前将完整训练集解压好,数量庞大,时间比较久。

    #!python
    import os
    from random import *
    import pandas as pd
    import shutil
    rs = Random()
    # 读取微软提供的训练集标注
    trainlabels = pd.read_csv('trainLabels.csv')
    fids = []
    opd = pd.DataFrame()
    for clabel in range (1,10):
        # 筛选特定分类
        mids = trainlabels[trainlabels.Class == clabel]
        mids = mids.reset_index(drop=True)
        # 在该分类下随机抽取100个
        rchoice = [rs.randint(0,len(mids)-1) for i in range(100)]
        rids = [mids.loc[i].Id for i in rchoice]
        fids.extend(rids)
        opd = opd.append(mids.loc[rchoice])
    opd = opd.reset_index(drop=True)
    # 生成训练子集标注
    opd.to_csv('subtrainLabels.csv', encoding='utf-8', index=False)
    # 将训练子集拷贝出来(根据实际情况修改这个路径)
    sbase = 'yourpath/train/'
    tbase = 'yourpath/subtrain/'
    for fid in fids:
        fnames = ['{0}.asm'.format(fid),'{0}.bytes'.format(fid)]
        for fname in fnames:
            cspath = sbase + fname
            ctpath = tbase + fname
            shutil.copy(cspath,ctpath)
    

    特征抽取

    本实验中只用到了.asm文件,用到了.asm文件图像特征(前1500个像素)和OpCode n-gram特征(本实验取n=3,将总体出现频数大于500次的3-gram作为特征保留),实现代码与前文基本一致,具体细节可参考完整代码。

    scikit-learn

    因为scikit-learn的存在,将机器学习算法应用到其他领域变得非常方便快捷。例如我们已经抽取了这些恶意代码的OpCode n-gram特征("3gramfeature.csv"),利用scikit-learn即可快速训练一个随机森林

    #!python
    from sklearn.ensemble import RandomForestClassifier as RF
    from sklearn import cross_validation
    from sklearn.metrics import confusion_matrix
    import pandas as pd
    subtrainLabel = pd.read_csv('subtrainLabels.csv')
    subtrainfeature = pd.read_csv("3gramfeature.csv")
    subtrain = pd.merge(subtrainLabel,subtrainfeature,on='Id')
    labels = subtrain.Class
    subtrain.drop(["Class","Id"], axis=1, inplace=True)
    subtrain = subtrain.as_matrix()
    # 将训练子集划分为训练集和测试集 其中测试集占40%
    X_train, X_test, y_train, y_test = cross_validation.train_test_split(subtrain,labels,test_size=0.4)
    # 构造随机森林 其中包含500棵决策树
    srf = RF(n_estimators=500, n_jobs=-1)
    srf.fit(X_train,y_train)  # 训练
    print srf.score(X_test,y_test)  # 测试
    

    实验结果

    这里只对预测的准确度做一个简单的评判。

    在只应用.asm文件图像特征(firstrandomforest.py)或者Opcode n-gram特征(secondrandomforest.py)的情况下,以及二者相结合的情况(combine.py),准确率如下所示

    enter image description here

    由于随机森林训练的过程中存在一定的随机性,因此每次结果不一定完全相同,但总的来说,二者结合的准确率通常要高出许多,基本可以达到98%以上的准确率,而且别忘了我们只用了不到1/10的数据

    为什么是前800像素

    观察.asm文件的格式,开头部分其实是IDA生成的一些信息,如下图所示

    enter image description here

    可以目测这个长度已经超出了800个像素(800个字节),实际上这800个像素和反汇编代码没有关系!完全就是IDA产生的一些信息,更进一步的说,实际上冠军队伍的方法压根与恶意代码图像没有关系,实际上是用到了IDA产生的信息。

    但是仔细观察这些IDA信息,貌似长的都差不多,也没有什么有价值的信息,为什么可以有效区分恶意软件类型呢?

    一个大胆的猜想是微软提前将这些恶意代码分好类,在调用IDA进行反汇编的时候是按照每个分类的顺序进行的,由于未知的原因可能导致了这些IDA信息在不同分类上有细微差别,恰好能作为一个非常有效的特征!

    0x07 其他


    • 好的方法总是简单又好理解的。这次Kaggle比赛也是如此,冠军队伍的方法没有特别难理解的部分。但是请注意:面上的方法并不能体现背后难度和工作量,真正复杂和耗时的部分在于特征选择和交叉验证上。比如他们最终放弃GIST特征正是经过反复对比验证才做出的决定。
    • 这次的Kaggle比赛归根结底还是比赛,最终目标是取得最好成绩,不代表这个方法在实际中一定好用。
    • 放弃GIST特征告诉我们一个宝贵的经验,并不是某个特征好就一定要用,还要考虑它和其他特征综合之后的效果。
    • 比赛的数据是去除了PE头的,而输入输出表对分析恶意代码是很有帮助的,假如微软提供的数据包含了PE头,将输入输出表作为特征,最终的结果应该还能进一步提升。
    • 这个方法的能够发现一些静态方法发现不了的变种,但对于未知的新品种依然无能为力(没有数据,机器学习巧妇难为无米之炊...)
    • 可以尝试将该方法应用到Android和IOS平台的恶意代码检测中。

    0x08 资源和参考资料


    比赛说明和原始数据

    https://www.kaggle.com/c/malware-classification/

    冠军队伍相关资料

    本文代码

    https://github.com/bindog/ToyMalwareClassification

    参考资料

    Malware Images: Visualization and Automatic Classification

    Detecting unknown malicious code by applying classification techniques on OpCode patterns(墙裂推荐)

    如何使用GIST+LIBLINEAR分类器提取CIFAR-10 dataset数据集中图像特征,并用测试数据进行实验

    GIST特征描述符使用

    随机森林算法

    How Random Forest algorithm works

    Supervised Classification with k-fold Cross Validation on a Multi Family Malware Dataset

     

    展开全文
  • 代码错误分类

    千次阅读 2012-11-09 16:28:45
    代码错误可以分为两个方面:性能问题,功能错误。  性能问题又可以分为时间性能和空间性能。时间性能就是执行效率不符合预期。空间性能就是所占用的资源超出预期。由于单元测试面对的测试目标是比较小的代码单元,...

           代码错误可以分为两个方面:性能问题,功能错误。

           性能问题又可以分为时间性能和空间性能。时间性能就是执行效率不符合预期。空间性能就是所占用的资源超出预期。由于单元测试面对的测试目标是比较小的代码单元,时间性能和空间性能比较难于衡量,所以单元测试一般不测试性能问题。性能问题应该在系统测试或者性能测试的时候来完成。

            单元测试主要测试代码的功能错误。功能错误就是程序没有实现正确的功能,它的行为不是我们所预期的,具体来说就是某种输入下没有产生我们想要的输出。崩溃也是一种功能错误的输出错误。

    功能错误可以分为有特征和无特征错误两种。有特征错误又可以进一步分为行为特征和语法特征错误。

    行为特征错误是指代码在执行的过程中产生的、具有可捕获的特征的错误,例如崩溃或者超时。

    语法特征错误是指代码中含有某些语法特征,这些特征可能含有潜在错误,例如在条件表达式当中使用了赋值操作符。

             

            软件开发有一个有趣的现象:错误越小,麻烦越大。如果一个程序,一启动就崩溃,那是大错误,但容易发现,容易定位,也容易解决。如果错误只是在某种不常见的输入下表现出来,好像是小错误,但修正的成本往往极大,尤其是用户在应用中发现的错误。

            对于一个代码单元,常见的错误是部分错误,是指对部分输入处理正确,对部分输入处理错误。例如一个函数有十类可能输入,代码对其有的五六类做了正确处理,两三类的处理含有错误,还有一两类输入则在编码时没有想到,未进行处理。

    展开全文
  • 鸢尾花分类matlab代码

    万次阅读 多人点赞 2020-03-01 20:16:06
    鸢尾花分类matlab代码 本文是基于matlab平台的libsvm工具箱进行的,是羊同学的练手做,代码编写不太仔细,欢迎大家斧正。 一、Iris数据集介绍 Iris 鸢尾花数据集是一个经典数据集,在统计学习和机器学习领域都经常...

    鸢尾花分类matlab代码

    本文是基于matlab平台的libsvm工具箱进行的,是羊同学的练手做,代码编写不太仔细,欢迎大家斧正。

    一、Iris数据集介绍

    Iris 鸢尾花数据集是一个经典数据集,在统计学习和机器学习领域都经常被用作示例。数据集内包含 3 类共 150 条记录,每类各 50 个数据,每条记录都有 4 项特征:花萼长度、花萼宽度、花瓣长度、花瓣宽度,可以通过这4个特征预测鸢尾花卉属于(iris-setosa, iris-versicolour, iris-virginica)中的哪一品种。
    由于本数据集十分的典型,羊同学便采用了本数据集。
    我们通过以下两条命令简单的观察一下该数据集的形式:

    load Iris
    head Iris
    

    得到结果如下:

    ans =
    
      8×6 table
    
        Id    SepalLengthCm    SepalWidthCm    PetalLengthCm    PetalWidthCm      Species  
        __    _____________    ____________    _____________    ____________    ___________
    
        1          5.1             3.5              1.4             0.2         Iris-setosa
        2          4.9               3              1.4             0.2         Iris-setosa
        3          4.7             3.2              1.3             0.2         Iris-setosa
        4          4.6             3.1              1.5             0.2         Iris-setosa
        5            5             3.6              1.4             0.2         Iris-setosa
        6          5.4             3.9              1.7             0.4         Iris-setosa
        7          4.6             3.4              1.4             0.3         Iris-setosa
        8            5             3.4              1.5             0.2         Iris-setosa
    

    二、代码分析

    2.1 标签数据化

    为了方便,我们将标签数据化处理。我们可通过unique()函数查看类别数。

    unique(Iris.Species)
    

    可以得到结果:

    ans = 
    
      3×1 categorical 数组
    
         Iris-setosa 
         Iris-versicolor 
         Iris-virginica 
    

    所以羊同学随手把三种类别转换为了1、2、3。

    %% 将类别数据化
    num = length(Iris.Species);
    label = [];
    for i = 1:num
        switch Iris.Species(i)
            case 'Iris-setosa'
                label(i) = 1;
            case 'Iris-versicolor'
                label(i) = 2;
            case 'Iris-virginica '
                label(i) = 3;
        end
    end
    label = label';
    data = [Iris.SepalLengthCm,Iris.SepalWidthCm,Iris.PetalLengthCm,Iris.PetalWidthCm];
    

    2.2 可视化分析

    羊同学决定对数据进行简单的可视化分析,对数据的情况有个整体的把握,主要从以下几个方面进行:

    • 相关系数热度图
    • 箱型图
    • 散点图

    2.2.1 相关系数热度图

    RHO = corr(data);
    name =  Iris.Properties.VariableNames(2:5);
    heatmap(name,name,RHO);
    colormap hot
    

    其结果如图:
    在这里插入图片描述
    由此可发现PetalLengthCm和PetalWidthCm相关性较强,我们可以删除一组,也可以用PCA提取主成分消除独立性。不过由于羊同学很懒,就直接不做了,有兴趣的同学可以试试看,效果会不会变好。

    2.2.2 箱型图

    boxplot(data,'orientation','horizontal','labels',name);
    

    结果如图:
    在这里插入图片描述

    2.2.3 散点图

    one2six = 1:4;
    comb = combntns(one2six,2);
    index_1 = find(label==1);
    index_2 = find(label==2);
    index_3 = find(label==3);
    figure
    hold on
    for i = 1:6
        subplot(2,3,i)
        scatter(data(index_1,comb(i,1)),index_1,data(comb(i,2)),'fill','r');
        hold on
        scatter(data(index_2,comb(i,1)),index_2,data(comb(i,2)),'fill','g');
        hold on 
        scatter(data(index_3,comb(i,1)),index_3,data(comb(i,2)),'fill','b');
        title([name{comb(i,1)},' and ',name{comb(i,2)}]);
        legend('Iris-setosa','Iris-versicolor','Iris-virginica','location','best');
    end
    hold off
    

    结果如图:
    在这里插入图片描述

    2.3 数据集的准备

    2.3.1 训练集和测试集的划分

    羊同学随手划分了一下,由于样本数不多感兴趣的同学也可以采用k-fold crossValidation方法。

    train_data = [data(1:40,:);data(51:90,:);data(101:140,:)];
    train_label = [label(1:40,:);label(51:90,:);label(101:140,:)];
    test_data = [data(1:40,:);data(51:90,:);data(101:140,:)];
    test_label = [label(1:40,:);label(51:90,:);label(101:140,:)];
    

    2.3.2 数据预处理

    使用mapminmax函数时,注意它的归一化方法。在归一化前记得转置。

    [mtrain,ntrain] = size(train_data);
    [mtest,ntest] = size(test_data);
    
    dataset = [train_data;test_data];       % mapminmax为MATLAB自带的归一化函数
    [dataset_scale,ps] = mapminmax(dataset',0,1);      %归一化要先转至
    dataset_scale = dataset_scale';
    
    train_data = dataset_scale(1:mtrain,:);
    test_data = dataset_scale( (mtrain+1):(mtrain+mtest),: );
    

    2.4 SVM网络的训练与预测

    羊同学先不调整任何参数,直接使用默认参数进行训练,看看效果:

    %% SVM网络训练
    model = svmtrain(train_label, train_data,'-c 2 -g 1');
    
    %% SVM网络预测
    [predict_label, accuracy,desc_value] = svmpredict(test_label, test_data, model);  % desc_value !!
    

    注意:libsvm工具箱由于版本不同会有一定的不同,新版本的预测函数需要添加dec_value,不然会运算报错。

    2.5 预测结果分析

    2.5.1 svmpredict函数结果

        optimization finished, #iter = 30
        nu = 0.410476
        obj = -48.386381, rho = 0.160529
        nSV = 34, nBSV = 31
        Total nSV = 43
        Accuracy = 96.6667% (116/120) (classification)
    

    由此我们可以看到正确率达到了96.6667%,有种勉勉强强的感觉呢。

    2.5.2 预测结果可视化

        figure;
        hold on;
        plot(test_label,'o');
        plot(predict_label,'r*');
        xlabel('测试集样本','FontSize',12);
        ylabel('类别标签','FontSize',12);
        legend('实际测试集分类','预测测试集分类');
        title('测试集的实际分类和预测分类图','FontSize',12);
        grid on;
    

    结果如图:
    在这里插入图片描述
    通过图可以看出只有一个测试样本是被错分的。就这样简单的libsvm模型就完成了。当然还可以对其进行许多方面的优化,最重要的一点就是对于libsvm参数模型的优化。

    三、模型优化

    3.1 libsvm训练参数简介

    Options:可用的选项即表示的涵义如下

    • -s svm类型:SVM设置类型(默认0)
    • 0 – C-SVC
    • 1 --v-SVC
    • 2 – 一类SVM
    • 3 – e -SVR
    • 4 – v-SVR
    • -t 核函数类型:核函数设置类型(默认2)
    • 0 – 线性:u’v
    • 1 – 多项式:(r*u’v + coef0)^degree
    • 2 – RBF函数:exp(-r|u-v|^2)
    • 3 –sigmoid:tanh(r*u’v + coef0)
    • -d degree:核函数中的degree设置(针对多项式核函数)(默认3)
    • -g r(gama):核函数中的gamma函数设置(针对多项式/rbf/sigmoid核函数)(默认1/ k)
    • -r coef0:核函数中的coef0设置(针对多项式/sigmoid核函数)((默认0)
    • -c cost:设置C-SVC,e -SVR和v-SVR的参数(损失函数)(默认1)
    • -n nu:设置v-SVC,一类SVM和v- SVR的参数(默认0.5)
    • -p p:设置e -SVR 中损失函数p的值(默认0.1)
    • -m cachesize:设置cache内存大小,以MB为单位(默认40)
    • -e eps:设置允许的终止判据(默认0.001)
    • -h shrinking:是否使用启发式,0或1(默认1)
    • -wi weight:设置第几类的参数C为weight*C (C-SVC中的C) (默认1)
    • -v n: n-fold交互检验模式,n为fold的个数,必须大于等于2
      其中-g选项中的k是指输入数据中的属性数。

    option -v 随机地将数据剖分为n部分并计算交互检验准确度和均方根误差。以上这些参数设置可以按照SVM的类型和核函数所支持的参数进行任意组合,如果设置的参数在函数或SVM类型中没有也不会产生影响,程序不会接受该参数;如果应有的参数设置不正确,参数将采用默认值。
    training_set_file是要进行训练的数据集;model_file是训练结束后产生的模型文件,文件中包括支持向量样本数、支持向量样本以及lagrange系数等必须的参数;该参数如果不设置将采用默认的文件名,也可以设置成自己惯用的文件名。

    3.2 利用PSO算法对参数进行优化

    优化后的结果:

    optimization finished, #iter = 40
    nu = 0.518337
    obj = -2741.351977, rho = 0.228981
    nSV = 43, nBSV = 40
    Total nSV = 52
    Accuracy = 97.5% (117/120) (classification)
    打印测试集分类准确率
    Accuracy = 97.5% (117/120)
    

    可视化作图:

    在这里插入图片描述
    在这里插入图片描述

    模型得到了一定程度的优化。

    展开全文
  • 使用BERT进行情感分类预测及代码实例

    万次阅读 多人点赞 2019-05-17 01:46:31
    1.1. clone BERT 代码 1.2. 数据处理 2. 修改代码 因为这次是分类问题, 所以我们需要修改run_classify.py 2.1 加入新的任务类 因为我们是做一个分类的任务, 但是 2.2 任务类注册 3. 运行代码 运行代码...
  • 场景分类MATLAB代码实现

    千次阅读 2017-09-19 21:27:43
    需要声明的是,下面的代码只是一个场景分类的demo,它和论文中提到的思想不一样,但它们可以帮助我们更好地理解论文。 原始代码是基于视觉词袋模型BOW的MATLAB实现的。整个程序的流程如下: 利用SIF
  • 网上有很多图像分类代码,有很多是必须要在GPU上面才能跑的,因为我想在自己的电脑跑,所以很多都是不能用的,而且说实话很多对我这个小白来说,都很难看懂。所以我找了一个就是之间用CNN写的神经卷积模型用来进行...
  • google earth engine(GEE)监督分类总结与代码分享

    千次阅读 多人点赞 2020-05-05 01:46:01
    提供分类代码以及思路整理
  • python做snowNLP文本情感分类代码示例

    千次阅读 2019-08-12 15:48:04
    支持的中文自然语言操作包括: 中文分词 词性标注 情感分析 文本分类 转换成拼音 繁体转简体 提取文本关键词 提取文本摘要 tf,idf Tokenization 文本相似 二、代码示范 下面是snownlp分词、词性标注、...
  • 历久而新,我的新书《第二行代码》已出版!

    万次阅读 多人点赞 2016-11-23 09:49:08
    《第二行代码》中的内容我相信很多人都会非常感兴趣,因为里面确实加入了很多很新的知识。略粗概括一下的话,新增内容就包括有Android Studio、Gradle、Material Design、运行时权限、多窗口模式、RecyclerView、...
  • sklearn常用分类器及代码实现

    千次阅读 2016-12-12 11:07:05
    常用的分类包括SVM、KNN、贝叶斯、线性回归、逻辑回归、决策树、随机森林、xgboost、GBDT、boosting、神经网络NN。 代码如下: from sklearn.metrics import precision_recall_fscore_support def ...
  • python,sklearn,svm,遥感数据分类,代码实例

    千次阅读 多人点赞 2020-04-17 23:31:30
    支持向量机(Support Vector Machine,即SVM)是包括分类(Classification)、回归(Regression)和异常检测(Outlier Detection)等一系列监督学习算法的总称。对于分类,SVM最初用于解决二分类问...
  • 大学生垃圾分类网页制作设计思路知识点应用内容说明代码...三层结构,共11个页面(1个首页、6个二级页面、4个三级页面)网页内容包括:网站首页、产生原因、分类原则、分类意义、垃圾种类、操作流程、在线留言。 代码
  • 关于Win10系统无法安装.NET Framework 3.5(包括.NET 2.0 和 3.0) 关于 错误代码:0x800F0950 2019-06-13 00:07:08LarryPage007阅读数 4668收藏收起 分类专栏:笔记 版权声明:本文为博主原创文章,遵循CC 4.0 BY-...
  • 代码审计

    千次阅读 2018-07-05 15:16:39
    代码审计网是端玛科技联合业界著名的软件安全咨询服务公司Security Innovation、最优秀的源代码安全扫描产品及服务提供商VeraCode、Micro Focus、(ISC)²国际信息系统安全技术联盟、公安部第三研究所——国际技贸、...
  • 恶意代码检测

    千次阅读 2019-12-15 14:08:32
    恶意代码种类 计算机病毒:指寄居在计算机系统中,在一定条件下被执行会破坏系统、程序的功能和数据,影响系统其他程序和自我复制。 蠕虫:也算是一种病毒,它具有自我复制能力并通过计算和网络的负载,消耗有限...
  • 情感分类论文、代码汇总

    千次阅读 2019-03-18 22:09:25
    :淘宝的“问大家”,主要包括美妆、鞋和电子产品这三个领域,每个领域收集了10000条问答对。 标注说明 :对于情感分类的标注结果有三类,分别是positive, negative, neutral,conflict。其中conflict代表这个问答...
  • 一个完整的处理图片分类代码包括以下几部分:导入需要的库,数据预处理,搭建神经网络模型,训练及测试,输出损失和正确率。 导入库 import torch import torchvision from torch.autograd import Variable ...
  • 前文从总结恶意代码检测技术,包括恶意代码检测的对象和策略、特征值检测技术、校验和检测技术、启发式扫描技术、虚拟机检测技术和主动防御技术。这篇文章将介绍基于机器学习的恶意代码检测技术,主要参考郑师兄的...
  • 恶意代码防护

    千次阅读 2018-09-26 10:31:34
    本认证旨在帮助学员了解恶意代码的主要分类及其特点,包括木马、蠕虫、病毒的特征和表现的现象,并了解和掌握恶意代码防护的主要技术和手段。 课程目标:  了解云计算环境下主机可能遭受到的恶意代码分类及特征 ...
  • 随机森林分类和回归python代码 详解

    万次阅读 热门讨论 2019-06-18 11:36:07
    数学的东西直接看代码。 ########################################################################## 下面是给了数据集之后,训练随机森林的过程: 首先,咱们先来看一棵树的成长!确定好这棵...
  • (▲由Python大本营下载自视觉中国)翻译 | 李润嘉校对 | 和中华来源 |数据派THU(ID:DatapiTHU)本教程介绍了用于分类的决策树,即分类树,包括分类...
  • 代码静态分析

    千次阅读 2019-07-28 14:37:51
    代码检查代码检查包括代码走查、桌面检查、代码审查等,主要检查代码和设计的一致性,代码对标准的遵循、可读性,代码的逻辑表达的正确性,代码结构的合理性等方面;可以发现违背程序编写标准的问题,程序中不安全、...
  • 代码覆盖率

    千次阅读 2018-02-11 13:06:47
    分类类的覆盖率:类覆盖描熟了项目中多少类已被测试套件访问。 方法覆盖率:方法覆盖率是被访问的方法的百分比。 语句覆盖率:语句覆盖率追踪单条源代码语句的调用。 语句块覆盖率:语句快覆...
  • 插件实现全代码实现分类加字段全代码实现标签加字段WordPress的分类目录默认只有名称、别名、父节点和描述这几个字段,有时候我们需要给分类目录拓展一些信息,如想添加一个分类封面图、给分类指定keywords和...
  • 机器学习常用的六种分类方法,Python代码详细都在这里! 六种常用分类方法包括两种线性分类及四种非线性分类法,分别是: 一、线性判别分析 from sklearn.model_selection import train_test_split from sklearn....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 466,235
精华内容 186,494
关键字:

代码的种类包括