美文网首页@产品数量遗传或生统Mongo
鸢尾花数据集(KNN、决策树、朴素贝叶斯分析)

鸢尾花数据集(KNN、决策树、朴素贝叶斯分析)

作者: keeeeeenon | 来源:发表于2019-05-05 08:55 被阅读29次

    目录

    1、问题描述

    2、数据准备与数据预处理

    2.1 收集数据

    2.2划分数据集

    3、数据可视化

    4、模型基本原理与算法实现

    4.1 KNN算法基本原理及主程序

    4.2决策树模型算法及基本原理

    4.3朴素贝叶斯算法及基本原理

    5、测试方法与结果

    5.1KNN测试结果

    5.2决策树测试结果

    5.3朴素贝叶斯测试结果

    6.总结

    7.问题

    1、问题描述
    iris是鸢尾植物,这里存储了其萼片和花瓣的长宽,共4个属性,鸢尾植物分三类。假定现在出现了一株鸢尾植物,如何通过其所具有的特征来推断出它属于三类中的哪一类?这就是机器学习中的分类问题了。该数据集一共包含4个特征变量,1个类别变量。共有150个样本,鸢尾有三个亚属,分别是山鸢尾 (Iris-setosa),变色鸢尾(Iris-versicolor)和维吉尼亚鸢尾(Iris-virginica)。

    2、数据准备与数据预处理
    2.1收集数据
    在本次问题过程中,所使用的是一个较经典的数据集,所以在scikit-learn的数据库中可以找到。也可以在UCI数据集上下载完成。

    image.png

    数据集一共分为四个变量,分别为:花萼长度、花萼宽度、花瓣长度、花瓣宽度

    image.png

    2.2划分数据集
    从上面对样本集的输出我们可以看出Iris数据集给出的三种花是按照顺序来的,前50个是第0类,51-100是第1类,101~150是第二类,如果我们分训练集和测试集的时候要把顺序打乱。在这里我们选取120个为训练集,30个为测试集。为实现随机性,选取三个部分的每部分的最后十组数据作为测试集元素。

    train_data = np.concatenate((iris.data[0:40, :], iris.data[50:90, :], iris.data[100:140, :]), axis = 0)  #训练集  
     
    train_target = np.concatenate((iris.target[0:40], iris.target[50:90], iris.target[100:140]), axis = 0)  #训练集样本类别  
     
    test_data = np.concatenate((iris.data[40:50, :], iris.data[90:100, :], iris.data[140:150, :]), axis = 0)  #测试集  
     
    test_target = np.concatenate((iris.target[40:50], iris.target[90:100], iris.target[140:150]), axis = 0) #测试集样本类别  
    

    3.数据可视化
    由于花瓣宽度变化很小,将其省略后根据前三维数据画出散点图,如下所示:

    image.png

    4、模型基本原理与算法实现
    4.1算法基本原理及主程序
    k近邻法是一种基本的多分类和回归的算法,给定一个训练数据集,对新的输入实例,在数据集中找到与该实例最近邻的k个实例,这k个实例的多数属于某个类,就把该输入实例分为这个类。kNN的三要素是k,距离度量和分类决策规则。

    第一步,计算输入实例和数据集各个数据的欧氏距离。
    第二步,将计算的距离按照从小到大排序,统计前k个数据的类别,这里假设k为3,则前3个距离最近的数据类为AAB。
    第三步,将输入实例判断为频率最高的类,本例中A的频率最高(为2),即输入实例是A类数据。

    以下为主程序段:

    def kNN(x, dataSet, labels, k):
        dataSetSize = dataSet.shape[0]
        distance1 = tile(x, (dataSetSize,1)) - dataSet #欧氏距离计算开始
        distance2 = distance1 ** 2 #每个元素平方
        distance3 = distance2.sum(axis=1) #矩阵每行相加
        distance4 = distance3 ** 0.5 #欧氏距离计算结束
        sortedIndex = distance4.argsort() #返回从小到大排序的索引
        classCount = {}
        for i in range (k): #统计前k个数据类的数量
            label = labels[sortedIndex[i]]
            classCount[label] = classCount.get(label,0) + 1
        sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True) #从大到小按类别数目排序
        return sortedClassCount[0][0]
    

    4.2决策树模型算法及基本原理
    决策树是一个属性结构的预测模型,代表对象属性和对象值之间的一种映射关系。它又节点和有向边组成,其节点有两种类型:内节点和叶节点,内部节点表示一个特征或属性,叶节点表示一个类。决策树的学习本质上是从训练集中归纳出一组分类规则,得到与数据集矛盾较小的决策树,同时具有很好的泛化能力。决策树学习的损失函数通常是正则化的极大似然函数,通常采用启发式方法,近似求解这一最优化问题。

    决策树学习算法包含特征选择、决策树生成与决策树的剪枝。决策树表示的是一个条件概率分布,所以深浅不同的决策树对应着不同复杂程度的概率模型。决策树的生成对应着模型的局部选择(局部最优),决策树的剪枝对应着全局选择(全局最优)。决策树常用的算法有ID3,C4.5,CART。

    为了计算信息增益,引入熵的概念,通过计算香农熵来将数据集划分不同的类别。

    程序段:

    
    def calcShannonEnt(dataSet):
           numEntries = len(dataSet)
        labelCounts = {}
        for featVec in dataSet:
            currentLabel = featVec[-1]
            if currentLabel not in labelCounts.keys(): 
                labelCounts[currentLabel] = 0
            labelCounts[currentLabel] += 1
        shannonEnt = 0.0
        for key in labelCounts:
            prob = float(labelCounts[key]) / numEntries
            shannonEnt -= prob * log(prob,2) # 以2为底的对数
        return shannonEnt
    
     
    
      在计算了信息增益后,应选择最好的数据集划分方式,在这里选择ID3算法进而绘制决策树。
    
      
    
    def chooseBestFeatureToSplitByID3(dataSet):#选择最好的数据集划分方式
        umFeatures = len(dataSet[0]) - 1 
        baseEntropy = calcShannonEnt(dataSet)
        bestInfoGain = 0.0
        bestFeature = -1
        for i in range(numFeatures):  # 遍历所有特征
            infoGain = calcInformationGain(dataSet, baseEntropy, i)     # 计算信息增益
            if (infoGain > bestInfoGain):  # 选择最大的信息增益
                bestInfoGain = infoGain
                bestFeature = i
        return bestFeature  
    def majorityCnt(classList):# 采用多数表决的方法决定叶结点的分类
        classCount={}
        for vote in classList:                         if vote not in classCount.keys():
                classCount[vote] = 0
            classCount[vote] += 1
        sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True) 
        return sortedClassCount[0][0]
     
    def createTree(dataSet,labels):#创建决策树
        classList = [example[-1] for example in dataSet]
        if classList.count(classList[0]) == len(classList): 
            return classList[0]            
        if len(dataSet[0]) == 1:        
            return majorityCnt(classList)   
        bestFeat = chooseBestFeatureToSplitByID3(dataSet)   
        bestFeatLabel = labels[bestFeat]
        myTree = {bestFeatLabel:{}}         
        del(labels[bestFeat])
        featValues = [example[bestFeat] for example in dataSet]
        uniqueVals = set(featValues)
        for value in uniqueVals:
            subLabels = labels[:]       
            myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value),subLabels)
        return myTree
    

    4.3朴素贝叶斯算法及基本原理
    朴素贝叶斯的思想基础是这样的:对于给出的待分类项,求解在此项出现的条件下各个类别出现的概率,哪个最大,就认为此待分类项属于哪个类别。朴素贝叶斯分类的核心算法如下:

    image.png

    那么现在的关键就是如何计算第3步中的各个条件概率。我们可以这么:

    1、已知分类的待分类项集合,这个集合叫做训练样本

    2、统计得到在各类别下各个特征属性的条件概率估计。

    3、如果各个特征属性是条件独立的,则根据贝叶斯定理有如下推导:

    image.png 因为分母对于所有类别为常数,因为我们只要将分子最大化皆可。又因为各特征属性是条件独立的,所以有: image.png

    为朴素贝叶斯的工作流程图:

    image.png

    5、测试方法与结果

    5.1测试结果
    对150个鸢尾花样本进行随机分割后,选取了其中的30个作为测试集,120个作为训练集,再计算他们的准确率、召回率和F值。结果如下:


    image.png

    看出准确率在93%,召回率为90%,说明是一次较为成功的训练。

    5.2决策树测试结果

    image.png

    看出在决策树训练的样本中,30组测试集完全正确,但这有可能是由以下原因造成的:

    1、测试集和训练集数目都太少,在数值上可能并不太符合要求。

    2、决策树本身算法易出现过拟合的现象,需要注意。

    绘制结果如下:


    image.png

    5.3朴素贝叶斯测试结果
    本次作业中关于应用朴素贝叶斯方法进行分类和测试,我是使用了sklearn中自带的分类器,并应用了其中两种相关算法。分别是:多项式朴素贝叶斯和高斯朴素贝叶斯

    结果如下:

    image.png

    可以看出,两种朴素贝叶斯的相关算法在此训练集上都有较好的应用。

    6.总结
    通过本次学习,我了解到决策树学习算法包含特征选择、决策树的生成与剪枝过程。决策树易于理解和实现,人们在在学习过程中不需要使用者了解很多的背景知识,这同时是它的能够直接体现数据的特点,只要通过解释后都有能力去理解决策树所表达的意义,非常直观。但是从此次实验的结果可以看出,30个测试样本全部正确,决策树算法非常容易过拟合,可以通过设置节点最少样本数量和限制决策树深度来改进。

    而KNN算法是一种简单,易于理解,易于实现,无需估计参数,无需训练的方法,但是它的缺点是计算量较大,因为对每一个待分类的文本都要计算它到全体已知样本的距离,才能求得它的K个最近邻点。如需改变其准确率可以通过改变其k值来进行测试,找到最优的分类方法。

    朴素贝叶斯朴素贝叶斯模型发源于古典数学理论,有稳定的分类效率。对缺失数据不太敏感,算法也比较简单,常用于文本分类。但是需要知道先验概率,且先验概率很多时候取决于假设,假设的模型可以有很多种,因此在某些时候会由于假设的先验模型的原因导致预测效果不佳。

    7.问题
    1、如何解决决策树中的过拟合问题?

    2、朴素贝叶斯方法“对输入数据的表达形式很敏感”是什么意思?

    3、如何最优选择KNN算法中的K?

    注:本文所使用的为64位系统,Python3.64版本,其中导入了与scikit-learn相关的数据包例如:DecisionTreeClassifier、sklearn.externals.six、pydot等。

    本文部分程序参考:

    CSDN论坛

    Python机器学习基础教程——人民邮电出版社

    Python编程从入门到实践——人民邮电出版社

    机器学习实战——人民邮电出版社

    相关文章

      网友评论

        本文标题:鸢尾花数据集(KNN、决策树、朴素贝叶斯分析)

        本文链接:https://www.haomeiwen.com/subject/mdoqoqtx.html