
本文實例講述了Python機器學習之決策樹算法。分享給大家供大家參考,具體如下:
決策樹學習是應用最廣泛的歸納推理算法之一,是一種逼近離散值目標函數(shù)的方法,在這種方法中學習到的函數(shù)被表示為一棵決策樹。決策樹可以使用不熟悉的數(shù)據(jù)集合,并從中提取出一系列規(guī)則,機器學習算法最終將使用這些從數(shù)據(jù)集中創(chuàng)造的規(guī)則。決策樹的優(yōu)點為:計算復雜度不高,輸出結(jié)果易于理解,對中間值的缺失不敏感,可以處理不相關(guān)特征數(shù)據(jù)。缺點為:可能產(chǎn)生過度匹配的問題。決策樹適于處理離散型和連續(xù)型的數(shù)據(jù)。
在算法中一般選用ID3,D3算法的核心問題是選取在樹的每個節(jié)點要測試的特征或者屬性,希望選擇的是最有助于分類實例的屬性。如何定量地衡量一個屬性的價值呢?這里需要引入熵和信息增益的概念。熵是信息論中廣泛使用的一個度量標準,刻畫了任意樣本集的純度。
假設(shè)有10個訓練樣本,其中6個的分類標簽為yes,4個的分類標簽為no,那熵是多少呢?在該例子中,分類的數(shù)目為2(yes,no),yes的概率為0.6,no的概率為0.4,則熵為 :
其中value(A)是屬性A所有可能值的集合,是S中屬性A的值為v的子集,即
。上述公式的第一項為原集合S的熵,第二項是用A分類S后熵的期望值,該項描述的期望熵就是每個子集的熵的加權(quán)和,權(quán)值為屬于的樣本占原始樣本S的比例
。所以Gain(S, A)是由于知道屬性A的值而導致的期望熵減少。
完整的代碼:
# -*- coding: cp936 -*-
from numpy import *
import operator
from math import log
import operator
def createDataSet():
dataSet = [[1,1,'yes'],
[1,1,'yes'],
[1,0,'no'],
[0,1,'no'],
[0,1,'no']]
labels = ['no surfacing','flippers']
return dataSet, labels
def calcShannonEnt(dataSet):
numEntries = len(dataSet)
labelCounts = {} # a dictionary for feature
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:
#print(key)
#print(labelCounts[key])
prob = float(labelCounts[key])/numEntries
#print(prob)
shannonEnt -= prob * log(prob,2)
return shannonEnt
#按照給定的特征劃分數(shù)據(jù)集
#根據(jù)axis等于value的特征將數(shù)據(jù)提出
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
#選取特征,劃分數(shù)據(jù)集,計算得出最好的劃分數(shù)據(jù)集的特征
def chooseBestFeatureToSplit(dataSet):
numFeatures = len(dataSet[0]) - 1 #剩下的是特征的個數(shù)
baseEntropy = calcShannonEnt(dataSet)#計算數(shù)據(jù)集的熵,放到baseEntropy中
bestInfoGain = 0.0;bestFeature = -1 #初始化熵增益
for i in range(numFeatures):
featList = [example[i] for example in dataSet] #featList存儲對應特征所有可能得取值
uniqueVals = set(featList)
newEntropy = 0.0
for value in uniqueVals:#下面是計算每種劃分方式的信息熵,特征i個,每個特征value個值
subDataSet = splitDataSet(dataSet, i ,value)
prob = len(subDataSet)/float(len(dataSet)) #特征樣本在總樣本中的權(quán)重
newEntropy = prob * calcShannonEnt(subDataSet)
infoGain = baseEntropy - newEntropy #計算i個特征的信息熵
#print(i)
#print(infoGain)
if(infoGain > bestInfoGain):
bestInfoGain = infoGain
bestFeature = i
return bestFeature
#如上面是決策樹所有的功能模塊
#得到原始數(shù)據(jù)集之后基于最好的屬性值進行劃分,每一次劃分之后傳遞到樹分支的下一個節(jié)點
#遞歸結(jié)束的條件是程序遍歷完成所有的數(shù)據(jù)集屬性,或者是每一個分支下的所有實例都具有相同的分類
#如果所有實例具有相同的分類,則得到一個葉子節(jié)點或者終止快
#如果所有屬性都已經(jīng)被處理,但是類標簽依然不是確定的,那么采用多數(shù)投票的方式
#返回出現(xiàn)次數(shù)最多的分類名稱
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]
#創(chuàng)建決策樹
def createTree(dataSet,labels):
classList = [example[-1] for example in dataSet]#將最后一行的數(shù)據(jù)放到classList中,所有的類別的值
if classList.count(classList[0]) == len(classList): #類別完全相同不需要再劃分
return classList[0]
if len(dataSet[0]) == 1:#這里為什么是1呢?就是說特征數(shù)為1的時候
return majorityCnt(classList)#就返回這個特征就行了,因為就這一個特征
bestFeat = chooseBestFeatureToSplit(dataSet)
print('the bestFeatue in creating is :')
print(bestFeat)
bestFeatLabel = labels[bestFeat]#運行結(jié)果'no surfacing'
myTree = {bestFeatLabel:{}}#嵌套字典,目前value是一個空字典
del(labels[bestFeat])
featValues = [example[bestFeat] for example in dataSet]#第0個特征對應的取值
uniqueVals = set(featValues)
for value in uniqueVals: #根據(jù)當前特征值的取值進行下一級的劃分
subLabels = labels[:]
myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet,bestFeat,value),subLabels)
return myTree
#對上面簡單的數(shù)據(jù)進行小測試
def testTree1():
myDat,labels=createDataSet()
val = calcShannonEnt(myDat)
print 'The classify accuracy is: %.2f%%' % val
retDataSet1 = splitDataSet(myDat,0,1)
print (myDat)
print(retDataSet1)
retDataSet0 = splitDataSet(myDat,0,0)
print (myDat)
print(retDataSet0)
bestfeature = chooseBestFeatureToSplit(myDat)
print('the bestFeatue is :')
print(bestfeature)
tree = createTree(myDat,labels)
print(tree)
對應的結(jié)果是:
>>> import TREE
>>> TREE.testTree1()
The classify accuracy is: 0.97%
[[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]
[[1, 'yes'], [1, 'yes'], [0, 'no']]
[[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]
[[1, 'no'], [1, 'no']]
the bestFeatue is :
0
the bestFeatue in creating is :
0
the bestFeatue in creating is :
0
{'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}
最好再增加使用決策樹的分類函數(shù)
同時因為構(gòu)建決策樹是非常耗時間的,因為最好是將構(gòu)建好的樹通過 python 的 pickle 序列化對象,將對象保存在磁盤上,等到需要用的時候再讀出
def classify(inputTree,featLabels,testVec):
firstStr = inputTree.keys()[0]
secondDict = inputTree[firstStr]
featIndex = featLabels.index(firstStr)
key = testVec[featIndex]
valueOfFeat = secondDict[key]
if isinstance(valueOfFeat, dict):
classLabel = classify(valueOfFeat, featLabels, testVec)
else: classLabel = valueOfFeat
return classLabel
def storeTree(inputTree,filename):
import pickle
fw = open(filename,'w')
pickle.dump(inputTree,fw)
fw.close()
def grabTree(filename):
import pickle
fr = open(filename)
return pickle.load(fr)
數(shù)據(jù)分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
LSTM 模型輸入長度選擇技巧:提升序列建模效能的關(guān)鍵? 在循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)家族中,長短期記憶網(wǎng)絡(luò)(LSTM)憑借其解決長序列 ...
2025-07-11CDA 數(shù)據(jù)分析師報考條件詳解與準備指南? ? 在數(shù)據(jù)驅(qū)動決策的時代浪潮下,CDA 數(shù)據(jù)分析師認證愈發(fā)受到矚目,成為眾多有志投身數(shù) ...
2025-07-11數(shù)據(jù)透視表中兩列相乘合計的實用指南? 在數(shù)據(jù)分析的日常工作中,數(shù)據(jù)透視表憑借其強大的數(shù)據(jù)匯總和分析功能,成為了 Excel 用戶 ...
2025-07-11尊敬的考生: 您好! 我們誠摯通知您,CDA Level I和 Level II考試大綱將于 2025年7月25日 實施重大更新。 此次更新旨在確保認 ...
2025-07-10BI 大數(shù)據(jù)分析師:連接數(shù)據(jù)與業(yè)務(wù)的價值轉(zhuǎn)化者? ? 在大數(shù)據(jù)與商業(yè)智能(Business Intelligence,簡稱 BI)深度融合的時代,BI ...
2025-07-10SQL 在預測分析中的應用:從數(shù)據(jù)查詢到趨勢預判? ? 在數(shù)據(jù)驅(qū)動決策的時代,預測分析作為挖掘數(shù)據(jù)潛在價值的核心手段,正被廣泛 ...
2025-07-10數(shù)據(jù)查詢結(jié)束后:分析師的收尾工作與價值深化? ? 在數(shù)據(jù)分析的全流程中,“query end”(查詢結(jié)束)并非工作的終點,而是將數(shù) ...
2025-07-10CDA 數(shù)據(jù)分析師考試:從報考到取證的全攻略? 在數(shù)字經(jīng)濟蓬勃發(fā)展的今天,數(shù)據(jù)分析師已成為各行業(yè)爭搶的核心人才,而 CDA(Certi ...
2025-07-09【CDA干貨】單樣本趨勢性檢驗:捕捉數(shù)據(jù)背后的時間軌跡? 在數(shù)據(jù)分析的版圖中,單樣本趨勢性檢驗如同一位耐心的偵探,專注于從單 ...
2025-07-09year_month數(shù)據(jù)類型:時間維度的精準切片? ? 在數(shù)據(jù)的世界里,時間是最不可或缺的維度之一,而year_month數(shù)據(jù)類型就像一把精準 ...
2025-07-09CDA 備考干貨:Python 在數(shù)據(jù)分析中的核心應用與實戰(zhàn)技巧? ? 在 CDA 數(shù)據(jù)分析師認證考試中,Python 作為數(shù)據(jù)處理與分析的核心 ...
2025-07-08SPSS 中的 Mann-Kendall 檢驗:數(shù)據(jù)趨勢與突變分析的有力工具? ? ? 在數(shù)據(jù)分析的廣袤領(lǐng)域中,準確捕捉數(shù)據(jù)的趨勢變化以及識別 ...
2025-07-08備戰(zhàn) CDA 數(shù)據(jù)分析師考試:需要多久?如何規(guī)劃? CDA(Certified Data Analyst)數(shù)據(jù)分析師認證作為國內(nèi)權(quán)威的數(shù)據(jù)分析能力認證 ...
2025-07-08LSTM 輸出不確定的成因、影響與應對策略? 長短期記憶網(wǎng)絡(luò)(LSTM)作為循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)的一種變體,憑借獨特的門控機制,在 ...
2025-07-07統(tǒng)計學方法在市場調(diào)研數(shù)據(jù)中的深度應用? 市場調(diào)研是企業(yè)洞察市場動態(tài)、了解消費者需求的重要途徑,而統(tǒng)計學方法則是市場調(diào)研數(shù) ...
2025-07-07CDA數(shù)據(jù)分析師證書考試全攻略? 在數(shù)字化浪潮席卷全球的當下,數(shù)據(jù)已成為企業(yè)決策、行業(yè)發(fā)展的核心驅(qū)動力,數(shù)據(jù)分析師也因此成為 ...
2025-07-07剖析 CDA 數(shù)據(jù)分析師考試題型:解鎖高效備考與答題策略? CDA(Certified Data Analyst)數(shù)據(jù)分析師考試作為衡量數(shù)據(jù)專業(yè)能力的 ...
2025-07-04SQL Server 字符串截取轉(zhuǎn)日期:解鎖數(shù)據(jù)處理的關(guān)鍵技能? 在數(shù)據(jù)處理與分析工作中,數(shù)據(jù)格式的規(guī)范性是保證后續(xù)分析準確性的基礎(chǔ) ...
2025-07-04CDA 數(shù)據(jù)分析師視角:從數(shù)據(jù)迷霧中探尋商業(yè)真相? 在數(shù)字化浪潮席卷全球的今天,數(shù)據(jù)已成為企業(yè)決策的核心驅(qū)動力,CDA(Certifie ...
2025-07-04CDA 數(shù)據(jù)分析師:開啟數(shù)據(jù)職業(yè)發(fā)展新征程? ? 在數(shù)據(jù)成為核心生產(chǎn)要素的今天,數(shù)據(jù)分析師的職業(yè)價值愈發(fā)凸顯。CDA(Certified D ...
2025-07-03