機器學習實戰 決策樹 演算法 筆記
trees.py 原始碼部分:
from math import log
import operator
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)
return shannonEnt
def creataDataSet():
dataSet=[[1,1,'yes'],[1,1,'yes'],[1,0,'no'],[0,1,'no'],[0,1,'no']]
labels=['no surfacing','flippers']
return dataSet,labels
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 chooesBestFeatureToSplit(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]
uniqueVals=set(featList)
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
if(infoGain>bestInFoGain):
bestInFoGain=infoGain
bestFeature=i
return bestFeature
def majorityCnt(classList):
classCount={}
for vote in classlist:
if vote not in classCount.keys():
classCount[vote]=0
classCount[vote]+=1
sortedClassCount=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)
return sortedClassCount[0][0]
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=chooesBestFeatureToSplit(dataSet)
bestFeatLabel=labels[bestFeat]
myTree={bestFeatLabel:{}}
del(labels[bestFeat])
featValues=[example[bestFeat] for example in dataSet]
uniqueVals=set(featValues)
for value in uniqueVals:
subLabels=labels[:]
myTree[bestFeatLabel][value]=createTree(splitDataSet(dataSet,bestFeat,value),subLabels)
return myTree
def classify(inputTree,featLabels,testVec):
firstStr=inputTree.keys()[0]
secondDict=inputTree[firstStr]
featIndex=featLabels.index(firstStr)
for key in secondDict.keys():
if testVec[featIndex]==key:
if type(secondDict[key])==dict:
classLabel=classify(secondDict[key],featLabels,testVec)
else:classLabel=secondDict[key]
return classLabel
treePlotter.py 原始碼部分:
import
matplotlib.pyplot as plt
decisionNode=dict(boxstyle="sawtooth",fc="0.2")
leafNode=dict(boxstyle="round4",fc="0.8")
arrow_args=dict(arrowstyle="->")
def plotNode(nodeTxt,centerPt,parentPt,nodeType):
createPlot.ax1.annotate(nodeTxt,xy=parentPt,xycoords='axes fraction',xytext=centerPt,textcoords='axes fraction',va="center",ha="center",bbox=nodeType,arrowprops=arrow_args)
def createPlot():
fig=plt.figure(1,facecolor='blue')
fig.clf()
createPlot.ax1=plt.subplot(111,frameon=False)
plotNode('a decisionNode',(0.5,0.1),(0.1,0.5),decisionNode)
plotNode('a leafNode',(0.8,0.1),(0.3,0.5),leafNode)
plt.show()
def getNumLeafs(myTree):
numLeafs=0
firstStr=myTree.keys()[0]
secondDict=myTree[firstStr]
for key in secondDict.keys():
if type(secondDict[key])==dict:
numLeafs+=getNumLeafs(secondDict[key])
else: numLeafs+=1
return numLeafs
def getTreeDepth(myTree):
maxDepth=0
firstStr=myTree.keys()[0]
secondDict=myTree[firstStr]
for key in secondDict.keys():
if type(secondDict[key])==dict:
thisDepth=1+getTreeDepth(secondDict[key])
else: thisDepth=1
if thisDepth>maxDepth:maxDepth=thisDepth
return maxDepth
def retrieveTree(i):
listOfTree=[{'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 listOfTree[i]
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)
def plotTree(myTree,parentPt,nodeTxt):
numLeafs=getNumLeafs(myTree)
depth=getTreeDepth(myTree)
firstStr=myTree.keys()[0]
cntrPt=(plotTree.xOff+(1.0+float(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
for key in secondDict.keys():
if type(secondDict[key])==dict:
plotTree(secondDict[key],cntrPt,str(key))
else:
plotTree.xOff=plotTree.xOff+1.0/plotTree.totalW
plotNode(secondDict[key],(plotTree.xOff,plotTree.yOff),cntrPt,leafNode)
plotMidText((plotTree.xOff,plotTree.yOff),cntrPt,str(key))
plotTree.yOff=plotTree.yOff+1.0/plotTree.totalD
def createPlot2(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
plotTree(inTree,(0.5,1.0),'')
plt.show()
筆記部分:
注:一般情況下
如果出現錯誤都是由於Python換行的問題 tab鍵和space鍵不公用 我用的是notepad++ 文字工具 沒有自帶換行功能
trees.py 原始碼部分:
from math import logimport operatordef calcShannonEnt(dataSet):numEntries=len(dataSet)labelCounts={}for featVec in dataSe
問題:NameError: name 'reload' is not defined
import imp
import trees
imp.reload(trees)
結論:已經匯入過的模組才能用reload, reload的引數應該是模組名,而不是檔名。在pyhton3.x中要先匯入檔案
1.ID3演算法
預備知識
1.資訊熵:
2.資訊增益
演算法內容
引入了資訊理論中的互資訊(資訊增益)作為選擇判別因素的度量,即:以資訊增益的下降速度作為選取分類屬性的標準,所選的測試屬性是從根節點到當前節點的路徑上從沒有
獲取樹節點的資料以及樹的層數
def getNumLeafs(myTree):
numLeafs=0
firstStr
決策樹是一種通過推斷分解,逐步縮小待推測事物範圍的演算法結構,重要任務就是理解資料中所蘊含的知識資訊,可以使用不熟悉的資料集合,並從中提取出一系列規則,根據資料集建立規則的過程就是機器學習的過程。
優點:計算複雜度不高,輸出結果易於理解,對中間值的缺失不敏感,可以處理不相關特
程式碼:
import numpy as np
import operator
#計算夏農熵,度量資料集的無序程度
def calcShannonEnt(dataSet):
numEntries = len(dataSet)
labelCountes = {
from math import log
#計算給定的熵
def calcsahnnonent(dataset):
numentries = len(dataset) #計算例項的總數
labelcounts ={}
#
#coding=utf8
‘’’
Created on 2018年11月4日
@author: xiaofengyang
決策樹演算法:ID3演算法
‘’’
from sklearn.feature_extraction import DictVectorize
1-1 基本流程
決策樹是一個有監督分類與迴歸演算法。
決策樹的生成只考慮區域性最優,相對的,決策樹剪枝則考慮全域性最優。
一、概念:
決策樹:是一種樹形結構,其中每個內部節點表示一個屬性上的判斷,每個分支代表一個判斷結果的輸出,最後每個葉節點代表一
本文記錄的是《機器學習實戰》和《統計學習方法》中決策樹的原理和實現。
1、決策樹
定義:分類決策樹模型是一種描述對例項進行分類的樹形結構。決策樹由節點(node)和有向邊(directed edge)組成。節點有兩種型別:內部結點和葉結點,內部結點表示一
決策樹的第一個演算法為,計算給定資料集的夏農熵
夏農熵的計算公式都給出來了,下面貼一下程式碼
還是比較好懂的,就是先建立一個字典,在字典裡面對每個類別新建一個鍵值對,值為每個類別的樣本個數
之後分別計算概率啊什麼的
輸出如下
跟書上的答案是一樣的
我個人有
參考周志華老師的《機器學習》一書,對決策樹演算法進行總結。
決策樹(Decision Tree)是在已知各種情況發生概率的基礎上,通過構建決策樹來求取淨現值期望值大於等於0的概率,評價專案風險,判斷其可行性的決策分析方法,是直觀運用概率分析的圖解法。
0 引言
決策樹是一種基本的分類和迴歸方法。決策樹模型呈樹形結構,在分類問題中,表示基於特徵對例項進行分類的過程。可以認為是if-then規則的集合,也可以認定是定義在特徵空間與類空間上的條件概率分佈。其主要特點是模型具有可讀性,分類速度快。學習時,利用訓
上一集中,我們講解了K近鄰演算法,那是一個十分入門的演算法,並沒有顯式的訓練方法。這次,我們要做一個真正的機器學習演算法,決策樹演算法。當然,它也是一個多元分類器。相比較K近鄰演算法對於數值型的資料處理較為舒服,因為畢竟是算距離,所以你就算是跑到天涯海角,也能算出來。但是決
一. 理論基礎
1. 特徵選擇
a. 資訊熵
H(D)=−∑i=0kpilogpi
b. 條件熵
H(Y|X)=∑i=0npiH(Y|X=xi)
c. 資訊增益
I(D,A)=H(D)−H(D|A)
d. 資訊增益比
一、決策樹
在機器學習中,決策樹是一個預測模型;他代表的是物件屬性與物件值之間的一種對映關係。樹中每個節點表示某個物件,而每個分叉路徑則代表的某個可能的屬性值,而每個葉結點則對應從根節點到該葉節點所經歷的路徑所表示的物件的值。決策樹僅有單一輸出,若欲有複數輸出,可以建立獨立的決策樹以處理不同輸出。資料探
內含3種演算法的核心部分.
沒有找到很好的測試資料.
但就理清演算法思路來說問題不大
剪枝演算法目前只實現了CART迴歸樹的後剪枝.
import numpy as np
from collections import Counter
from sklearn imp
1.用到的主要三條熵公式:
1.1 資訊熵 詳情見夏農資訊理論 概率越平衡 事件所含有的資訊量越大
1.2 條件熵 代表某一屬性下不同分類的資訊熵之和
1.3 資訊增益 等於資訊熵減去條件熵,從數值上,越大的資訊增益在資訊熵一定的情況下,代表條件熵越小,條件熵越
都說萬事開頭難,可一旦開頭,就是全新的狀態,就有可能收穫自己未曾預料到的成果。從2018.12.28開始,決定跟隨《機器學習實戰》的腳步開始其征程,記錄是為了更好的監督、理解和推進,學習過程中用到的資料集和程式碼都將上傳到github
機器學習系列部落格:(1)
機器學習之K-近鄰演算法
最近在看整合演算法AdaBoost,推薦先看李航的統計學習方法第8章,然後再看機器學習實戰第7章,李航的書上的公式推導講的很詳細了,但是很多地方對於初學者來說,還是需要時間去理解和消化的。本文將從以下幾個方面來介紹AdaBoost演算法。一、AdaBoost演算法公式推導二、
煩的一B 。。。 也沒刻意去下個編輯器。。就隨便弄著寫 發現好麻煩 換行的問題 還有函式for if 的區分全靠縮排格數
如果縮排格數錯了就直接GG 還念C/java 的大括號。。。(*^__^*) 嘻嘻…… 因為這個問題出現了巨大問題 導致我現在對Python
有點煩。。。 不過方便是比java/c方便多了 就是這個縮排問題。。。改天弄個編輯器玩玩。。看能不能解決 要是不能解決我就GG
1:夏農熵:集合資訊的度量方式成為夏農熵或者簡稱熵,這個名字來源於資訊理論之父克勞德·夏農。熵定義為資訊的期望值。
如果待分類的事務可能劃分在多個分類中。關於期望的計算就是對於x*p(x)求和,p(x)表示事件x發生的概率。我們計算夏農熵也遵循著這種
方式,下面是計算給定資料集的夏農熵:
from math import log /*匯入math模組中的log函式,因為計算X的資訊時需要用到log函式
def calcShannonEnt(dataSet) /* 輸入資料集
numEntries=len(dataSet) /*統計資料集中例項的總數
labelCounts={} /*定義一個字典
for featVec in dataSet: /*依照每行遍歷資料集
currentLabel=featVec[-1] /*取每行中最後一個元素
if currentLabel not in labelCounts.keys(): /*如果最後一個元素不是鍵值
labelCounts[currentLabel]=0 /*設定currentLabel為建,值為0
labelCounts[currentLabel] +=1 /*由於字典中出現了一個currentLabel,就是上面被置為0的,所以變為1,
/*上面一條語句是新建,若沒執行if則說明已有一條currentLabel存在,即+1
shannonEnt = 0.0
for key in labelCounts:
prob = float(labelCounts[key])/numEntries /*求概率,出現次數/總數
shannonEnt -=prob*log(prob,2) /*求對數,自增 就是期望, 期望就是對概率和事件乘集的求和
return shannonEnt /*資料後
第一個for迴圈本質是記錄鍵出現的次數,若沒出現則新建,新建後置次數為0 ,然後通過語句+1,這是對+=1這條語句的利用
2:根據資料集的特徵進行劃分。
def splitDataSet(dataSet,axis,value): /*輸入樣本集, axis代表樣本集中第i行的第axis號元素,表示特徵屬性
value代表想要測量第axis號元素的值 表示特徵屬性的值
retDataSet=[] /%為了儲存分類完畢的集合
for featVec in dataSet:
if featVec[axis] == value: /*若第 axis號元素等於初始給定的value值 則記錄下來
reducedFeatVec=featVec[:axis]
reducedFeatVec.extend(featVec[axis+1:]) /*以上兩條語句是把featVec陣列中除了特徵值的元素給保留下來
[1,0,yes] 若0零特徵值 則最後儲存的是[1,yes]
retDataSet.append(reducedFeatVec)
return retDataSet
3:選擇最好的資料集劃分方式。我們是按照獲取最大資訊增益來劃分的資料集。也就是計算最小的熵。初始熵是dataSet的熵,
通過劃分得到的熵是該劃分所佔原始資料的百分比乘以該劃分下來的子集的熵 然後對兩個子集的熵相加才是劃分後的熵
注意!!!注意區分【特徵&特徵值】
def chooesBestFeatureToSplit(dataSet):
numFeatures=len(dataSet[0])-1 /* 特徵值的數量 減去yes or no
baseEntropy=calcShannonEnt(dataSet) /* 先置最優熵為為劃分是資料集的熵
bestInFoGain=0.0;beastFeatutre=-1 /* 預設最好的特徵為-1
for i in range(numFeatures) /*在特徵數量內遍歷 遍歷所有的特徵 i代表的是axis
featList=[example[i] for exapmle in dataSet] /* featList陣列存放的是特徵值 存放len(dataSet)個
uniqueVals=set(featList) /* set集合中存放的是不同的 在本列中是[0,1]
所代表的的是特徵值 也就是value
newEntropy=0.0
for value in uniqueVals: /* 進行遍歷 呼叫splitDataSet()進行劃分
subDataSet=splitDataSet(dataSet,i,value)
prob=len(subDataSet)/float(len(dataSet)) /*劃分後在原集合中佔的比例
newEntropy +=prob*calcShannonEnt(subDataSet) /* 比例乘以劃分後集合的熵 相加表示兩個比例相加為1
然後各自乘以各自劃分集合的熵 與原資料的熵比較
infoGain=baseEntropy-newEntropy /* 表示的是未劃分集合(原集合dataSet)的熵減去劃分好各自熵的和
if(infoGain>bestInFoGain): /* 與0相比 若大於則表示熵減小了 也就是這種劃分方式是有利的
bestInFoGain=infoGain /*用這個劃分與原資料的熵的差值代替0,並設定該劃分為當前最優劃分
在隨後的迴圈中直接計算下次劃分與當前最優劃分的熵的大小
bestFeature=i
return bestFeature /* 輸出的是最好的劃分中的特徵
4:通過多數表決的方式確定葉子節點的分類
def majorityCnt(classList):
classCount={}
for vote in classlist:
if vote not in classCount.keys():
classCount[vote]=0
classCount[vote]+=1
sortedClassCount=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True)
/* iteritems是返回當前字典操作後的迭代
相關推薦
機器學習實戰 決策樹 演算法 筆記
機器學習實戰——決策樹Python實現問題記錄
機器學習_8.決策樹演算法
機器學習實戰-決策樹-畫圖
機器學習實戰--決策樹(一)
機器學習實戰--決策樹
機器學習實戰決策樹(一)——資訊增益與劃分資料集
【機器學習】決策樹演算法(二)— 程式碼實現
機器學習之決策樹演算法詳解
機器學習實戰——決策樹
機器學習實戰-決策樹
【機器學習】決策樹演算法的基本原理
機器學習之決策樹演算法(一)
機器學習之決策樹演算法(1)
機器學習之決策樹演算法python實現
機器學習之決策樹演算法
【機器學習】決策樹(基於ID3,C4.5,CART分類迴歸樹演算法)—— python3 實現方案
[機器學習]ID3決策樹 詳細計算流程 周志華機器學習 筆記 原創Excel手算方法
機器學習之決策樹 機器學習之K-近鄰演算法
【機器學習實戰系列】讀書筆記之AdaBoost演算法公式推導和例子講解(一)