• 前言
  • 一、ID3算法构造决策树
    • 1.1 背景
    • 1.2 信息增益计算
    • 1.3 递归生成决策树
  • 二、使用Matplotlib注解绘制树形图
    • 2.1 Matplotlib注解
    • 2.2 构造注解树
  • 三、测试和存储分类器
    • 3.1 测试算法:使用决策树执行分类
    • 3.2 使用算法:决策树的存储
  • 四、示例:使用决策树预测隐形眼镜类型

前言

机器学习实战系列之学习笔记主要是本人进行学习机器学习的整理。本系列所有代码是用python3编写,并使用IDE PycharmWindows平台上编译通过。本系列所涉及的所有代码和资料可在我的github或者码云上下载到,gitbub地址:https://github.com/mcyJacky/MachineLearning,码云地址:https://gitee.com/mcyHome/MachineLearning,如有问题,欢迎指出~。

一、ID3算法构造决策树

1.1 背景

上一篇内容已经较详尽的介绍决策树理论,包括特征的选择、决策树的生产和决策树的剪枝。现在我们就对表1.1海洋生物数据表数据集运用ID3算法使用信息增益准则选择特征,构造决策树,表中数据包含5个海洋动物,特征包括:no surfacing、flippers(结果1表示、结果0表示),将这些动物分为两类:鱼类和非鱼类(鱼类用yes表示、非鱼类用no表示)。

表1.1 海洋生物数据表

序号 不浮出水面是否可以生存(no surfacing) 是否有脚蹼(flippers) 属于鱼类
1
2
3
4
5

决策树的一般流程

  • (1)收集数据:可以使用任何方法
  • (2)准备数据:树构造算法只适用于标称型数据,因此数值型数据必须离散化
  • (3)分析数据:可以使用任何方法,构造树完成之后,我们应该检查图形是否符合预期
  • (4)训练算法:构造树的数据结构
  • (5)测试算法:使用经验树计算错误率
  • (6)使用算法:此不步骤可以适用于任何监督学习算法,而使用决策树可以更好地理解数据的内在含义

1.2 信息增益计算

1)熵(香农熵)计算

首先,我们对表1.1海洋生物数据表创建数据集,如下:

'''
@function:创建一个训练数据集
@#param: None
@return: dataSet [list] 训练数据集labels [list] 特征标签
'''
def createDataSet():dataSet = [[1, 1, 'yes'],[1, 1, 'yes'],[1, 0, 'no'],[0, 1, 'no'],[0, 1, 'no']]labels = ['no surfacing', 'flippers']return dataSet, labelsif __name__ == '__main__':myDat, labels = createDataSet()print(myDat)print(labels)'''输出结果
[[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]
['no surfacing', 'flippers']
'''

接着,我们根据给定的数据集来计算香农熵(Entropy):

import time
import math'''
@function:创建一个训练数据集
@#param: None
@return: dataSet [list] 训练数据集labels [list] 特征标签
'''
def createDataSet():dataSet = [[1, 1, 'yes'],[1, 1, 'yes'],[1, 0, 'no'],[0, 1, 'no'],[0, 1, 'no']]labels = ['no surfacing', 'flippers']return dataSet, labels'''
@function:给定数据集熵的计算
@#param: dataSet [list] 训练数据集列表
@return: shannonEnt [num] 熵(香农熵)
'''
def calcShannonEnt(dataSet):numEntries = len(dataSet)labelCounts = {}    #定义类标签数量字典for featVec in dataSet:currentLabel = featVec[-1]if currentLabel not in labelCounts.keys():labelCounts[currentLabel] = 0labelCounts[currentLabel] += 1shannoEnt = 0.0for key in labelCounts: #进行熵计算prob = float(labelCounts[key])/numEntriesshannoEnt -= prob * math.log(prob, 2)return shannoEntif __name__ == '__main__':start = time.clock()myDat, labels = createDataSet()print(myDat)entropy = calcShannonEnt(myDat)print("entropy: ", entropy)end = time.clock()print(end - start)'''输出结果
[[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]
entropy:  0.9709505944546686
0.0011534813068524764
'''

2)划分数据集

如果我们已经确定了某个特征,再接下来的计算时,我们就要对数据集进行划分,我们将对每个特征划分数据集的结果计算一次信息熵,然后判断按照哪个特征划分数据集是最好的划分方式。下面就是按照给定特征划分数据集的方法:

'''
@function:划分数据集
@#param: dataSet [list] 待划分训练数据集axis 划分数据集的特征(索引)value 需要返回特征的值
@return: retDataSet [list] 划分后的数据集
'''
def splitDataSet(dataSet, axis, value):retDataSet = []for featVec in dataSet:if featVec[axis] == value:reducedFeatVec = featVec[:axis]reducedFeatVec.extend(featVec[axis+1:])retDataSet.append(reducedFeatVec)return retDataSetif __name__ == '__main__':start = time.clock()myDat, labels = createDataSet()print(myDat)retData = splitDataSet(myDat, 0, 1)print(retData)end = time.clock()print(end - start)'''输出结果
[[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]
[[1, 'yes'], [1, 'yes'], [0, 'no']]
4.8949925410577366e-05
'''

3)用信息增益法选择最优特征

现在,我们就可以进行选择最好的数据集划分方式来确定最优特征,当然我们要注意在下面函数调用需要满足一定的要求数据必须是一种由列表元素组成的列表,而且所有的列表元素都要具有相同的数据长度;数据的最后一列或者每个实例的最后一个元素是当前实例的类别标签。

'''
@function:通过信息增益选择最优特征
@#param: dataSet [list] 待划分训练数据集
@return: bestFeature [num] 最优特征位于列表的索引
'''
def chooseBestFeatureToSplit(dataSet):numFeatures = len(dataSet[0]) - 1   #特征个数baseEntropy = calcShannonEnt(dataSet) #熵的结果bestInfoGain = 0.0; bestFeature = -1    #初始化信息增益和最优特征for i in range(numFeatures):featList = [example[i] for example in dataSet]  #某一特征所有取值列表uniqueValues =set(featList) #用集合去取列表中相同部分newEntropy = 0.0        #初始化特征熵for value in uniqueValues:subDataSet = splitDataSet(dataSet, i, value)    #H划分特征数据集prob = len(subDataSet) / float(len(dataSet))newEntropy += prob * calcShannonEnt(subDataSet)infoGain = baseEntropy - newEntropyif infoGain > bestInfoGain:bestInfoGain = infoGainbestFeature = i #最优特征索引return bestFeatureif __name__ == '__main__':start = time.clock()myDat, labels = createDataSet()print(myDat)bestFeat = chooseBestFeatureToSplit(myDat)print('bestFeat', bestFeat)end = time.clock()print(end - start)'''输出结果
[[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]
bestFeat 0
0.00010855830232184497
'''

通过函数chooseBestFeatureToSplit()可以计算出某个训练数据集最优特征的索引位置。运行结果为0,即我们将按照将表1.1中先按第一个特征属性进行划分(序号1,2,3为一组;序号4,5为一组)。按照上述方法划分数据集,第一个特征为1的海洋生物分组将有两个属于鱼类,一个属于非鱼类;另一个分组则全部属于非鱼类。如果按照第二个特征分组呢?第一个海洋动物分组将有两个属于鱼类、两个属于非鱼类;另一个分组则只有一个非鱼类。因此,比较可知第一种划分很好地处理了相关数据,这也正是我们的计算结果。

1.3 递归生成决策树

目前我们已经学习了从数据集构造决策树算法所需要的子功能模块,其工作原理如下:得到原始数据集,然后基于最后的属性值划分数据集,由于特征值可能多于两个,因此可能存在大于两个分支的数据集划分。第一次划分之后,数据将向下传递到树分支的下一个节点,在这个节点上,我们可以再次划分数据。因此可以采用递归的原则处理数据集。

递归结束的条件是:程序遍历完所有划分数据集的属性,或者每个分支下的所有实例都具有相同的分类。如果所有实例具有相同的分类,则得到一个叶子节点或者终止块。第一个结束条件使得算法可以终止,我们甚至可以设置算法可以划分的最大分组数目。(如果数据集已经处理所有属性,但是类标签依然不是唯一的,此时我们需要决定如何定义该叶子节点,在这种情况下,我们通常会采用多数表决的方法决定该叶子节点的分类)。下面函数majorityCnt()就是返回数据集中出现次数最多的分类:


import operator
'''
@function:通过多数表决返回次数分类最多的名称
@#param: classList [list] 类标签
@return: sortedClassCount[0][0] 次数最多的类标签的名称
'''
def majorityCnt(classList):classCount = {}     #定义初始化分类标签字典存储变量for vote in classList:if vote not in classCount.keys():classCount[vote] = 0classCount[vote] += 1sortedClassCount = sorted(classCount.items(), key = operator.itemgetter(1), reverse=True) #从大到小排序return sortedClassCount[0][0]if __name__ == '__main__':start = time.clock()classList = ['yes', 'yes', 'yse', 'no']maxLabel = majorityCnt(classList)print(maxLabel)end = time.clock()print(end - start)'''输出结果
yes
9.079421648736125e-05
'''

最后,我们根据训练数据集合特征标签来创建决策树:

'''
@function:构建决策树
@#param: dataSet [list] 待划分训练数据集labels []   特征标签
@return: myTree [dict] 决策树
'''
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 = chooseBestFeatureToSplit(dataSet) #最优特征索引bestFeatLabel = labels[bestFeat] #最优特征的名称myTree = {bestFeatLabel:{}}     #初始化决策树del(labels[bestFeat] )featValues = [example[bestFeat] for example in dataSet] #最优特征中特征值列表uniqueVals = set(featValues) #特征值列表去重for value in uniqueVals:subLables = labels[:]   myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value), subLables) #递归return myTreeif __name__ == '__main__':start = time.clock()myDat, labels = createDataSet()print(myDat)myTree = createTree(myDat, labels)print(myTree)end = time.clock()print(end - start)'''输出结果
[[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]
{'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}
0.00015513968295449118
'''

如上变量myTree包含了很多代表树结构信息的嵌套字典,从左边开始,第一个关键字no surfacing是第一个特征划分的数据集,该关键字的值也是另一个数据字典。第二个关键字是flippers特征划分数据集,这些关键字是值no surfacing节点的子节点。这些值可能是类标签,也可能是另一个数据字典。如果值是类标签,则该子节点是叶子节点;如果值是另一个数据字典,则子节点是一个判断节点,这种格式结构不断重复就构成了整课树。本例子子中,这棵树包含了3个叶子节点和2个判断节点。

二、使用Matplotlib注解绘制树形图

上述我们已经学习了如何从数据集中创建树,然而字典的表示形式非常不易于理解,而且直接绘制图形也比较困难。决策树的主要优点是直观易于理解,如果不能将其直观显示出来,就无法发挥优势,本节我们将使用matplotlib库创建树形图

2.1 Matplotlib注解

Matplotlib提供了一个非常有用的注解工具annotations,我们创建treePlotter.py文件,它可以在数据图形上添加文本标注。简单使用方法示例如下:

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号decisionNode = dict(boxstyle='sawtooth', fc='0.8') #pad=0.3,tooth_size=None
leafNode = dict(boxstyle='round4', fc='0.8')
arrow_args = dict(arrowstyle='<-') #head_length=0.4,head_width=0.2def plotNode(nodeTxt, centerPt, parentPt, nodeType):# xy 标注点# xytext 对标注点进行注释的点# axes fraction:  fraction of axes from lower leftcreatePlot.ax1.annotate(nodeTxt, xy=parentPt, xycoords='axes fraction',xytext=centerPt, textcoords='axes fraction',va="center", ha="center", bbox=nodeType, arrowprops=arrow_args)'''
@function:绘制结点标注
@#param: nodeTxt [str] 标注文字centerPt [xy] 注释文字位置的坐标parentPt [xy] 标注对象点坐标nodeType [dic] 标注字体框的格式
@return: 标注后的图
'''
def createPlot():fig = plt.figure(1, facecolor='white') #背景色fig.clf()       #Clear the current figurecreatePlot.ax1 = plt.subplot(111, frameon=False) ##用函数属性createPlot.ax1定义全局变量plotNode('决策结点', (0.5, 0.1), (0.1, 0.5), decisionNode)plotNode('叶结点', (0.8, 0.1), (0.3, 0.8), leafNode)plt.show()if __name__ == '__main__':createPlot()

使用createPlot()会输出图2.1注解示例结果:


图2.1 使用matplotlib注解示例

2.2 构造注解树

1)获取叶节点数目和树层数

绘制一颗树需要一些技巧,我们虽然有x,y坐标,但是如何放置所有的树节点却是一个问题。我们要知道有多少个节点,以便正确确定x轴的长度;我们还需要知道树由多少层,以便可以正确确定y轴的高度。下面我们用getNumLeafs()和getTreeDepth()来获取叶节点的数目和树的层数:

'''
@function:获得叶子结点个数
@#param: myTree [dict] 决策树
@return: numLeafs [nums] 叶子结点个数
'''
def getNumLeafs(myTree):numLeafs = 0    #初始化叶子节点树firstStr = next(iter(myTree))   #当前树的第一个keysecondDict = myTree[firstStr]   #当前树的第一个key值for key in secondDict.keys():if type(secondDict[key]).__name__ == 'dict':    #如果该节点是判断节点,使用递归numLeafs += getNumLeafs(secondDict[key])else:numLeafs += 1   #如果是叶子节点,则叶子结点数+1return numLeafs'''
@function:获得决策树层数
@#param: myTree [dict] 决策树
@return: maxDepth [nums] 树的层数
'''
def getTreeDepth(myTree):maxDepth = 0firstStr = next(iter(myTree))   #当前树的第一个keysecondDict = myTree[firstStr]   ##当前树的第一个key值for key in secondDict.keys():if type(secondDict[key]).__name__ == 'dict':    #如果该节点是判断节点,使用递归thisDepth = 1 + getTreeDepth(secondDict[key])else:thisDepth = 1if thisDepth > maxDepth:maxDepth = thisDepthreturn maxDepth'''
@function:返回预定义的树结构(用于测试)
@#param: i [num] 列表的索引
@return: listOfTrees[i] [dict] 某决策树
'''
def retrieveTree(i):listOfTrees = [{'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}},{'no surfacing': {0: 'no', 1: {'flippers': {0: {'head': {0: 'no', 1: 'yes'}}, 1: 'no'}}}}]return listOfTrees[i]if __name__ == '__main__':# createPlot()myTree = retrieveTree(0)print(myTree)numLeafs = getNumLeafs(myTree)depth = getTreeDepth(myTree)print('numLeafs: ', numLeafs)print('depth: ', depth)'''输出结果
{'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}
numLeafs:  3
depth:  2
'''

2)绘制注解树

下面使用plotMidText()函数绘制父子节点间的填充文本信息,用plotTree()函数来绘制树:

'''
@function:标注结点之间的判断文字
@#param: cntrPt [xy] 标注文字的位置parentPt [xy] 标注对象的位置txtString [str] 标注文字
@return: 结点之间的判断文字
'''
def plotMidText(cntrPt, parentPt, txtString):xMid = (parentPt[0] - cntrPt[0])/2.0 + cntrPt[0]yMid = (parentPt[1] - cntrPt[1])/2.0 + cntrPt[1]createPlot.ax1.text(xMid, yMid, txtString)'''
@function:绘制决策树方法
@#param: myTree [dict] 待绘制的决策树对象parentPt [xy] 标注文字的位置nodeText [str] 标注文字
@return: 决策树图
'''
def plotTree(myTree, parentPt, nodeText):numLeafs = getNumLeafs(myTree)# depth = getTreeDepth(myTree)firstStr = next(iter(myTree))cntrPt = (plotTree.xOff + (1.0 + float(numLeafs))/2.0/plotTree.totalW, plotTree.yOff) #标注点的中心位置plotMidText(cntrPt, parentPt, nodeText)plotNode(firstStr, cntrPt, parentPt, decisionNode)secondDict = myTree[firstStr]plotTree.yOff = plotTree.yOff - 1.0/plotTree.totalDfor key in secondDict.keys():if type(secondDict[key]).__name__ == 'dict':plotTree(secondDict[key], cntrPt, str(key))else:plotTree.xOff = plotTree.xOff + 1.0/plotTree.totalWplotNode(secondDict[key], (plotTree.xOff, plotTree.yOff), cntrPt, leafNode)plotMidText((plotTree.xOff, plotTree.yOff), cntrPt, str(key))plotTree.yOff = plotTree.yOff + 1.0 / plotTree.totalDdef createPlot(inTree):fig = plt.figure(1, facecolor='white')fig.clf()axprops = dict(xticks=[], yticks=[])createPlot.ax1 = plt.subplot(111, frameon=False, **axprops) #无坐标轴的图plotTree.totalW = float(getNumLeafs(inTree))    #全局变量定义树的宽度plotTree.totalD = float(getTreeDepth(inTree))   #全局变量定义树的高度plotTree.xOff = -0.5/plotTree.totalW;plotTree.yOff = 1.0; #x,y偏移量plotTree(inTree, (0.5, 1.0), '')plt.show()if __name__ == '__main__':myTree = retrieveTree(0)createPlot(myTree)

现在我们就绘制出树形图,如下图2.2决策树形图:


图2.2 决策树形图

三、测试和存储分类器

3.1 测试算法:使用决策树执行分类

依靠训练数据构造了决策树之后,我们可以将它用于实际数据的分类。在执行数据分类时,需要使用决策树以及用于构造决策树的标签向量。然后,程序比较测试数据与决策树上的数值,递归执行该过程直到进入叶子结点;最后将测试数据定义为叶子节点所属的类型。

'''
@function:决策树的分类函数
@#param: inputTree [dict] 决策树featLabels [list] 特征标签testVec [list] 测试对象
@return: classLabel 分类标签
'''
def classify(inputTree, featLabels, testVec):firstStr = next(iter(inputTree))secondDict = inputTree[firstStr]featIndex = featLabels.index(firstStr)for key in secondDict.keys():if testVec[featIndex] == key:if type(secondDict[key]).__name__ == 'dict':classLabel = classify(secondDict[key], featLabels, testVec)else: classLabel = secondDict[key]return classLabelif __name__ == '__main__':start = time.clock()import treePlotter as tpmyTree = tp.retrieveTree(0)result = classify(myTree, labels, [1,0])print('result: ', result)end = time.clock()print(end - start)'''输出结果
[[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]
result:  no
0.9584667778040511
'''

3.2 使用算法:决策树的存储

我们构造决策树是很耗时的任务,因此,为了节省计算时间,最后能够在每次执行分类时调用已经构造好的决策树,为了解决这个问题,我们用模块pickle序列化对象。序列化对象可以在磁盘上保存对象,并在需要的时候读取出来。(任何对象都能序列化,字典对象也不例外)

'''
@function:序列化对象存储决策树
@#param: inputTree [dict] 决策树filename 存储后的文件
@return: None
'''
def storeTree(inputTree, filename):import pickle   #导入pickle模块fw = open(filename, 'wb')pickle.dump(inputTree, fw)  #序列化fw.close()'''
@function:将对象进行反序列化(读取决策树对象)
@#param: filename 存储后的文件
@return: 决策树模型
'''
def grabTree(filename):import picklefr = open(filename, 'rb')return pickle.load(fr)  #反序列化if __name__ == '__main__':start = time.clock()import treePlotter as tpmyTree = tp.retrieveTree(0)filename = './storageTree1.txt' #当前目录下的文件storeTree(myTree, filename)rTree = grabTree(filename)print('rTree', rTree)end = time.clock()print(end - start)'''输出结果
rTree {'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}
0.7381443478034314
'''

通过执行storeTree()函数会将存储在当前文件夹下的txt文件中,当你用记事本打开文件时是乱码的格式,因为序列化是已二进制格式进行存储的。而当执行gragTree()函数我重新加载原理树的格式。

四、示例:使用决策树预测隐形眼镜类型

下面我们通过一个例子讲解决策树如何预测患者需要佩戴的隐形眼镜类型。它的一般流程是:

  • (1)收集数据:提供的文本文件
  • (2)准备数据:解析tab键分隔的数据行
  • (3)分析数据:快速检查数据,确保正确地解析数据内容,绘制树形图
  • (4)训练算法:使用createTree()函数
  • (5)测试算法:编写测试函数验证决策树可以正确分类给定的数据实例
  • (6)使用算法:存储树的数据结构,以便下次使用时无需重新构造树

下面是训练数据集的部分文本:

young myope no reduced no lenses
young myope no normal soft
young myope yes reduced no lenses
young myope yes normal hard
young hyper no reduced no lenses

该数据的特征标签分别是:age(年龄)、prescript(症状)、astigmatic(是否散光)、tearRate(眼泪数量)以及类标签。下面我们使用决策树ID3算法来生成隐形眼镜数据集决策树:

if __name__ == '__main__':import treePlotter as tpfr = open('lenses.txt')lenses = [inst.strip().split('\t') for inst in fr.readlines()]lensesLabels = ['age', 'prescript', 'astigmatic', 'tearRate']  # 年龄, 散光,lensesTree = createTree(lenses, lensesLabels)print(lensesTree)tp.createPlot(lensesTree)'''输出结果
[[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]
{'tearRate': {'reduced': 'no lenses', 'normal': {'astigmatic': {'yes': {'prescript': {'hyper': {'age': {'young': 'hard', 'pre': 'no lenses', 'presbyopic': 'no lenses'}}, 'myope': 'hard'}}, 'no': {'age': {'young': 'soft', 'pre': 'soft', 'presbyopic': {'prescript': {'hyper': 'soft', 'myope': 'no lenses'}}}}}}}}
'''

输出的决策树图如下:


图4.1 由ID3算法生成的隐形眼镜分类决策树图

至目前为止,我们已经完成了决策树的匹配,但是可能这些匹配选项可能太多了,过造成过度拟合问题,之后我们会介绍如果减少过度匹配问题,通过裁剪决策树,这边就不多详述。总体来说,使用决策树的优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据;缺点:可能会产生过度匹配问题;适用数据类型:数值型和标称型。

【参考】:
     1. 《统计学习方法》作者:李航   第5章 决策树
     2. 《机器学习实战》作者:Peter Harrington   第3章 决策树


转载声明:
版权声明:非商用自由转载-保持署名-注明出处
署名 :mcyJacky
文章出处:https://blog.csdn.net/mcyJacky

python3《机器学习实战系列》学习笔记----3.2 决策树实战相关推荐

  1. Pyhthon3《机器学习实战》学习笔记二:决策树

    一 决策树 概述 决策树(Decision Tree)算法是一种基本的分类与回归方法,是最经常使用的数据挖掘算法之一.书中只讨论用于分类的决策树.   决策树模型呈树形结构,在分类问题中,表示基于特征 ...

  2. python predictabel_Python3《机器学习实战》学习笔记(三):决策树实战篇之为自己配个隐形眼镜...

    ) p1Vect = np.log(p1Num/p1Denom) #取对数,防止下溢出 p0Vect = np.log(p0Num/p0Denom) return p0Vect,p1Vect,pAbu ...

  3. Python3《机器学习实战》学习笔记(八):支持向量机原理篇之手撕线性SVM

    原 Python3<机器学习实战>学习笔记(八):支持向量机原理篇之手撕线性SVM 置顶 2017年09月23日 17:50:18 阅读数:12644 转载请注明作者和出处: https: ...

  4. Python3《机器学习实战》学习笔记(三):决策树实战篇

    转载请注明作者和出处: http://blog.csdn.net/c406495762  运行平台: Windows  Python版本: Python3.x  IDE: Sublime text3 ...

  5. Python3《机器学习实战》学习笔记(三):决策树实战篇之为自己配个隐形眼镜

    转载请注明作者和出处: http://blog.csdn.net/c406495762 运行平台: Windows Python版本: Python3.x IDE: Sublime text3 一 前 ...

  6. Python3《机器学习实战》学习笔记(五):朴素贝叶斯实战篇之新浪新闻分类

    转载请注明作者和出处:http://blog.csdn.net/c406495762 Github代码获取:https://github.com/Jack-Cherish/Machine-Learni ...

  7. Python3《机器学习实战》学习笔记(二):决策树基础篇之让我们从相亲说起

    转载请注明作者和出处: http://blog.csdn.net/c406495762 运行平台: Windows Python版本: Python3.x IDE: Sublime text3 个人网 ...

  8. 《机器学习实战》学习笔记(八):预测数值型数据 - 回归

    欢迎关注WX公众号:[程序员管小亮] [机器学习]<机器学习实战>读书笔记及代码 总目录 https://blog.csdn.net/TeFuirnever/article/details ...

  9. 《机器学习实战》学习笔记(三):决策树

    欢迎关注WX公众号:[程序员管小亮] [机器学习]<机器学习实战>读书笔记及代码 总目录 https://blog.csdn.net/TeFuirnever/article/details ...

最新文章

  1. 和世界冠军一起准备ACM!清华杜瑜皓来了:连续4年ACM中国赛区冠军
  2. 关于召开全国大学生智能车竞赛--航天智慧物流项目
  3. 算法入门经典 第三章
  4. php识别字符编码,PHP自动识别字符集编码并完成转码_PHP教程
  5. 树状数组(搬运自维基百科)
  6. 4.2 js没有块级作用域
  7. 如何查询Oracle性能监控
  8. hdu 1421 搬寝室(dp)
  9. 为什么有些程序员明明很努力,但是却回报很低,收益很小,工资始终上不去-出自中华石杉老师
  10. 论文发表如何选择正确的期刊杂志?
  11. 软件工程-第二章 软件过程
  12. 爱情七十六课,门当户对
  13. 用胶带屏蔽PCIE接口解决兼容问题,150块的P104矿渣卡也能跑深度学习
  14. 阿里终于杀进5G了!“新基建”赛道谁更胜一筹
  15. python爬虫requests.post()_网页爬虫 - Python requests爬虫,如何post payload里的数据,谢谢!...
  16. 服务器 php 版本低,php 版本过低 怎么修改?
  17. 初学CAD,该如何正确查看CAD图纸呢?
  18. 【转】GPS定位基本原理浅析
  19. 人生最好的医生,其实是自己。
  20. oracle技术基础知识,ORACLE基础知识培训.ppt

热门文章

  1. android 高斯模糊实现
  2. 如何将二维码巧妙放进海报里?
  3. 单片机I/O口的结构的详解
  4. Android Studio 控制台 log不显示解决
  5. x的y次方python表达式怎么写_x 的 y 次方(xy) 以下表达式正确的是________
  6. Setup Factory导入注册表时丢失部分语句
  7. pc客户端软件自动化测试工具,自动化测试工具(QuickTester)
  8. 【戒焦戒躁,can win】Linux--inode
  9. LVGL笔记(1)-使用《avilib》库播放avi视频(lvgl在windows模拟运行)
  10. Codeforces Round #807 (Div. 2) A-C题解