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

目录

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编程从入门到实践——人民邮电出版社

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352

推荐阅读更多精彩内容