决策树(二)——决策树的生成
说明:这篇博客是看李航老师的《统计学习方法》的笔记总结,博客中有很多内容是摘选自李航老师的《统计学习方法》一书,仅供学习交流使用。
决策树的生成
在上一篇博客决策树(一)——构建决策树中,我们已经讲述了决策树三步骤中的特征选择,今天我们首先来讲解一下决策树的生成。
决策树生成的基本思想是分割数据集。具体的做法就是尝试每一个特征,并衡量哪一个特征会给你带来最好的结果,然后,基于最优的特征分割数据集(由于最优特征可能有好几个值,所以我们也可能会得到多个子集)。第一次划分之后,数据集被向下传递到树的分支的下一个结点。在这个结点上,我们可以再次划分数据。即我们可以采用递归来处理数据集。
决策树生成的算法有ID3、C4.5等,我们先来讲解一下ID3算法。
ID3
ID3算法的核心是在决策树各个节点上应用信息增益准则选择特征,递归地构造决策树。
输入:训练数据集D,特征集A阈值ε
输出:决策树T
(1)若D中所有实例属于同一类 C k C_k Ck,则T为单结点树,并将类 C k C_k Ck作为该结点的类标记,返回T;
(2)若 A = ∅ A=∅ A=∅,则T为单结点树,并将D中实例数最大的类 C k C_k Ck作为该结点的类标记,返回T;
(3)否则,计算A中各特征对D的信息增益,选择信息增益最大的特征 A g A_g Ag;
(4)如果 A g A_g Ag的信息增益小于阈值ε,则置T为单结点树,并将D中实例数最大的类 C k C_k Ck作为该结点的类标记,返回T;
(5)否则,对 A g A_g Ag的每一可能值 a i a_i ai,依 A g = a i A_g=a_i Ag=ai将D分割为若干非空子集 D i D_i Di,将 D i D_i Di中实例数最大的类最为标记,构建子节点,由结点及其子结点构成树T,返回T;
(6)对第i个子结点,以 D i D_i Di为训练集,以 A − { A g } A-\{A_g\} A−{Ag}为特征集,递归地调用步(1)~(5),得到子树 T i T_i Ti,返回 T i T_i Ti。
举例
其实在上一篇博客,我们通过对各特征计算其各自的信息增益已经知道第三个特征(有自己的房子)的信息增益最大,故其就是决策树的根节点;然后该特征取值有两个:是 or 否,故我们可以把数据集D分成两个子集 D 是 D_是 D是和 D 否 D_否 D否,那么数据集就该是这样的:(在选出最优特征后,我们需要删除最优特征的标签,及其在数据集中的值)
D 是 D_是 D是:
ID | 年龄 | 有工作 | 信贷情况 | 类别 |
---|---|---|---|---|
4 | 青年 | 是 | 一般 | 是 |
8 | 中年 | 是 | 好 | 是 |
9 | 中年 | 否 | 非常好 | 是 |
10 | 中年 | 否 | 非常好 | 是 |
11 | 老年 | 否 | 非常好 | 是 |
12 | 老年 | 否 | 好 | 是 |
根据表格可知,有自己的房子的类别均为是,满足决策树算法的第一条,所以返回类标签是。
D 否 D_否 D否:
ID | 年龄 | 有工作 | 信贷情况 | 类别 |
---|---|---|---|---|
1 | 青年 | 否 | 一般 | 否 |
2 | 青年 | 否 | 好 | 否 |
3 | 青年 | 是 | 好 | 是 |
5 | 青年 | 否 | 一般 | 否 |
6 | 中年 | 否 | 一般 | 否 |
7 | 中年 | 否 | 好 | 否 |
13 | 老年 | 是 | 好 | 是 |
14 | 老年 | 是 | 非常好 | 是 |
15 | 老年 | 否 | 一般 | 否 |
子集 D 否 D_否 D否就需要计算 g ( D 否 , A ) g(D_否,A) g(D否,A)来比较哪一个特征更适合做子集 D 否 D_否 D否的根结点了,下面咱们我就带着大家简单的计算一下。
假设 A 1 A_1 A1表示特征年龄, A 2 A_2 A2表示特征有, A 3 A_3 A3表示特征信贷情况
g ( D 否 , A 1 ) = H ( D 否 ) − H ( D 否 , A 1 ) = − 6 9 l o g 2 6 9 − 3 9 l o g 2 3 9 − [ 4 9 ( − 3 4 l o g 2 3 4 − 1 4 l o g 2 1 4 ) + 2 9 ∗ 0 + 3 9 ( − 2 3 l o g 2 2 3 − 1 3 l o g 2 1 3 ) ] = 0.918 − ( 0.361 + 0 + 0.306 ) = 0.251 \begin{aligned} g(D_否,A_1)&=H(D_否)-H(D_否,A_1) \\ &=-\frac{6}{9}log_2\frac{6}{9}-\frac{3}{9}log_2\frac{3}{9}-[\frac{4}{9}(-\frac{3}{4}log_2\frac{3}{4}-\frac{1}{4}log_2\frac{1}{4})+\frac{2}{9}*0+\frac{3}{9}(-\frac{2}{3}log_2\frac{2}{3}-\frac{1}{3}log_2\frac{1}{3})] \\ &=0.918-(0.361+0+0.306) \\ &=0.251 \end{aligned} g(D否,A1)=H(D否)−H(D否,A1)=−96log296−93log293−[94(−43log243−41log241)+92∗0+93(−32log232−31log231)]=0.918−(0.361+0+0.306)=0.251
其他特征同理。
代码实现
from math import log
import operatordef createDataSet():# 数据集dataSet=[[0, 0, 0, 0, 'no'],[0, 0, 0, 1, 'no'],[0, 1, 0, 1, 'yes'],[0, 1, 1, 0, 'yes'],[0, 0, 0, 0, 'no'],[1, 0, 0, 0, 'no'],[1, 0, 0, 1, 'no'],[1, 1, 1, 1, 'yes'],[1, 0, 1, 2, 'yes'],[1, 0, 1, 2, 'yes'],[2, 0, 1, 2, 'yes'],[2, 0, 1, 1, 'yes'],[2, 1, 0, 1, 'yes'],[2, 1, 0, 2, 'yes'],[2, 0, 0, 0, 'no']]#分类属性labels=['年龄','有工作','有自己的房子','信贷情况']#返回数据集和分类属性return dataSet,labels#香农熵(经验熵)
def calcShannonEnt(dataSet):#数据集行数numEntries=len(dataSet)#保存类标签出现次数的字典labelCounts={}#对每组特征向量进行统计for featVec in dataSet:currentLabel=featVec[-1] #类标签if currentLabel not in labelCounts.keys(): #如果标签没有放入统计次数的字典,添加进去labelCounts[currentLabel]=0labelCounts[currentLabel]+=1 shannonEnt=0.0 #计算经验熵for key in labelCounts:prob=float(labelCounts[key])/numEntries shannonEnt-=prob*log(prob,2) return shannonEnt #返回经验熵#分割数据集
def splitDataSet(dataSet,axis,value):retDataSet=[]#遍历数据集for featVec in dataSet:if featVec[axis]==value:#去掉axis特征reduceFeatVec=featVec[:axis]reduceFeatVec.extend(featVec[axis+1:])#将符合条件的添加到返回的数据集retDataSet.append(reduceFeatVec)return retDataSet#求实例数最多的类
def majorityCnt(classList):classCount={}#统计classList中每个元素出现的次数for vote in classList:if vote not in classCount.keys():classCount[vote]=0classCount[vote]+=1#根据字典的值降序排列sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)return sortedClassCount[0][0]#选择最优特征(依据:信息增益 or 信息增益比)
def chooseBestFeatureToSplit(dataSet):#特征数量numFeatures = len(dataSet[0]) - 1baseEntropy = calcShannonEnt(dataSet)#信息增益bestInfoGain = 0.0#最优特征的索引值bestFeature = -1#遍历所有特征for i in range(numFeatures):# 获取dataSet的第i个所有特征featList = [example[i] for example in dataSet]#创建set集合{},元素不可重复uniqueVals = set(featList)#经验条件熵newEntropy = 0.0#计算信息增益for value in uniqueVals:#subDataSet划分后的子集subDataSet = splitDataSet(dataSet, i, value)prob = len(subDataSet) / float(len(dataSet))#根据公式计算经验条件熵newEntropy += prob * calcShannonEnt((subDataSet))#信息增益infoGain = baseEntropy - newEntropy#打印每个特征的信息增益print("第%d个特征的增益为%.3f" % (i, infoGain))#选择信息增益最大的特征,并存储其索引if (infoGain > bestInfoGain):bestInfoGain = infoGainbestFeature = ireturn bestFeature#创建决策树
def createTree(dataSet,labels,featLabels):#读取类标签classList=[example[-1] for example in dataSet]#如果D中所有实例同属于一个类if classList.count(classList[0])==len(classList):return classList[0]#遍历完所有特征时返回出现次数最多的类标签if len(dataSet[0])==1:return majorityCnt(classList)#选择最优特征bestFeat=chooseBestFeatureToSplit(dataSet)#最优特征的标签bestFeatLabel=labels[bestFeat]featLabels.append(bestFeatLabel)#根据最优特征的标签生成树myTree={bestFeatLabel:{}}#删除已经使用的特征标签del(labels[bestFeat])#得到训练集中所有最优特征的属性值featValues=[example[bestFeat] for example in dataSet]#去掉重复的属性值uniqueVls=set(featValues)#遍历特征,创建决策树for value in uniqueVls:myTree[bestFeatLabel][value]=createTree(splitDataSet(dataSet,bestFeat,value),labels,featLabels)return myTreeif __name__=='__main__':dataSet,labels=createDataSet()featLabels=[]myTree=createTree(dataSet,labels,featLabels)print(myTree)
第0个特征的增益为0.083
第1个特征的增益为0.324
第2个特征的增益为0.420
第3个特征的增益为0.363
第0个特征的增益为0.252
第1个特征的增益为0.918
第2个特征的增益为0.474
{'有自己的房子': {0: {'有工作': {0: 'no', 1: 'yes'}}, 1: 'yes'}}
C4.5
C4.5同ID3很是相似,只是在选择最优特征时使用的不是信息增益,而是信息增益比,故此处不多赘述。
代码实现
C4.5算法的实现可以参考ID3,我这里简单的把需要修改的部分展示出来。
大家都知道信息增益比的公式是 g R ( D , A ) = g ( D , A ) H A ( D ) g_R(D,A)=\frac{g(D,A)}{H_A(D)} gR(D,A)=HA(D)g(D,A),这里就简单地带大家计算一下 H A ( D ) H_A(D) HA(D)
我们之前就已经计算过第一个特征的信息增益了,这里我们就直接拿来用。
g ( D , A 1 ) = 0.083 g(D,A_1)=0.083 g(D,A1)=0.083
H A 1 ( D ) = − ∑ i = 1 n ∣ D i ∣ ∣ D ∣ l o g 2 ∣ D i ∣ ∣ D ∣ = − 5 15 l o g 2 5 15 − 5 15 l o g 2 5 15 − 5 15 l o g 2 5 15 = − l o g 2 5 15 = 1.585 \begin{aligned} H_{A_1}(D)&=-\sum_{i=1}^n\frac{|D_i|}{|D|}log_2\frac{|D_i|}{|D|} \\ &=-\frac{5}{15}log_2\frac{5}{15}-\frac{5}{15}log_2\frac{5}{15}-\frac{5}{15}log_2\frac{5}{15} \\ &=-log_2\frac{5}{15} \\ &=1.585 \end{aligned} HA1(D)=−i=1∑n∣D∣∣Di∣log2∣D∣∣Di∣=−155log2155−155log2155−155log2155=−log2155=1.585
g R ( D , A ) = g ( D , A ) H A ( D ) = 0.083 1.585 ≈ 0.052 g_R(D,A)=\frac{g(D,A)}{H_A(D)}=\frac{0.083}{1.585}≈0.052 gR(D,A)=HA(D)g(D,A)=1.5850.083≈0.052
下面的calcAShannonEnt()函数就是对 H A ( D ) H_A(D) HA(D)的计算。
def calcAShannonEnt(dataSet,i):#返回数据集行数numEntries=len(dataSet)#保存每个标签(label)出现次数的字典labelCounts={}#对每组特征向量进行统计for featVec in dataSet:currentLabel=featVec[i] #提取标签信息if currentLabel not in labelCounts.keys(): #如果标签没有放入统计次数的字典,添加进去labelCounts[currentLabel]=0labelCounts[currentLabel]+=1 #label计数shannonEnt=0.0 #经验熵#计算经验熵for key in labelCounts:prob=float(labelCounts[key])/numEntries #选择该标签的概率shannonEnt-=prob*log(prob,2) #利用公式计算return shannonEnt
接下来需要改的就是chooseBestFeatureToSplit()函数,该函数主要是计算了信息增益 g ( D , A ) g(D,A) g(D,A)与特征A数据集经验熵 H A ( D ) H_A(D) HA(D)之间的比值。
def chooseBestFeatureToSplit(dataSet):#特征数量numFeatures = len(dataSet[0]) - 1#计数数据集的香农熵baseEntropy = calcShannonEnt(dataSet)#信息增益bestInfoGainRate = 0.0#最优特征的索引值bestFeature = -1#遍历所有特征for i in range(numFeatures):# 获取dataSet的第i个所有特征featList = [example[i] for example in dataSet]#创建set集合{},元素不可重复uniqueVals = set(featList)#经验条件熵newEntropy = 0.0#计算信息增益for value in uniqueVals:#subDataSet划分后的子集subDataSet = splitDataSet(dataSet, i, value)#计算子集的概率prob = len(subDataSet) / float(len(dataSet))#根据公式计算经验条件熵newEntropy += prob * calcShannonEnt((subDataSet))#信息增益infoGain = baseEntropy - newEntropyif calcAShannonEnt(dataSet,i) == 0:continue#信息增益infoGain = baseEntropy - newEntropy#print("第%d个特征的增益比为%.3f" % (i, infoGain))if calcAShannonEnt(dataSet,i) == 0:continue#print("第%d个特征的增益比为%.3f" % (i, calcAShannonEnt(dataSet,i)))#信息增益比infoGainRate = infoGain / calcAShannonEnt(dataSet,i)print("第%d个特征的增益比为%.3f" % (i, infoGainRate))#计算信息增益if (infoGainRate > bestInfoGainRate):#更新信息增益,找到最大的信息增益bestInfoGainRate = infoGainRate#记录信息增益最大的特征的索引值bestFeature = i#返回信息增益最大特征的索引值return bestFeature
第0个特征的增益比为0.052
第1个特征的增益比为0.352
第2个特征的增益比为0.433
第3个特征的增益比为0.232
第0个特征的增益比为0.164
第1个特征的增益比为1.000
第2个特征的增益比为0.340
{'有自己的房子': {0: {'有工作': {0: 'no', 1: 'yes'}}, 1: 'yes'}}
cart生成算法
cart模型分回归树与分类树两种,而这里只讲解下分类树。
分类树用基尼指数选择最优特征,同时决定该特征的最有二值切分点。
基尼指数:分类问题中,假设有K个类,样本点属于第k类的概率为 p k p_k pk,则概率分布的基尼指数定义为
G i n i ( p ) = ∑ k = 1 K p k ( 1 − p k ) = 1 − ∑ k = 1 K p k 2 Gini(p)=\sum_{k=1}^Kp_k(1-p_k)=1-\sum_{k=1}^Kp_k^2 Gini(p)=k=1∑Kpk(1−pk)=1−k=1∑Kpk2
对于二类分类问题,若样本点属于第1个类的概率是p,则概率分布的基尼指数为
G i n i ( p ) = 2 p ( 1 − p ) Gini(p)=2p(1-p) Gini(p)=2p(1−p)
对于给定样本集合D,其基尼指数为
G i n i ( D ) = 1 − ∑ k = 1 K ( ∣ C k ∣ ∣ D ∣ ) 2 Gini(D)=1-\sum_{k=1}^K(\frac{|C_k|}{|D|})^2 Gini(D)=1−k=1∑K(∣D∣∣Ck∣)2
如果样本集合D根据特征A是否取某一可能值a被分割为 D 1 D_1 D1和 D 2 D_2 D2两部分,即
D 1 = { ( x , y ) ∈ D ∣ A ( x ) = a } , D 2 = D − D 1 D_1=\{(x,y)∈D|A(x)=a\}, \ D_2=D-D_1 D1={(x,y)∈D∣A(x)=a}, D2=D−D1
则在特征A的条件下,集合D的基尼指数定义为
G i n i ( D , A ) = ∣ D 1 ∣ ∣ D 2 ∣ G i n i ( D 1 ) + ∣ D 2 ∣ ∣ D ∣ G i n i ( D 2 ) Gini(D,A)=\frac{|D_1|}{|D_2|}Gini(D_1)+\frac{|D_2|}{|D|}Gini(D_2) Gini(D,A)=∣D2∣∣D1∣Gini(D1)+∣D∣∣D2∣Gini(D2)
注:基尼指数Gini(D)表示集合D的不确定性,基尼指数Gini(D,A)表示经A=a分割后集合D的不确定性。
生成算法
输入:训练数据集D,停止计算的条件;
输出:CART决策树
根据训练数据集,从根结点开始,递归地对每个结点进行以下操作,构建二叉决策树。
(1)设结点的训练数据集为D,计算现有特征对该数据集的基尼指数。此时,对每一个特征A,对其可能取得每个值a,根据样本点对A=a的测试为“是”或“否”将D分割成 D 1 D_1 D1和 D 2 D_2 D2两部分,利用上述最后一个公式计算A=a时的基尼指数。
(2)在所有可能的特征A以及他们所有可能的切分点a中,选择基尼指数最小的特征及其对应的切分点作为最优特征与最优切分点。依最优特征与最优切分点,从现结点生成两个子结点,将训练数据集依特征分配到两个子节点中。
(3)对两个子结点递归调用(1),(2),直到满足条件。
(4)生成cart决策树。
def createDataSet():# 数据集dataSet=[[0, 0, 0, 0, 'no'],[0, 0, 0, 1, 'no'],[0, 1, 0, 1, 'yes'],[0, 1, 1, 0, 'yes'],[0, 0, 0, 0, 'no'],[1, 0, 0, 0, 'no'],[1, 0, 0, 1, 'no'],[1, 1, 1, 1, 'yes'],[1, 0, 1, 2, 'yes'],[1, 0, 1, 2, 'yes'],[2, 0, 1, 2, 'yes'],[2, 0, 1, 1, 'yes'],[2, 1, 0, 1, 'yes'],[2, 1, 0, 2, 'yes'],[2, 0, 0, 0, 'no']]#分类属性labels=['年龄','有工作','有自己的房子','信贷情况']#返回数据集和分类属性return dataSet,labels#计算基尼指数Gini(D)
def calcGini(dataSet):#返回数据集行数numEntries=len(dataSet)#保存每个标签(label)出现次数的字典labelCounts={}#对每组特征向量进行统计for featVec in dataSet:currentLabel=featVec[-1] #提取标签信息if currentLabel not in labelCounts.keys(): #如果标签没有放入统计次数的字典,添加进去labelCounts[currentLabel]=0labelCounts[currentLabel]+=1 gini=1.0 #计算基尼指数for key in labelCounts:prob=float(labelCounts[key])/numEntries gini-=prob**2 return gini def splitDataSet(dataSet,axis,value):#创建返回的数据集列表retDataSet=[]#遍历数据集for featVec in dataSet:if featVec[axis]==value:#去掉axis特征reduceFeatVec=featVec[:axis]#将符合条件的添加到返回的数据集reduceFeatVec.extend(featVec[axis+1:])retDataSet.append(reduceFeatVec)#返回划分后的数据集return retDataSet
#获取特征其他样本的子集
def splitOtherDataSetByValue(dataSet,axis,value):#创建返回的数据集列表retDataSet=[]#遍历数据集for featVec in dataSet:if featVec[axis]!=value:#去掉axis特征reduceFeatVec=featVec[:axis]#将符合条件的添加到返回的数据集reduceFeatVec.extend(featVec[axis+1:])retDataSet.append(reduceFeatVec)#返回划分后的数据集return retDataSet
def binaryZationDataSet(bestFeature,bestSplitValue,dataSet):# 求特征标签数featList = [example[bestFeature] for example in dataSet]uniqueValues = set(featList)# 特征标签输超过2,对数据集进行二值划分if len(uniqueValues) >= 2:for i in range(len(dataSet)):if dataSet[i][bestFeature] == bestSplitValue: # 不做处理passelse:dataSet[i][bestFeature] = '其他'def chooseBestFeatureToSplit(dataSet):#特征数量numFeatures = len(dataSet[0]) - 1#初始化最优基尼指数值bestGiniIndex = 1000000.0bestSplictValue =-1#最优特征的索引值bestFeature = -1#遍历所有特征for i in range(numFeatures):# 获取dataSet的第i个所有特征featList = [example[i] for example in dataSet]#创建set集合{},元素不可重复uniqueVals = set(featList)bestGiniCut = 1000000.0bestGiniCutValue =-1giniValue = 0.0for value in uniqueVals:subDataSet1 = splitDataSet(dataSet, i, value)prob = len(subDataSet1) / float(len(dataSet))subDataSet2 = splitOtherDataSetByValue(dataSet, i, value) prob_ = len(subDataSet2) / float(len(dataSet))#根据公式计算基尼指数giniValue = prob * calcGini(subDataSet1) + prob_ * calcGini(subDataSet2)
# if(len(uniqueVals)==2):
# print("第%d个特征的基尼指数为%.2f" % (i, gini_A))
# break
# else:
# print("第%d个特征第%d个样本的基尼指数为%.2f" % (i, value, gini_A))#找出最优切分点if (giniValue < bestGiniCut):bestGiniCut = giniValuebestGiniCutValue = value# 选择最优特征向量GiniIndex = bestGiniCutif GiniIndex < bestGiniIndex:bestGiniIndex = GiniIndexbestSplictValue = bestGiniCutValuebestFeature = i# 若当前结点的划分结点特征中的标签超过3个,则将其以之前记录的划分点为界进行二值化处理binaryZationDataSet(bestFeature,bestSplictValue,dataSet)return bestFeaturedef majorityCnt(classList):classCount={}#统计classList中每个元素出现的次数for vote in classList:if vote not in classCount.keys():classCount[vote]=0classCount[vote]+=1#根据字典的值降序排列sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)return sortedClassCount[0][0]def createTree(dataSet,labels,featLabels):classList=[example[-1] for example in dataSet]#如果D中所有实例同属于一个类if classList.count(classList[0])==len(classList):return classList[0]#遍历完所有特征时返回出现次数最多的类标签if len(dataSet[0])==1:return majorityCnt(classList)#选择最优特征bestFeat=chooseBestFeatureToSplit(dataSet)#最优特征的标签bestFeatLabel=labels[bestFeat]featLabels.append(bestFeatLabel)#根据最优特征的标签生成树myTree={bestFeatLabel:{}}#删除已经使用的特征标签del(labels[bestFeat])#得到训练集中所有最优特征的属性值featValues=[example[bestFeat] for example in dataSet]#去掉重复的属性值uniqueVls=set(featValues)#遍历特征,创建决策树for value in uniqueVls:myTree[bestFeatLabel][value]=createTree(splitDataSet(dataSet,bestFeat,value),labels,featLabels)return myTreeif __name__=='__main__':dataSet,labels=createDataSet()featLabels=[]myTree=createTree(dataSet,labels,featLabels)print(myTree)
{'有自己的房子': {0: {'有工作': {0: 'no', '其他': 'yes'}}, '其他': 'yes'}}
决策树的剪枝
决策树生成算法递归地产生决策树,直到不能继续下去为止。这样产生的树往往对训练数据的分类很准确,但对未知的测试数据的分类却没有那么准确,即出现过拟合现象。解决这个问题的办法是考虑决策树复杂度,对已产生的决策树进行简化。
在决策时学习中将已生成的树进行简化的过程称为剪枝(pruning)。具体地,剪枝从已生成的书上裁掉一些子树或叶节点,并将其根节点或父节点作为新的叶节点,从而简化分类树模型。
在《统计学习方法》中介绍了一种简单的决策树学习的剪枝算法,但是由于其内容我尚存一些疑问,故暂时空着。
决策树(二)——决策树的生成相关推荐
- 决策树及决策树生成与剪枝
文章目录 1. 决策树学习 2. 最优划分属性的选择 2.1 信息增益 - ID3 2.1.1 什么是信息增益 2.1.2 ID3 树中最优划分属性计算举例 2.2 信息增益率 - C4.5 2.3 ...
- 机器学习实验二---决策树python
机器学习实验二---决策树python 一.了解一下决策树吧 决策树基本流程 信息增益 决策树的优缺点 二.数据处理 三.决策树的构建 计算给定数据集的香农熵 按照给定特征划分数据集 选择最好的数据划 ...
- 分类决策树 回归决策树_决策树分类器背后的数学
分类决策树 回归决策树 决策树分类器背后的数学 (Maths behind Decision Tree Classifier) Before we see the python implementat ...
- 机器学习_决策树(信息熵,决策树,决策树优化,剪枝)
今天开始学决策树,尽管导师每天催任务,但我还是得把机器学习学完,学懂,现在看西瓜书很有感觉.这个机器学习太好了,感觉学着学着就变聪明了一样,不断地让自己的思维变得更敏捷,所以我爱机器学习. 今天要讲的 ...
- 舒工深度解析不规则场地座位二维码生成规则
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8" ...
- 玩转Android之二维码生成与识别
二维码,我们也称作QRCode,QR表示quick response即快速响应,在很多App中我们都能见到二维码的身影,最常见的莫过于微信了.那么今天我们就来看看怎么样在我们自己的App中集成二维码的 ...
- java 二维码生成和解析
2019独角兽企业重金招聘Python工程师标准>>> <!-- 二维码 --><dependency><groupId>com.google.z ...
- 支付宝支付 第五集:二维码生成工具
支付宝支付 第五集:二维码生成工具 一.代码 目录结构 BufferedImageLuminanceSource.java package com.dzy.alipay.qrcode;import c ...
- Android之二维码生成与扫描
转载请标明出处: http://blog.csdn.net/hai_qing_xu_kong/article/details/51260428 本文出自:[顾林海的博客] ##前言 月底离开公司,准备 ...
- [开源]C#二维码生成解析工具,可添加自定义Logo
原文:[开源]C#二维码生成解析工具,可添加自定义Logo 二维码又称 QR Code,QR 全称 Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的 Bar Co ...
最新文章
- 利用最小二乘法求解仿射变换参数
- Nature子刊:微生物来源分析包SourceTracker——结果解读和使用教程
- 第九周项目二-我的数组类
- Spark Streaming(三)zookeepe搭建
- ajax是操作系统吗,ajax 跟post 可以设置它是否同步执行
- 基于websocket的聊天实现逻辑(springboot)
- Docker系列四~docker安装mysql
- POJ3750 小孩报数问题【模拟】
- Vue:刷新页面 且只刷新一次
- VBA,工作簿workbook相关操作,workbooks.add workbooks.save workbooks.saveas 等等
- 水星如何设置虚拟机服务器,水星mercury路由器电脑怎么设置?
- 2019下半年的教师资格考试~学霸大佬们总结的记忆口诀涨分必备
- word调整标题编号
- kaldi跑自己数据遇到的问题合集(持续更)
- Agora Flat:在线教室的开源初体验
- 【openMP并行计算】计算π
- 限制Input只能输入汉字、数字
- NBA篮球英语专业术语
- 企业面试题|最常问的MySQL面试题集合(一)
- BLE数据报文格式解析
热门文章
- 第三方客户端配置个人教育邮箱(以华北电力大学邮箱为例)
- Andorid开发中好用的库
- 注册苹果开发者,登录后提示Need assistance with accessing your developer account?解决过程
- Package com.google.common.collect
- Fast Online Object Tracking and Segmentation: A Unifying Approach
- Arrays.asList 转换数组成list集合失败的原因
- 如何优雅地下载和使用Apache Commons_io
- 范式1NF、2NF、3NF和BCNF的区别
- ABAQUS如何输出应力应变曲线(XY曲线)
- c++练习题,动物爱吃什么