決策樹①——信息熵&信息增益&基尼系數(shù)
決策樹②——決策樹算法原理(ID3,C4.5,CART)
決策樹③——決策樹參數(shù)介紹(分類和回歸)
決策樹④——決策樹Sklearn調(diào)參(GridSearchCV調(diào)參及過程做圖)
決策樹應(yīng)用實(shí)例①——泰坦尼克號分類
決策樹應(yīng)用實(shí)例②——用戶流失預(yù)測模型
決策樹應(yīng)用實(shí)例③——銀行借貸模型
上一篇總結(jié)了Sklearn庫用GridSearchCV調(diào)參的過程,今天用python依據(jù)現(xiàn)代女生的審美創(chuàng)建一顆簡單的決策樹,看下是否能代表大眾的心聲~~
from math import log
import operator
def calcShannonEnt(dataset):
numEntries = len(dataset) # 輸入樣本個(gè)數(shù)
labelCounts = {} # 存類別及相應(yīng)的數(shù)量
for featVec in dataset: # 一行即是一個(gè)特征向量
currentLable = featVec[-1] # 取每個(gè)樣本的類別
if currentLable not in labelCounts.keys():# 如果變量已經(jīng)有類別,則在數(shù)量上+1,如果沒有,則先新建一個(gè)再+1
labelCounts[currentLable] = 0
labelCounts[currentLable] += 1
shannoEnt = 0
for key in labelCounts:
prob = float(labelCounts[key])/float(numEntries)
shannoEnt += -prob*log(prob, 2) # 計(jì)算所有樣本的信息熵
return shannoEnt
def creaDataSet1():
dataSet = [['高', '富', '帥','同意'],
['高', '富', '丑','同意'],
['高', '窮', '丑','同意'],
['高', '窮', '帥','同意'],
['矮', '窮', '帥','拒絕'],
['矮', '富', '帥', '同意'],
['矮', '窮', '丑', '拒絕'],
['矮', '富', '丑', '拒絕']]
labels = ['身高', '財(cái)富', '外貌']
return dataSet, labels
def splitDataSet(dataSet, axis, value):
retDataset = []
for feaVec in dataSet: # 迭代每一個(gè)樣本
if feaVec[axis] == value: # 如果樣本的這個(gè)特征值=要求的值
reducedFeatVec = feaVec[:axis] # 取這個(gè)樣本的前N個(gè)特征,直到篩選的這個(gè)特征
reducedFeatVec.extend(feaVec[axis+1:]) #拼接這個(gè)特征之后的所有特征值,相當(dāng)于去掉這個(gè)特征
retDataset.append(reducedFeatVec) # 給出按這個(gè)特征值分類后的剩余特征
return retDataset
def chooseBestFeatureToSplit(dataset):
numFeatures = len(dataset[0]) - 1 #特征個(gè)數(shù)
baseEntropy = calcShannonEnt(dataset) # 計(jì)算信息熵
bestInfoGain = 0
bestFeature = -1
for i in range(numFeatures):# 迭代每一個(gè)特征
featList = [example[i] for example in dataset] # 找出這個(gè)特征的所有屬性值
uniqueVals = set(featList) # 這個(gè)特征的唯一屬性值
newEntropy = 0
for value in uniqueVals:
subDataset = splitDataSet(dataset, i, value) # 按這個(gè)特征這個(gè)屬性值分類后的子集
prob = float(len(subDataset))/float(len(dataset)) # 子集在全樣本集中的概率
newEntropy += prob*calcShannonEnt(subDataset) # 計(jì)算按這個(gè)特征這個(gè)屬性分裂后的信息熵,直接迭代完這個(gè)特征所有的屬性值,得到按這個(gè)特征分裂后所有的條件熵
infoGain = baseEntropy - newEntropy # 計(jì)算信息增益
if (infoGain>bestInfoGain):
bestInfoGain = infoGain # 最佳的信息增益
bestFeature = i # 最佳的特征
return bestFeature
def majorityCnt(classList):
classCount = {}
for vote in classList: # 對提供的樣本類別列表進(jìn)行計(jì)數(shù)
if vote not in classCount.keys():
classCount[vote] = 0
classCount[vote] += 1
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True) # 倒排,找到個(gè)數(shù)最多的樣品類別,則為這個(gè)節(jié)點(diǎn)的類別
return sortedClassCount[0][0]
def createTree(dataset, labels):
classList = [example[-1] for example in dataset] # 得到所有樣本的類別
if classList.count(classList[0]) == len(classList): # 如果樣本都是一個(gè)類別,則直接按這個(gè)類別就行了
return classList[0]
if len(dataset[0]) == 1: # 如果只剩下一個(gè)特征,?
return majorityCnt(classList)
bestFeat = chooseBestFeatureToSplit(dataset) # 篩選最佳的特征
print(labels) # 對應(yīng)的特征名
bestFeatLabel = labels[bestFeat] # 得到最佳的特征名
myTree = {bestFeatLabel:{}}
del (labels[bestFeat]) # 刪除已經(jīng)用于分裂的特征
featValues = [example[bestFeat] for example in dataset] # 按此特征的所有特征值
uniqueVals = set(featValues) # 特征值的唯一
for value in uniqueVals:
subLablels = labels[:] # 剩余可以用于分裂的特征
print('sub"', subLablels)
myTree[bestFeatLabel][value] = createTree(splitDataSet(dataset, bestFeat, value), subLablels)
# 先按最優(yōu)特征值的某一個(gè)屬性分裂,得到子集,對子集再找最優(yōu)特征分裂,直到全部類別一樣,或者已經(jīng)沒有特征可選時(shí)采用最大投票法得出分類結(jié)果;迭代的結(jié)果全部依次存入mytree字典中
return myTree
if __name__ == '__main__':
dataSet, labels = creaDataSet1()
map = createTree(dataSet, labels)
print(map)
從結(jié)果看出,女生在身高,財(cái)富和外貌中,最重視的還是身高,如果身高較高,不會在意其它2個(gè)條件,如果身高不高,則會再看財(cái)富,如果有錢且長得還行,能接受,如果有錢但長得不好則拒絕,如果沒錢則直接拒絕。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
