ディシジョン・ツリー・シリーズ3 - ジニ指数、マイナスの枝と

- -コーディング:UTF-8 - -

「」」
火8月14日17時36分57秒2018で作成されました

@author:weixw
""」
NPとしてインポートnumpyの

条件は、右のサブツリー真である:条件が偽であるバイナリツリー、左部分木を使用して定義ツリー構造、

leftBranch:左側のサブツリーノード

rightBranch:右部分木のノード

COL:最大ゲイン情報、対応する列インデックス

値:最適な列インデックス、分割されたデータ型の値

結果:分類結果

要約:最大の情報ゲインサンプル情報

データ:最大情報利得データセット

クラスツリー:
DEF INIT(自己、leftBranch =なし、rightBranch =なし、COL = -1、値=なし、結果=なし、要約=なし、データ=なし):
self.leftBranch = leftBranch
self.rightBranch = rightBranch
自己。 COL = COL
self.value =値
self.results =結果
self.summary =要約
self.data =データ

def __str__(self):
    print(u"列号:%d" % self.col)
    print(u"列划分值:%s" % self.value)
    print(u"样本信息:%s" % self.summary)
    return ""

データ分割

DEF splitDataSet(のdataSet A、値、カラム):
leftList = []
rightList = []
値が数値であるか否かを判断する
IF(でisinstance(値、INT)又はでisinstance(値、フロート)):
データの各行を介し#
rowDataためにdataSet:
指定された列場合列値> =値は、別段rightListに記憶されたラインleftListに格納されたデータ、
IF(rowData [列]> =値):
leftList.append(rowData)
他:
rightList.append (rowData)は
#は、公称値のタイプである
:他の
データの各行を介し#
データセット内rowData用:
行が指定されている場合は#がカラム値==値は、それ以外の場合にrightListに格納されているラインleftListに格納されたデータ、
IF(rowData [列] ==値):
leftList.append(rowData)
他:
rightList.append(rowData)は
leftList、rightListを返します

統計カテゴリの各サンプルタグ番号

「」「
[A「」B 『この関数は、ジニ値ヘルパーを算出し、データセットが入力するためのものであると仮定」 、』 C「」A「」A「」D 『]、
出力は[』でA ':3、' B ' :1、' C ':1、' D ':1]、 その結果、各カテゴリデータセットの数についての統計
' ''

calculateDiffCount DEF(のdataSet A):
結果= {}
のdataSet Aのデータの:
#データ[-1]ベースの最後のデータセット、すなわちラベルがある
場合、データ[-1]れていない結果で:
results.setdefault(DATA [-1] 、1)。
それ以外:
。結果[データ[-1]] + 1 =
リターン結果

達成するためのジニ係数の式

DEFジニ(のdataSet A)
の計算値ジニ(計算GINI)#
すべての行の#データ
長= LEN(のdataSet)
列データセットのマージ#ラベル後に
結果を= calculateDiffCount(のdataSet A)
IMP = 0.0
結果でIのための:
IMP + =結果[I] / *長さ結果[I] /長
リターン1 - 。IMP

決定木

「」「アルゴリズムステップは、」」 『
』 『バイナリツリーを構築し、再帰的に各ノードの動作を、以下、ルートノードから始めて、トレーニングデータセットに応じて』:
訓練データセットノードの集合はDであり、前記データセットは、事前情報ゲインを算出します。この場合、各機能Aにおいて、その可能性を取る
テストを「YES」または「NO」Dにはジニ指数を用いて、二つの部分D1及びD2に分割されている> =サンプル点Aに応じて、それぞれの値を情報利得の計算。
可能なすべての機能とそのすべての可能なカットポイント2 Aは、最適な切断特性として最大情報ゲインと対応する特徴点を選択し
、最適なカットと最適な特性に基づいて、最適なカットポイントアクティブノードから二つのサブノードを生成する点は、訓練データセットは、特性に応じて2つのつの子ノードに割り当てられています。
停止条件が満たされるまで1、2、3は、再帰的、2つのつの子ノードを必要とします。
図4は、CARTの決定木を生成します。
「」「」「」「」「」「」「」「」「」「'」

evaluationFunc =ジニ:ジニ係数は、注目指標を測定するために使用されます

DEF buildDecisionTree(のdataSet A、evaluationFunc =ジニ):
ジニ指数データセットに基づいて計算#
baseGain = evaluationFunc(のdataSet A)
各行(すなわち、列の合計数)の長さの計算位
columnLength = lenが(データセットが[0] A)
は、データアイテムの合計数を計算します
LEN = rowLength(のdataSet A)
初期
bestGain = 0.0#情報最大利得
最大利得のbestValue =列インデックス情報なし#、及び分割データのサンプル値を設定
bestSet =なし#情報が聞こえ最大サンプル値データ分割を得ます後のデータのサブセット
のデータの各列から(最後のものを除く)#タグ列、
範囲内のCOLため(columnLength - 1):
は、指定された列データ取得
colSet = [データセット内の実施例については実施例[COL]をA]
は、指定された列のサンプルを取得します一意の値
uniqueColSet =セット(colSet)
サンプルの指定された列セットトラバース#
:uniqueColSetにおける値の
#分割データセット
leftDataSet、rightDataSet = splitDataSet(データセット値、COL)
#計算されたサブデータセットの確率のpython3は"/"の結果を分割小数である
プロップ= LEN(leftDataSet)/ rowLength
#計算された情報ゲイン
InfoGain = baseGain - *プロプevaluationFunc(leftDataSet) - (1 -プロパ)* evaluationFunc(rightDataSet)
最大ゲイン値、データのサブセットを識別するための列インデックス情報
:IF(InfoGain> bestGain)
bestGain = InfoGain
bestValue =(COL、値)
bestSet =(leftDataSet、rightDataSet)
ノード情報
#1 nodeDescription = {「不純物: %.3f '%baseGain、'サンプル:%のD '}%rowLength
nodeDescription = {'不純物':' .3f% '%baseGain、'試料':' D「rowLengthの%}%
一貫性のないデータの行ラベルカテゴリがあってもよいですカテゴリを続ける
#再帰終了条件をしなければならない
IF bestGain> 0:
は、再帰的に左サブツリーのノードを生成し、右の部分木のノード
leftBranch = buildDecisionTree(bestSet [0] 、evaluationFunc)
rightBranch = buildDecisionTree(bestSet [1]、evaluationFunc)
ツリーを返す(leftBranch = leftBranch、rightBranch = rightBranch、COL = bestValue [0]
値= bestValue [1]、要約= nodeDescription、データ= bestSetの)
他:
#数据行标签类别都相同、分类终止
ツリー(結果= calculateDiffCount(のdataSet)、要約= nodeDescription、データ=データセット)を返します

createTree DEF(のdataSet A、evaluationFunc =ジニ):
再帰決定木、もしゲイン= 0、戻り止め
セット基本データの#ジニ指数
baseGain = evaluationFunc(のdataSet A)
各行の長さを計算位(即ち、列の合計数)
LEN = columnLength(のdataSet [0])
のデータ項目位数計算
rowLength = LEN(のdataSet A)
初期
bestGain = 0.0#情報取得最大
最大利得のサンプル値bestValue =列インデックス情報なし#、分割データがセット
bestSetを=なし#情報ゲイン最大値が、分割されたデータのサンプル値後のデータのサブセットを聞くこと設定
データの各列を介して、(最後のものを除く)#タグ列を
(。columnLength - 1)の範囲でCOL用:
#が指定された列のデータを取得し
colSet = [ dataSet A]実施例については実施例[COL]
指定された列の固有値取得#サンプル
uniqueColSet =セット(colSet)
カラム指定サンプルセットトラバース#
uniqueColSetの値の場合:
#分割データセット
leftDataSet、rightDataSet = splitDataSet(のdataSet A、値、COL)
は、サブデータセットの確率を算出し、のpython3 "/"結果を分割小数である
プロップ= LEN(leftDataSet)/ rowLengthの
#算出情報ゲイン
infoGain = baseGain - * evaluationFunc(プロプ leftDataSet) - (1 -プロプ)* evaluationFunc(rightDataSet)
最大情報ゲイン、値、データのサブセットを見つけるために#列インデックス
IF(InfoGain> bestGain):
bestGain = InfoGain
bestValue =(COL、値)
bestSet =(leftDataSet、rightDataSet )

impurity = u'%.3f' % baseGain
sample = '%d' % rowLength

if bestGain > 0:
    bestFeatLabel = u'serial:%s\nimpurity:%s\nsample:%s' % (bestValue[0], impurity, sample)
    myTree = {bestFeatLabel: {}}
    myTree[bestFeatLabel][bestValue[1]] = createTree(bestSet[0], evaluationFunc)
    myTree[bestFeatLabel]['no'] = createTree(bestSet[1], evaluationFunc)
    return myTree
else:  # 递归需要返回值
    bestFeatValue = u'%s\nimpurity:%s\nsample:%s' % (str(calculateDiffCount(dataSet)), impurity, sample)
    return bestFeatValue

テストの並べ替え:

「「修飾された葉ノードを見つけるために、所定のバイナリツリー走査試験データによれば」」「」
「」[5.9,3,4.2,1.75]、例えば、テストデータを」、決定木分類を生成したトレーニングデータシーケンスに従う
最初の2ルートノードとテストデータ= 4.2>ツリーに対応する(2)の値(3)と比較し、> =左サブツリー、または横断右サブツリートラバース3、
リーフノードは、「'」の結果であります

分類DEF(データ、ツリー):
はリーフノード、リーフノード戻る関連情報は、トラバースを継続するか否か否かを判断する
IF tree.results = :!なし
「%のSの\ S N - %」Uを返す%を(ツリー.results、tree.summary)
他:
分岐なし=
V =データ[tree.col]
数値データ
IFでisinstance(V、INT)又はでisinstance(V、フロート):
IF V> = tree.value:
支店=ツリー.leftBranch
他:
ブランチ= tree.rightBranch
他#公称データ
IF V == tree.value:
ブランチ= tree.leftBranch
他:
ブランチ= tree.rightBranch
分類を返す(データ、支店)

デフloadCSV(fileNameに):
デフconvertTypes(S):
S = s.strip()
してみてください:
リターン・フロート(S)場合を'' Sの他にint型(S)で
ValueErrorを除い:
リターン秒

data = np.loadtxt(fileName, dtype='str', delimiter=',')
data = data[1:, :]
dataSet = ([[convertTypes(item) for item in row] for row in data])
return dataSet

多数決

列の結果の数まで同じ値

DEF majorityCnt(CLASSLIST):
インポートオペレータ
classCounts = {}
:CLASSLISTにおける値の
場合(値ないclassCounts.keysに()):
classCounts [値] = 0
classCounts [値] + = 1
sortedClassCount =ソート(classCounts.items( )、キー= operator.itemgetter(1)= TRUE)逆
リターンsortedClassCount [0] [0]

剪定アルゴリズム(先行順走査方法:ルート=>左サブツリー=>右サブツリー)

「」アルゴリズムのステップは」

  1. バイナリツリーの剪定アルゴリズムのルートから開始し、左と右のノードがリーフノードである再帰的になるまで
  2. 計算親ノード(子ノードがリーフノードである)情報ゲインinfoGain
  3. infoGain <miniGain、サンプルの数は、置換された親ノードにリーフノードを選択した場合
  4. 1,2,3循環は、ツリーの完全なトラバーサルまで、
    「」「」「」「'」

:DEF(木、miniGain、evaluationFunc =ジニ)プルーン
:印刷(U「現在のノード情報」)
を印刷(STR(木))
現在のノードの左の部分木は、左部分木を横断、リーフノードでない場合は#を
(場合==なしtree.leftBranch.results):
印刷(U "左サブツリーノードの情報:")
を印刷(STR(tree.leftBranch))
プルーン(tree.leftBranch、miniGain、evaluationFunc)
現在の右の子ノードの場合ツリーは葉ノードは、右のサブツリーを横断していない
IF(tree.rightBranch.results ==なし):
印刷(U "ノード情報の右部分木:")
を印刷(STR(tree.rightBranch))
プルーン(tree.rightBranch、 miniGain、evaluationFunc)
左サブツリー及び右サブツリーがリーフノードである
(tree.leftBranch.results =なしとtree.rightBranch.results =なしIF):!!
#左葉ノードのデータ長算出
leftLen = LENを( tree.leftBranch.data)
は、右の葉ノードのデータ長算出
rightLen = LEN(tree.rightBranch.data)を
左の葉ノード#計算された確率
leftProp leftLenは= /(+ leftLen rightLen)は
#は、ノード(リーフノードサブクラス)のゲイン情報を算出
InfoGain =(evaluationFunc(tree.leftBranch.data tree.rightBranch.data +) -
* evaluationFunc leftProp(tree.leftBranch.data) - (1 - leftProp)* evaluationFunc(
tree.rightBranch.data))
ゲイン情報<所定の閾値は、次いで、リーフノードと親ノードが非常に異なる特性ではなく、切断することができます分岐
(InfoGain <miniGain)IF:
は、リーフノードデータの周囲にマージ
のdataSet A = + tree.rightBranch.data tree.leftBranch.data
#はラベル列取得
[Aデータセット内の例えば[-1]実施例] = classLabelsを
#ほとんどのサンプルを見つけます。タグ値
keyLabel = majorityCnt(classLabels)
約リーフノード#タグ値決定
keyLabel IF tree.leftBranch.resultsで:
#左の葉ノード非置換親ノード
tree.data = tree.leftBranch.data
tree.results = tree.leftBranch.results
tree.summary = tree.leftBranch.summary
他:
#叶子结点右取代父结点
tree.data = tree.rightBranch.data
tree.results = tree.rightBranch.results
tree.summary = tree.rightBranch.summary
tree.leftBranch =なし
tree.rightBranch =なし

「」」
2010年10月14日に作成されました

@author:ピーター・ハリントン
「」」
PLTとしてインポートmatplotlib.pyplot

decisionNode = dictの(boxstyle = "鋸歯状"は、Fc = "0.8")
リーフノード= dictの(boxstyle = "円"、FC = "0.7")
arrow_args = dictの(矢のスタイル(arrowstyle)= "< - ")

ツリーのリーフノードを取得します。

getNumLeafs DEF(myTreeの):
= 0 numLeafs
リストに#dict
firstSides =リスト(myTree.keys())
firstStr firstSides = [0]
myTreeのsecondDict = [firstStr]
secondDict.keysにおけるキーの():
リーフか否かを判断しますノード(タイプによって決定される、子クラスは、型STR存在しない。サブクラスが存在し、その後のdict)
タイプ(secondDict [キー])IF == .__名__「辞書」:#テストdictonairesが表示される場合、ノードは、にあります場合、彼らはリーフノードではない
numLeafs + = getNumLeafs(secondDict [キー])
他:+ = 1 numLeafsが。
numLeafsを返します

木の層数を取得します。

DEF getTreeDepth(myTree):
MAXDEPTH = 0
#dict转化为リスト
firstSides =リスト(myTree.keys())
firstStr = firstSides [0]
secondDict = myTree [firstStr]
secondDict.keysにおけるキーの():
タイプ(secondDict [ならキー]).__名前__ == '辞書':ノードがdictonairesあり、そうでない場合は、彼らはリーフノードであるかどうかを確認するために#テスト
thisDepth = 1 + getTreeDepth(secondDict [キー])
他:thisDepth = 1
thisDepth> MAXDEPTHの場合:MAXDEPTH = thisDepth
リターンMAXDEPTH

DEF plotNode(nodeTxt、centerPt、parentPt、nodeTypeの):
createPlot.ax1.annotate(nodeTxt、XY = parentPt、xycoords = '部分を軸'、
xytext = centerPt、textcoords = 'フラクション軸'
= HA、Vaは= "センター" "中央"、バウンディングボックス= nodeTypeの、arrowprops = arrow_args)

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、VA = "センター"、HA = "センター"、回転= 30)

デフplotTree(myTree、parentPt、nodeTxt):#最初のキーは上分割されたどのような偉業を示しています場合
numLeafs =のgetNumLeafs(myTree)#これは、この木の×幅を決定する
深さ= getTreeDepth(myTree)
firstSidesを=リスト(myTree.keys ())
firstStr = firstSides [0]であるべきで、このノードのために#このテキストラベル
cntrPt =(plotTree.xOff +(1.0 +フロート(numLeafs))/ 2.0 / plotTree.totalW、plotTree.yOff)
plotMidText(cntrPt、parentPtを、nodeTxt)
plotNode(firstStr、cntrPt、parentPt、decisionNode)
secondDict = myTree [firstStr]
plotTree.yOff = plotTree.yOff - 1.0 / plotTree.totalD
secondDict.keysにおけるキーの():
もしタイプ(secondDict [キー])。 __name __ ==「辞書」:ノードがdictonairesあるかどうかを確認するために#テスト、そうでない場合は、彼らはリーフノードであります
プロットツリー([キー] secondDict、cntrPt、STR(キー))#recursion
他:#それはリーフノードリーフノードプリントです
plotTree.xOff = plotTree.xOff + 1.0 / plotTree.totalWの
プロットノード([キー] secondDict、(プロットツリー。 XOFF、plotTree.yOff)cntrPt、リーフノード)
plotMidText((plotTree.xOff、plotTree.yOff)cntrPt、STR(キー))
plotTree.yOff = plotTree.yOff + 1.0 / plotTree.totalD

あなたがdictonaryを得るかどうかは、それは木だ知っている、と最初の要素は、別の辞書になります

決定木のサンプルを描く1

DEF createPlot(inTree):
図= plt.figure(1、のFaceColor = '白')
fig.clf()
axprops = dictの(xticks = []、yticks = [])
createPlot.ax1 = plt.subplot(111、frameon =偽、** axprops)ティック#NO
#createPlot.ax1 = plt.subplot(デモのために111、frameon =偽)#ticksをpuropses
#1宽、高间距
)plotTree.totalW =フロート(getNumLeafs(inTree) - 3
plotTreeを。 totalD =フロート(getTreeDepth(inTree)) - 2

plotTree.totalW =フロート(getNumLeafs(エントリ))

plotTree.totalD =フロート(getTreeDepth(エントリ))

plotTree.xOff = -0.5/plotTree.totalW; plotTree.yOff = 1.0;
plotTree(inTree, (0.95,1.0), '')
plt.show()

決定木のサンプルを描く2

DEF createPlot1(inTree):
図= plt.figure(1、のFaceColor = '白')
図= plt.figure(DPI = 255)
fig.clf()
axprops = dictの(xticks = []、yticks = [])
ダニ#NO createPlot.ax1 = plt.subplot(111、frameon = Falseを、** axprops)
#createPlot.ax1 = plt.subplot(111を、frameon = False)がデモpuropsesため#ticks
#宽、高间距
plotTree.totalW =フロート(getNumLeafs(inTree)) - 4.5
plotTree.totalD =フロート(getTreeDepth(inTree))-3
plotTree.xOff = -0.5 / plotTree.totalW。plotTree.yOff = 1.0;
plotTree(inTree、(1.0,1.0)、 '')
plt.show()

ツリー(矩形、リーフノード:楕円ルート状)のルート及びリーフノードを描きます

デフcreatePlot():

図= plt.figure(1、のFaceColor = '白')

fig.clf()

デモpuropsesためcreatePlot.ax1 = plt.subplot(111、frameon = False)が#ticks

plotNode( '決定ノード'、(0.5、0.1)、(0.1、0.5)、decisionNode)

plotNode( 'リーフノード'、(0.8、0.1)、(0.3、0.8)、リーフノード)

plt.show()

DEF retrieveTree(I):
listOfTrees = [{ 'いいえ浮上':{0: 'いいえ'、1:{ 'フリッパー':{0: 'いいえ'、1 'YES'}}}}、
{「いいえサーフェス':{0: 'いいえ'、1:{'フリッパー':{0:{'頭':{0: 'いいえ'、1 'はい'}}、1: 'NO'}}}}
]
リターンlistOfTrees [I]

thisTree = retrieveTree(0)

createPlot(thisTree)

createPlot()

myTree = retrieveTree(0)

numLeafs = getNumLeafs(myTree)

treeDepth = getTreeDepth(myTree)

プリント(U "リーフノードの数:%D" %のnumLeafs)

印刷(U "ツリーの深さ:%dの" %treeDepth)

- -コーディング:UTF-8 - -

「」」
水曜日8月15日午後02時16分59秒2018で作成されました

@author:weixw
"" "
インポートDemo_1.myCart MCと
Demo_1.myCartインポートジニから
IF 名前 == ' メイン ':
TP ASインポートtreePlotter
のdataSet = mc.loadCSV(" F:ディスクファイル\データセット以上の\ Cに移動。 ")CSV
myTree = mc.createTree(のdataSet A、evaluationFunc =ジニ)の
%" myTreeの%)のS:myTreeの印刷(U "
#ドローツリー
プリント(U"決定木を描く:「)
myTreeのtp.createPlot1()
decisionTree MC = .buildDecisionTree(のdataSet A、evaluationFunc =ジニ)
TESTDATA = [5.9,3,4.2,1.75]
R&LT mc.classify =(TESTDATA、decisionTree)
"ポスト分類試験結果:" U)印刷
プリント(R&LT)
プリント()
MC。プルーン(decisionTree、0.4)
R1 = mc.classify(TESTDATA、decisionTree)
( "剪定試験結果:" U)印刷
印刷(R1)

おすすめ

転載: www.cnblogs.com/131415-520/p/11802578.html