ディシジョン・ツリーが定義されています
ツリーしたがって、データを分類、機能の選択されたデータセットを分割
ディシジョン・ツリーのビルドプロセス
特徴選択:現在のノード分割の標準としてトレーニングデータから特徴を選択する
決定木:選択した機能に基づいて評価基準を、再帰的に生成された子ノードの下からデータセットはサブツリーでなくなるまでは成長が止まっている
剪定:ツリーレベルが深すぎる場合、それはオーバーフィッティング、(前の剪定や剪定を含む)の木の大きさや構造を減らすために剪定ニーズが発生します
生成された決定木を再帰的プロセスであり、決定木:注意基本的なアルゴリズム、再帰戻り、ここで3つの状況がある:
1.現在のサンプルは、同じカテゴリの右ノード、の分周なし含ま
2.属性の現在のセットが空である、または全てのサンプルのすべてのプロパティに同じ値ではありません分割
現在のノードを含む3サンプルセットが分割されない空き缶であります
ディシジョン・ツリー・アルゴリズム
ID3 | 情報利得により、 |
---|---|
C4k5 | 情報利得比によって |
カート | ジニ係数により、 |
- ID3
;情報データを分類達成するために測定された情報エントロピーと情報ゲインに基づいて、理論、への
分割後の分割に最大の属性情報を獲得、情報の測定属性の選択を獲得選択する:コアアイデア
エントロピ | |
---|---|
情報利得 |
例:
上記の場合、サンプル数:14、サンプル数が遅くとも:5;後のサンプル数:9
のステップ:データセット情報エントロピー計算
最初の分割の特性を決定するための第2のステップ--- - >情報ゲインは、属性ごとに計算され、サイズ:
年齢によって | |
---|---|
収入により、 | |
学生による | |
クレジットにより、 | |
最後に、情報利得を比較します | 最初の結果は、年齢によって分割されました |
第3のステップは、プロパティの第二の分割を決定することである:
分割処理最初のと同様、データセットの年齢に基づいて
停止分割に比較可能なデータの最後のノードまで
決定木の利点 | 概念的には、計算の複雑さは、高出力を分かりやすく説明強く簡単ではありません。単純なデータの作成、小文字を区別しない中間値の欠落、アプリケーションの広い範囲 |
---|---|
決定木の欠点 | オーバーマッチした問題を引き起こす可能性があり、より困難な情報が欠落しているときに対処するために、情報利得の測定は、分類属性として高い値属性に有利にバイアスされます |
- C4.5
ID3アルゴリズム、プロパティは唯一の離散することができ、C4.5はID3アルゴリズム最適化されています
1の改善 | 代わりに、情報利得の属性を持つより、プロパティを選択し、プロパティの値を選択する際の選択肢の不足を克服する傾向があるとする情報ゲイン情報利得比を使用します: |
---|---|
2の改良 | 連続離散属性値の処理を完了するために |
3の改善 | あなたはのプロパティ値の損失の場合を扱うことができます |
4の改良 | プルーン工事完了後のツリー:事前に剪定:あらかじめ設定ニーズ木のいくつかのレベルを生成するために、樹木の成長を停止する訓練セットの後に完全に正しい分類;剪定:ツリー全体が生成させ、その後、その後、プルーン |
例:
- CART
ID3は、各列を介して、情報ゲイン分類にのみ適用され
、各列の情報ゲインによるC4.5
分類後のジニ係数によって-----とCART純度
分割がデータを有効にするために設計された、純粋な、意思決定なります分類ツリー、CART値は、GINI純度のノードを使用して測定した場合、近い真値にツリー出力をもたらす場合、サンプル分散の測定ノードの純度、より不純なノード、ノードの分類または悪い効果の予測を使用して、回帰木、;
CART両方の分類を行うことができますし、リターンを行うことができますが、バイナリツリーがある
例は:
そこにプレスルーム状況 | |
---|---|
配偶者の有無により、 |
分裂の連続値:
達成ID3python
# -*- coding: utf-8 -*-
"""
Created on Sat Mar 7 11:58:40 2020
@author: DELL
"""
#定义函数,构造函数数据集
import operator
from math import log
import subprocess
from sklearn import tree
def createDataSet():
labels =["头发","声音"]#两个特征
dataSet=[['长','粗','男'],
['短','粗','男'],
['短','粗','男'],
['长','粗','女'],
['长','细','女'],
['短','粗','女'],
['短','细','女'],
['长','粗','女']]
return dataSet,labels
#获取函数类型的类别
def createTree(dataSet,lables):
#获取每个类别男生数量,女生数量
classlist=[example[-1] for example in dataSet]
#print(classlist)
#统计每个类别的人数classlist.count(classlist)
#判断 是否停止树的计算
#第一种情况,如果类别人数和总人数相等,不进行下述计算
if classlist.count(classlist[0])==len(classlist):
return classlist[0]
#第二种情况,如果数据集中只有一个人 也不进行计算
if len(dataSet[0]) == 1:
return majorityCnt(classlist)
#选择分裂类型
bestFeat = chooseBestFeatureTosplit(dataSet)
bestFeatlable = lables[bestFeat]
myTree = {bestFeatlable:{}}
del(lables[bestFeat])
featValues=[example[bestFeat] for example in dataSet]
uniqueVals=set(featValues)
for value in uniqueVals:
subLabels=lables[:]
myTree[bestFeatlable][value]=createTree(splitDataSet(dataSet,bestFeat,value),subLabels)
return myTree
def chooseBestFeatureTosplit(dataSet):
#获取特征列的个数("长",“粗”)两列
numFeature = len (dataSet[0])-1
#对整个数据集 计算 信息熵
baseEntropy = calcShannonEnt(dataSet)
#对每一列计算条件信息熵
bestInfoGain = 0
bestFeature = -1
#把两列属性获取出来
for i in range (numFeature):
featlist = [example [i] for example in dataSet]
#print(featlist)
'''['长', '短', '短', '长', '长', '短', '短', '长']
['粗', '粗', '粗', '粗', '细', '粗', '细', '粗']'''
#获取每个特征里面 有的属性值 长的一列 粗的一列
uniqueVals = set(featlist)
#print(uniqueVals)
'''{'长', '短'}
{'粗', '细'}'''
newEntroy = 0
#统计每个类别的 样本的 数量--->得出信息熵
for value in uniqueVals:
subDataSet = splitDataSet(dataSet,i,value)#对哪个数据集,哪个类别,哪个属性
#计算 条件信息熵
prob = len(subDataSet)/float(len(dataSet))
newEntroy += prob*calcShannonEnt(subDataSet)
#信息增益 信息熵-条件信息熵
infoGain= baseEntropy - newEntroy
#比较两列属性的信息增益
#比较出最大的信息增益
if(infoGain > bestInfoGain):
bestInfoGain=infoGain
bestFeature = i
return bestFeature
#计算信息熵
#按照某个特征值 对数据集进行划分,希望获取某个类的总个数
#返回和某个类别一样的所有数据“长”, 去除掉 当前的属性列 所有数据集
def splitDataSet(dataSet,i,value):
retDataSet=[]
for vote in dataSet:
if vote[i]==value:
reduceFeatVec = vote[:i]
reduceFeatVec.extend(vote[i+1:])
retDataSet.append(reduceFeatVec)
return retDataSet
def calcShannonEnt(dataSet):
classCount = {}
#遍历整个 数据集 各个类别的人数统计出来
for vote in dataSet:
currentLabel = vote [-1]
if currentLabel not in classCount.keys():
classCount[currentLabel]=0
classCount[currentLabel] += 1
#得到 (男,3) (女,4)这种类别
#根据 信息熵的计算方式 得到信息熵
shannonEnt = 0
for key in classCount:
#获取整个数据集的大小-----14
numEntries = len(dataSet)
prob = float(classCount[key])/numEntries
shannonEnt -= prob*log(prob,2)#基础的信息熵
return shannonEnt
def majorityCnt(classlist):
classcount ={}
#在classlist男和女进行遍历
for vote in classlist:
if vote not in classcount.keys():
#如果没有男或女这个标签就添加并加一
classcount[vote] = 0
classcount[vote] += 1
sortedClasscount=sorted(classcount.items(),key=operator.itemgetter(1),reverse=True)
#print (sortedClasscount[0][0])
return sortedClasscount[0][0]
if __name__=='__main__':
dataSet,lables = createDataSet()
#print(dataSet)
print(createTree(dataSet,lables))