目录
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.png2.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.数据可视化
由于花瓣宽度变化很小,将其省略后根据前三维数据画出散点图,如下所示:
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朴素贝叶斯算法及基本原理
朴素贝叶斯的思想基础是这样的:对于给出的待分类项,求解在此项出现的条件下各个类别出现的概率,哪个最大,就认为此待分类项属于哪个类别。朴素贝叶斯分类的核心算法如下:
那么现在的关键就是如何计算第3步中的各个条件概率。我们可以这么:
1、已知分类的待分类项集合,这个集合叫做训练样本
2、统计得到在各类别下各个特征属性的条件概率估计。
3、如果各个特征属性是条件独立的,则根据贝叶斯定理有如下推导:
image.png 因为分母对于所有类别为常数,因为我们只要将分子最大化皆可。又因为各特征属性是条件独立的,所以有: image.png为朴素贝叶斯的工作流程图:
image.png5、测试方法与结果
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编程从入门到实践——人民邮电出版社
机器学习实战——人民邮电出版社
网友评论