python 决策树简单实现

一、决策树一般流程

1、收集数据

2、准备数据(数值型数据必须离散化)

3、分析数据

4、训练数据

5、学习数据,使用经验树计算错误率

二、构建决策树由以下三部分所构成 

1、特征选择

2、决策树生成

3、决策树剪枝

      特征选择:

      如果将一个特征进行分类的结果和随机分类的结果无异,则可以认为这个特征不具备分类能力,则如果把这个特征去掉,那么这颗决策树的精度不会有太多的影响。

              信息增益和熵:

              这里是决策树中最难懂的部分,我们首先要知道信息增益就是数据集之前和之后信息发生的变化。若我们知道如何计算信息增益,我们就可以计算依靠每个特征划分数据集所得到的信息增益,如果按照某个特征所划分的数据获得的信息增益最高,则称为这个特征就是最好的选择。

              我这里举个例子:有西瓜、冬瓜、南瓜、黄瓜,这几个瓜有很多属性,我们统计了他们的颜色,形状,重量等;我们知道要区分这几个瓜很容易,但是机器却不是这么想的,我们让机器学习,我们先把重量当做划分的依据,说小于5斤的(举个例子不必当真)不是西瓜,那有些小西瓜就马上被排除了,但如果我们把颜色做划分依据,说黄色外壳的不是西瓜,那基本上就不会出错。显然颜色对于选择更加重要。

             熵

      熵表示随机变量不确定性的度量,设X是一个离散型的随机变量,分布是P(X = x_i) = p_i,\ i=1,2,\cdots,n

             则随机变量X的熵 定义 为:H(X)= - \sum_{i=1}^{n} p_{i}log(p_i)

            对于0-1选择,可以得到:H(X)=-plog(p)-(1-p)log(1-p)

从而有\frac{\partial H(X)}{\partial p} = -log(\frac{p}{1-p})            

            若将Pi看做x,log(pi)看做f(x),那么H(x)=xf(x)其实看起来很像期望!!对吗!他是对于随机变量x的概率的期望。有点绕。

             如何计算熵:

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) #log base 2

return shannonEnt

            上面的代码很好理解,你首先要做的是计算每一个Label出现的概率p,然后乘上log(p);主要的就是求概率,首先:先计算一共有多少记录,概率等于出现次数除以总记录数(上文说过是离散的,还记得吧!);对于第四行代码,很简单,举个例子,aaabdsdesa,每一个字符出现次数是怎么算的,我写一下C++代码你就知道了。

int d[26];

for(int i=0;i<len(str);i++)

{

          d[str[i]-'a']++;

}

             就是上面这个意思,稍微理解下,就会了。

             划分数据集:

             上面也说了,信息增益就是数据集之前和之后信息发生的变化,我们先用上面的代码将全部数据计算熵,接着,我们要利用某些规则去划分数据集,然后计算这些数据集的熵,看效果怎么样,这样才能选择哪个划分是最好的,因为计算机很“笨”,只能一个一个比较才能求出最好的,下面是划分数据集的代码。

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 retDataSet

               选择最好的划分方式:

def chooseBestFeatureToSplit(dataSet):
      numFeatures = len(dataSet[0]) - 1      #the last column is used for the labels
      baseEntropy = calcShannonEnt(dataSet)
      bestInfoGain = 0.0; bestFeature = -1
      for i in range(numFeatures):        #iterate over all the features
           featList = [example[i] for example in dataSet]#create a list of all the examples of this feature
           uniqueVals = set(featList)       #get a set of unique values
           newEntropy = 0.0
           for value in uniqueVals:
                  subDataSet = splitDataSet(dataSet, i, value)
                  prob = len(subDataSet)/float(len(dataSet))
                  newEntropy += prob * calcShannonEnt(subDataSet)     
           infoGain = baseEntropy - newEntropy     #calculate the info gain; ie reduction in entropy
           if (infoGain > bestInfoGain):       #compare this to the best gain so far
                  bestInfoGain = infoGain         #if better than current best, set to best
                  bestFeature = i
return bestFeature 

下一节继续。。。

猜你喜欢

转载自blog.csdn.net/qq_36336522/article/details/79934099
今日推荐